From 659ff866e119a6968c50113366156b63210118d0 Mon Sep 17 00:00:00 2001 From: qianlifeng Date: Sat, 5 Jul 2014 23:10:34 +0800 Subject: [PATCH 01/10] Add Executable Plugin Loader --- Wox.Plugin.SystemPlugins/CMD/CMD.cs | 4 +- .../ThirdpartyPluginIndicator.cs | 11 +- .../WebSearch/WebSearchPlugin.cs | 4 +- Wox.Plugin/AllowedLanguage.cs | 9 +- Wox.Plugin/IPublicAPI.cs | 38 + Wox.Plugin/PluginInitContext.cs | 92 +- Wox.Plugin/Result.cs | 3 +- Wox.Plugin/Wox.Plugin.csproj | 1 + Wox/Commands/PluginCommand.cs | 29 +- Wox/Commands/SystemCommand.cs | 15 +- Wox/MainWindow.xaml.cs | 916 ++++++++++-------- Wox/PluginLoader/ExecutablePluginLoader.cs | 29 + Wox/PluginLoader/ExecutablePluginWrapper.cs | 72 ++ Wox/PluginLoader/Plugins.cs | 128 +-- Wox/RPC/JsonPRCModel.cs | 17 + Wox/RPC/JsonRPC.cs | 20 + Wox/Wox.csproj | 4 + 17 files changed, 850 insertions(+), 542 deletions(-) create mode 100644 Wox.Plugin/IPublicAPI.cs create mode 100644 Wox/PluginLoader/ExecutablePluginLoader.cs create mode 100644 Wox/PluginLoader/ExecutablePluginWrapper.cs create mode 100644 Wox/RPC/JsonPRCModel.cs create mode 100644 Wox/RPC/JsonRPC.cs diff --git a/Wox.Plugin.SystemPlugins/CMD/CMD.cs b/Wox.Plugin.SystemPlugins/CMD/CMD.cs index c205e3dca4..9d112aa1e3 100644 --- a/Wox.Plugin.SystemPlugins/CMD/CMD.cs +++ b/Wox.Plugin.SystemPlugins/CMD/CMD.cs @@ -59,7 +59,7 @@ namespace Wox.Plugin.SystemPlugins.CMD } catch (Exception) { } - context.PushResults(query, new List() { result }); + context.API.PushResults(query,context.CurrentPluginMetadata, new List() { result }); pushedResults.Add(result); IEnumerable history = CMDStorage.Instance.CMDHistory.Where(o => o.Key.Contains(cmd)) @@ -95,7 +95,7 @@ namespace Wox.Plugin.SystemPlugins.CMD return ret; }).Where(o => o != null).Take(4); - context.PushResults(query, history.ToList()); + context.API.PushResults(query,context.CurrentPluginMetadata,history.ToList()); pushedResults.AddRange(history); try diff --git a/Wox.Plugin.SystemPlugins/ThirdpartyPluginIndicator.cs b/Wox.Plugin.SystemPlugins/ThirdpartyPluginIndicator.cs index b5c817bda8..495a2c28ff 100644 --- a/Wox.Plugin.SystemPlugins/ThirdpartyPluginIndicator.cs +++ b/Wox.Plugin.SystemPlugins/ThirdpartyPluginIndicator.cs @@ -11,11 +11,13 @@ namespace Wox.Plugin.SystemPlugins public class ThirdpartyPluginIndicator : BaseSystemPlugin { private List allPlugins = new List(); - private Action changeQuery; + private PluginInitContext context; protected override List QueryInternal(Query query) { List results = new List(); + if(allPlugins.Count == 0) allPlugins = context.API.GetAllPlugins(); + foreach (PluginMetadata metadata in allPlugins.Select(o => o.Metadata)) { @@ -36,7 +38,7 @@ namespace Wox.Plugin.SystemPlugins IcoPath = "Images/work.png", Action = (c) => { - changeQuery(metadataCopy.ActionKeyword + " "); + context.ChangeQuery(metadataCopy.ActionKeyword + " "); return false; }, }; @@ -52,7 +54,7 @@ namespace Wox.Plugin.SystemPlugins IcoPath = "Images/work.png", Action = (c) => { - changeQuery(n.ActionWord + " "); + context.ChangeQuery(n.ActionWord + " "); return false; } })); @@ -62,8 +64,7 @@ namespace Wox.Plugin.SystemPlugins protected override void InitInternal(PluginInitContext context) { - allPlugins = context.Plugins; - changeQuery = context.ChangeQuery; + this.context = context; } diff --git a/Wox.Plugin.SystemPlugins/WebSearch/WebSearchPlugin.cs b/Wox.Plugin.SystemPlugins/WebSearch/WebSearchPlugin.cs index e2c69c47f3..b7afa08dd2 100644 --- a/Wox.Plugin.SystemPlugins/WebSearch/WebSearchPlugin.cs +++ b/Wox.Plugin.SystemPlugins/WebSearch/WebSearchPlugin.cs @@ -32,7 +32,7 @@ namespace Wox.Plugin.SystemPlugins title = subtitle; subtitle = null; } - context.PushResults(query, new List() + context.API.PushResults(query,context.CurrentPluginMetadata, new List() { new Result() { @@ -54,7 +54,7 @@ namespace Wox.Plugin.SystemPlugins var result = sugg.GetSuggestions(keyword); if (result != null) { - context.PushResults(query, result.Select(o => new Result() + context.API.PushResults(query,context.CurrentPluginMetadata, result.Select(o => new Result() { Title = o, SubTitle = subtitle, diff --git a/Wox.Plugin/AllowedLanguage.cs b/Wox.Plugin/AllowedLanguage.cs index c6d0fa805b..32262b48f2 100644 --- a/Wox.Plugin/AllowedLanguage.cs +++ b/Wox.Plugin/AllowedLanguage.cs @@ -17,9 +17,16 @@ namespace Wox.Plugin get { return "csharp"; } } + public static string ExecutableFile + { + get { return "ExecutableFile"; } + } + public static bool IsAllowed(string language) { - return language.ToUpper() == Python.ToUpper() || language.ToUpper() == CSharp.ToUpper(); + return language.ToUpper() == Python.ToUpper() + || language.ToUpper() == CSharp.ToUpper() + || language.ToUpper() == ExecutableFile.ToUpper(); } } } \ No newline at end of file diff --git a/Wox.Plugin/IPublicAPI.cs b/Wox.Plugin/IPublicAPI.cs new file mode 100644 index 0000000000..eb3b8fffba --- /dev/null +++ b/Wox.Plugin/IPublicAPI.cs @@ -0,0 +1,38 @@ +using System; +using System.Collections.Generic; +using System.Windows.Documents; + +namespace Wox.Plugin +{ + public interface IPublicAPI + { + + void PushResults(Query query,PluginMetadata plugin, List results); + + bool ShellRun(string cmd); + + void ChangeQuery(string query, bool requery = false); + + void CloseApp(); + + void HideApp(); + + void ShowApp(); + + void ShowMsg(string title, string subTitle, string iconPath); + + void OpenSettingDialog(); + + void ShowCurrentResultItemTooltip(string tooltip); + + void StartLoadingBar(); + + void StopLoadingBar(); + + void InstallPlugin(string path); + + void ReloadPlugins(); + + List GetAllPlugins(); + } +} diff --git a/Wox.Plugin/PluginInitContext.cs b/Wox.Plugin/PluginInitContext.cs index 68be7a58f1..f38b1c1c70 100644 --- a/Wox.Plugin/PluginInitContext.cs +++ b/Wox.Plugin/PluginInitContext.cs @@ -7,31 +7,87 @@ namespace Wox.Plugin { public class PluginInitContext { - public List Plugins { get; set; } public PluginMetadata CurrentPluginMetadata { get; set; } - - public Action ChangeQuery { get; set; } - public Action CloseApp { get; set; } - public Action HideApp { get; set; } - public Action ShowApp { get; set; } - public Action ShowMsg { get; set; } - public Action OpenSettingDialog { get; set; } - - public Action ShowCurrentResultItemTooltip { get; set; } - /// - /// reload all plugins + /// Public APIs for plugin invocation /// - public Action ReloadPlugins { get; set; } + public IPublicAPI API { get; set; } - public Action InstallPlugin { get; set; } + #region Legacy APIs - public Action StartLoadingBar { get; set; } - public Action StopLoadingBar { get; set; } + [Obsolete("This method has been obsoleted, use API.ShellRun instead")] + public bool ShellRun(string cmd) + { + return API.ShellRun(cmd); + } - public Func ShellRun { get; set; } + [Obsolete("This method has been obsoleted, use API.OpenSettingDialog instead")] + public void ChangeQuery(string query, bool requery = false) + { + API.ChangeQuery(query, requery); + } - public Action> PushResults { get; set; } + [Obsolete("This method has been obsoleted, use API.CloseApp instead")] + public void CloseApp() + { + API.CloseApp(); + } + + [Obsolete("This method has been obsoleted, use API.HideApp instead")] + public void HideApp() + { + API.HideApp(); + } + + [Obsolete("This method has been obsoleted, use API.ShowApp instead")] + public void ShowApp() + { + API.ShowApp(); + } + + [Obsolete("This method has been obsoleted, use API.OpenSettingDialog instead")] + public void ShowMsg(string title, string subTitle, string iconPath) + { + API.ShowMsg(title, subTitle, iconPath); + } + + [Obsolete("This method has been obsoleted, use API.OpenSettingDialog instead")] + public void OpenSettingDialog() + { + API.OpenSettingDialog(); + } + + [Obsolete("This method has been obsoleted, use API.ShowCurrentResultItemTooltip instead")] + public void ShowCurrentResultItemTooltip(string tooltip) + { + API.ShowCurrentResultItemTooltip(tooltip); + } + + [Obsolete("This method has been obsoleted, use API.StartLoadingBar instead")] + public void StartLoadingBar() + { + API.StartLoadingBar(); + } + + [Obsolete("This method has been obsoleted, use API.StopLoadingBar instead")] + public void StopLoadingBar() + { + API.StopLoadingBar(); + } + + [Obsolete("This method has been obsoleted, use API.InstallPlugin instead")] + public void InstallPlugin(string path) + { + API.InstallPlugin(path); + } + + [Obsolete("This method has been obsoleted, use API.ReloadPlugins instead")] + public void ReloadPlugins() + { + API.ReloadPlugins(); + } + + #endregion } } diff --git a/Wox.Plugin/Result.cs b/Wox.Plugin/Result.cs index fa70cc99a9..f0c7fd4460 100644 --- a/Wox.Plugin/Result.cs +++ b/Wox.Plugin/Result.cs @@ -3,6 +3,7 @@ using System.Collections; using System.Collections.Generic; namespace Wox.Plugin { + public class Result { public string Title { get; set; } public string SubTitle { get; set; } @@ -41,7 +42,6 @@ namespace Wox.Plugin { return Title + SubTitle; } - public Result() { } @@ -52,6 +52,5 @@ namespace Wox.Plugin { this.SubTitle = SubTitle; } - } } \ No newline at end of file diff --git a/Wox.Plugin/Wox.Plugin.csproj b/Wox.Plugin/Wox.Plugin.csproj index e6a31c09cc..558dc86573 100644 --- a/Wox.Plugin/Wox.Plugin.csproj +++ b/Wox.Plugin/Wox.Plugin.csproj @@ -46,6 +46,7 @@ + diff --git a/Wox/Commands/PluginCommand.cs b/Wox/Commands/PluginCommand.cs index 1c25e5d5ad..388db8ecb0 100644 --- a/Wox/Commands/PluginCommand.cs +++ b/Wox/Commands/PluginCommand.cs @@ -15,40 +15,29 @@ namespace Wox.Commands private string currentPythonModulePath = string.Empty; private IntPtr GIL; - public override void Dispatch(Query q) + public override void Dispatch(Query query) { - PluginPair thirdPlugin = Plugins.AllPlugins.FirstOrDefault(o => o.Metadata.ActionKeyword == q.ActionName); + PluginPair thirdPlugin = Plugins.AllPlugins.FirstOrDefault(o => o.Metadata.ActionKeyword == query.ActionName); if (thirdPlugin != null && !string.IsNullOrEmpty(thirdPlugin.Metadata.ActionKeyword)) { var customizedPluginConfig = UserSettingStorage.Instance.CustomizedPluginConfigs.FirstOrDefault(o => o.ID == thirdPlugin.Metadata.ID); if (customizedPluginConfig != null && customizedPluginConfig.Disabled) { + //need to stop the loading animation UpdateResultView(null); return; } - if (thirdPlugin.Metadata.Language == AllowedLanguage.Python) - { - SwitchPythonEnv(thirdPlugin); - } + //if (thirdPlugin.Metadata.Language == AllowedLanguage.Python) + //{ + // SwitchPythonEnv(thirdPlugin); + //} ThreadPool.QueueUserWorkItem(t => { try { - thirdPlugin.InitContext.PushResults = (qu, r) => - { - if (r != null) - { - r.ForEach(o => - { - o.PluginDirectory = thirdPlugin.Metadata.PluginDirecotry; - o.OriginQuery = qu; - }); - UpdateResultView(r); - } - }; - List results = thirdPlugin.Plugin.Query(q) ?? new List(); - thirdPlugin.InitContext.PushResults(q, results); + List results = thirdPlugin.Plugin.Query(query) ?? new List(); + App.Window.PushResults(query,thirdPlugin.Metadata,results); } catch (Exception queryException) { diff --git a/Wox/Commands/SystemCommand.cs b/Wox/Commands/SystemCommand.cs index e38a5ca12b..e3eee7fb6c 100644 --- a/Wox/Commands/SystemCommand.cs +++ b/Wox/Commands/SystemCommand.cs @@ -19,19 +19,10 @@ namespace Wox.Commands ThreadPool.QueueUserWorkItem(state => { - pair1.InitContext.PushResults = (q, r) => - { - foreach (Result result in r) - { - result.PluginDirectory = pair1.Metadata.PluginDirecotry; - result.OriginQuery = q; - result.AutoAjustScore = true; - } - UpdateResultView(r); - }; - List results = pair1.Plugin.Query(query); - pair1.InitContext.PushResults(query, results); + results.ForEach(o=> { o.AutoAjustScore = true; }); + + App.Window.PushResults(query,pair1.Metadata,results); }); } } diff --git a/Wox/MainWindow.xaml.cs b/Wox/MainWindow.xaml.cs index c83d82073d..e410307f3e 100644 --- a/Wox/MainWindow.xaml.cs +++ b/Wox/MainWindow.xaml.cs @@ -35,429 +35,538 @@ using Rectangle = System.Drawing.Rectangle; using TextBox = System.Windows.Controls.TextBox; using ToolTip = System.Windows.Controls.ToolTip; -namespace Wox { - public partial class MainWindow { +namespace Wox +{ + public partial class MainWindow : IPublicAPI + { - #region Properties + #region Properties private static readonly object locker = new object(); public static bool initialized = false; private static readonly List waitShowResultList = new List(); - private readonly GlobalHotkey globalHotkey = new GlobalHotkey(); - private readonly KeyboardSimulator keyboardSimulator = new KeyboardSimulator(new InputSimulator()); - private readonly Storyboard progressBarStoryboard = new Storyboard(); - private bool WinRStroked; - private NotifyIcon notifyIcon; - private bool queryHasReturn; - private string lastQuery; - private ToolTip toolTip = new ToolTip(); + private readonly GlobalHotkey globalHotkey = new GlobalHotkey(); + private readonly KeyboardSimulator keyboardSimulator = new KeyboardSimulator(new InputSimulator()); + private readonly Storyboard progressBarStoryboard = new Storyboard(); + private bool WinRStroked; + private NotifyIcon notifyIcon; + private bool queryHasReturn; + private string lastQuery; + private ToolTip toolTip = new ToolTip(); - private bool isCMDMode = false; - private bool ignoreTextChange = false; - #endregion + private bool isCMDMode = false; + private bool ignoreTextChange = false; + #endregion - #region Public API + #region Public API - public void ChangeQuery(string query, bool requery = false) { - tbQuery.Text = query; - tbQuery.CaretIndex = tbQuery.Text.Length; - if (requery) { - TextBoxBase_OnTextChanged(null, null); - } - } + public void ChangeQuery(string query, bool requery = false) + { + Dispatcher.Invoke(new Action(() => + { + tbQuery.Text = query; + tbQuery.CaretIndex = tbQuery.Text.Length; + if (requery) + { + TextBoxBase_OnTextChanged(null, null); + } + })); + } - public void CloseApp() { - notifyIcon.Visible = false; - Close(); - Environment.Exit(0); - } + public void CloseApp() + { + Dispatcher.Invoke(new Action(() => + { + notifyIcon.Visible = false; + Close(); + Environment.Exit(0); + })); + } - public void HideApp() { - HideWox(); - } + public void HideApp() + { + Dispatcher.Invoke(new Action(HideWox)); + } - public void ShowApp() { - ShowWox(); - } + public void ShowApp() + { + Dispatcher.Invoke(new Action(() => ShowWox())); + } - public void ShowMsg(string title, string subTitle, string iconPath) { - var m = new Msg { Owner = GetWindow(this) }; - m.Show(title, subTitle, iconPath); - } + public void ShowMsg(string title, string subTitle, string iconPath) + { + Dispatcher.Invoke(new Action(() => + { + var m = new Msg {Owner = GetWindow(this)}; + m.Show(title, subTitle, iconPath); + })); + } - public void OpenSettingDialog() { - WindowOpener.Open(this); - } + public void OpenSettingDialog() + { + Dispatcher.Invoke(new Action(() => WindowOpener.Open(this))); + } - public void ShowCurrentResultItemTooltip(string text) { - toolTip.Content = text; - toolTip.IsOpen = true; - } + public void ShowCurrentResultItemTooltip(string text) + { + Dispatcher.Invoke(new Action(() => + { + toolTip.Content = text; + toolTip.IsOpen = true; + })); + } - public void StartLoadingBar() { - Dispatcher.Invoke(new Action(StartProgress)); - } + public void StartLoadingBar() + { + Dispatcher.Invoke(new Action(StartProgress)); + } - public void StopLoadingBar() { - Dispatcher.Invoke(new Action(StopProgress)); - } + public void StopLoadingBar() + { + Dispatcher.Invoke(new Action(StopProgress)); + } - #endregion + public void InstallPlugin(string path) + { + Dispatcher.Invoke(new Action(() => PluginInstaller.Install(path))); + } - public MainWindow() { - InitializeComponent(); + public void ReloadPlugins() + { + Dispatcher.Invoke(new Action(Plugins.Init)); + } - if (UserSettingStorage.Instance.OpacityMode == OpacityMode.LayeredWindow) - this.AllowsTransparency = true; + public List GetAllPlugins() + { + return Plugins.AllPlugins; + } - System.Net.WebRequest.RegisterPrefix("data", new DataWebRequestFactory()); + public void PushResults(Query query, PluginMetadata plugin, List results) + { + results.ForEach(o => + { + o.PluginDirectory = plugin.PluginDirecotry; + o.OriginQuery = query; + }); + OnUpdateResultView(results); + } - progressBar.ToolTip = toolTip; - InitialTray(); - resultCtrl.OnMouseClickItem += AcceptSelect; + #endregion - ThreadPool.SetMaxThreads(30, 10); - try { - SetTheme(UserSettingStorage.Instance.Theme); - } - catch (Exception) { - SetTheme(UserSettingStorage.Instance.Theme = "Dark"); - } - SetHotkey(UserSettingStorage.Instance.Hotkey, OnHotkey); - SetCustomPluginHotkey(); + public MainWindow() + { + InitializeComponent(); - globalHotkey.hookedKeyboardCallback += KListener_hookedKeyboardCallback; + if (UserSettingStorage.Instance.OpacityMode == OpacityMode.LayeredWindow) + this.AllowsTransparency = true; - this.Closing += MainWindow_Closing; - } + System.Net.WebRequest.RegisterPrefix("data", new DataWebRequestFactory()); - void MainWindow_Closing(object sender, System.ComponentModel.CancelEventArgs e) { - UserSettingStorage.Instance.WindowLeft = Left; - UserSettingStorage.Instance.WindowTop = Top; - UserSettingStorage.Instance.Save(); - this.HideWox(); - e.Cancel = true; - } + progressBar.ToolTip = toolTip; + InitialTray(); + resultCtrl.OnMouseClickItem += AcceptSelect; - private void MainWindow_OnLoaded(object sender, RoutedEventArgs e) { - if (UserSettingStorage.Instance.WindowLeft == 0 - && UserSettingStorage.Instance.WindowTop == 0) - { - Left = UserSettingStorage.Instance.WindowLeft - = (SystemParameters.PrimaryScreenWidth - ActualWidth) / 2; - Top = UserSettingStorage.Instance.WindowTop - = (SystemParameters.PrimaryScreenHeight - ActualHeight) / 5; - } - else { - Left = UserSettingStorage.Instance.WindowLeft; - Top = UserSettingStorage.Instance.WindowTop; - } + ThreadPool.SetMaxThreads(30, 10); + try + { + SetTheme(UserSettingStorage.Instance.Theme); + } + catch (Exception) + { + SetTheme(UserSettingStorage.Instance.Theme = "Dark"); + } - Plugins.Init(); + SetHotkey(UserSettingStorage.Instance.Hotkey, OnHotkey); + SetCustomPluginHotkey(); - InitProgressbarAnimation(); + globalHotkey.hookedKeyboardCallback += KListener_hookedKeyboardCallback; - //only works for win7+ - if (UserSettingStorage.Instance.OpacityMode == OpacityMode.DWM) - DwmDropShadow.DropShadowToWindow(this); + this.Closing += MainWindow_Closing; + } - this.Background = Brushes.Transparent; - HwndSource.FromHwnd(new WindowInteropHelper(this).Handle).CompositionTarget.BackgroundColor = Color.FromArgb(0, 0, 0, 0); + void MainWindow_Closing(object sender, System.ComponentModel.CancelEventArgs e) + { + UserSettingStorage.Instance.WindowLeft = Left; + UserSettingStorage.Instance.WindowTop = Top; + UserSettingStorage.Instance.Save(); + this.HideWox(); + e.Cancel = true; + } - WindowIntelopHelper.DisableControlBox(this); - } + private void MainWindow_OnLoaded(object sender, RoutedEventArgs e) + { + if (UserSettingStorage.Instance.WindowLeft == 0 + && UserSettingStorage.Instance.WindowTop == 0) + { + Left = UserSettingStorage.Instance.WindowLeft + = (SystemParameters.PrimaryScreenWidth - ActualWidth) / 2; + Top = UserSettingStorage.Instance.WindowTop + = (SystemParameters.PrimaryScreenHeight - ActualHeight) / 5; + } + else + { + Left = UserSettingStorage.Instance.WindowLeft; + Top = UserSettingStorage.Instance.WindowTop; + } - public void SetHotkey(string hotkeyStr, EventHandler action) { - var hotkey = new HotkeyModel(hotkeyStr); - try { - HotkeyManager.Current.AddOrReplace(hotkeyStr, hotkey.CharKey, hotkey.ModifierKeys, action); - } - catch (Exception) { - MessageBox.Show("Register hotkey: " + hotkeyStr + " failed."); - } - } + Plugins.Init(); - public void RemoveHotkey(string hotkeyStr) { - if (!string.IsNullOrEmpty(hotkeyStr)) { - HotkeyManager.Current.Remove(hotkeyStr); - } - } + InitProgressbarAnimation(); - private void SetCustomPluginHotkey() { - if (UserSettingStorage.Instance.CustomPluginHotkeys == null) return; - foreach (CustomPluginHotkey hotkey in UserSettingStorage.Instance.CustomPluginHotkeys) { - CustomPluginHotkey hotkey1 = hotkey; - SetHotkey(hotkey.Hotkey, delegate { - ShowApp(); - ChangeQuery(hotkey1.ActionKeyword, true); - }); - } - } + //only works for win7+ + if (UserSettingStorage.Instance.OpacityMode == OpacityMode.DWM) + DwmDropShadow.DropShadowToWindow(this); - private void OnHotkey(object sender, HotkeyEventArgs e) { - if (!IsVisible) { - ShowWox(); - } - else { - HideWox(); - } - e.Handled = true; - } + this.Background = Brushes.Transparent; + HwndSource.FromHwnd(new WindowInteropHelper(this).Handle).CompositionTarget.BackgroundColor = Color.FromArgb(0, 0, 0, 0); - private void InitProgressbarAnimation() { - var da = new DoubleAnimation(progressBar.X2, ActualWidth + 100, new Duration(new TimeSpan(0, 0, 0, 0, 1600))); - var da1 = new DoubleAnimation(progressBar.X1, ActualWidth, new Duration(new TimeSpan(0, 0, 0, 0, 1600))); - Storyboard.SetTargetProperty(da, new PropertyPath("(Line.X2)")); - Storyboard.SetTargetProperty(da1, new PropertyPath("(Line.X1)")); - progressBarStoryboard.Children.Add(da); - progressBarStoryboard.Children.Add(da1); - progressBarStoryboard.RepeatBehavior = RepeatBehavior.Forever; - progressBar.Visibility = Visibility.Hidden; - progressBar.BeginStoryboard(progressBarStoryboard); - } + WindowIntelopHelper.DisableControlBox(this); + } - private void InitialTray() { - notifyIcon = new NotifyIcon { Text = "Wox", Icon = Properties.Resources.app, Visible = true }; - notifyIcon.Click += (o, e) => ShowWox(); - var open = new MenuItem("Open"); - open.Click += (o, e) => ShowWox(); - var setting = new MenuItem("Setting"); - setting.Click += (o, e) => OpenSettingDialog(); - var exit = new MenuItem("Exit"); - exit.Click += (o, e) => CloseApp(); - MenuItem[] childen = { open, setting, exit }; - notifyIcon.ContextMenu = new ContextMenu(childen); - } + public void SetHotkey(string hotkeyStr, EventHandler action) + { + var hotkey = new HotkeyModel(hotkeyStr); + try + { + HotkeyManager.Current.AddOrReplace(hotkeyStr, hotkey.CharKey, hotkey.ModifierKeys, action); + } + catch (Exception) + { + MessageBox.Show("Register hotkey: " + hotkeyStr + " failed."); + } + } - private void TextBoxBase_OnTextChanged(object sender, TextChangedEventArgs e) { - if (ignoreTextChange) { ignoreTextChange = false; return; } + public void RemoveHotkey(string hotkeyStr) + { + if (!string.IsNullOrEmpty(hotkeyStr)) + { + HotkeyManager.Current.Remove(hotkeyStr); + } + } - lastQuery = tbQuery.Text; - toolTip.IsOpen = false; - resultCtrl.Dirty = true; - Dispatcher.DelayInvoke("UpdateSearch", - o => { - Dispatcher.DelayInvoke("ClearResults", i => { - // first try to use clear method inside resultCtrl, which is more closer to the add new results - // and this will not bring splash issues.After waiting 30ms, if there still no results added, we - // must clear the result. otherwise, it will be confused why the query changed, but the results - // didn't. - if (resultCtrl.Dirty) resultCtrl.Clear(); - }, TimeSpan.FromMilliseconds(100), null); + private void SetCustomPluginHotkey() + { + if (UserSettingStorage.Instance.CustomPluginHotkeys == null) return; + foreach (CustomPluginHotkey hotkey in UserSettingStorage.Instance.CustomPluginHotkeys) + { + CustomPluginHotkey hotkey1 = hotkey; + SetHotkey(hotkey.Hotkey, delegate + { + ShowApp(); + ChangeQuery(hotkey1.ActionKeyword, true); + }); + } + } + + private void OnHotkey(object sender, HotkeyEventArgs e) + { + if (!IsVisible) + { + ShowWox(); + } + else + { + HideWox(); + } + e.Handled = true; + } + + private void InitProgressbarAnimation() + { + var da = new DoubleAnimation(progressBar.X2, ActualWidth + 100, new Duration(new TimeSpan(0, 0, 0, 0, 1600))); + var da1 = new DoubleAnimation(progressBar.X1, ActualWidth, new Duration(new TimeSpan(0, 0, 0, 0, 1600))); + Storyboard.SetTargetProperty(da, new PropertyPath("(Line.X2)")); + Storyboard.SetTargetProperty(da1, new PropertyPath("(Line.X1)")); + progressBarStoryboard.Children.Add(da); + progressBarStoryboard.Children.Add(da1); + progressBarStoryboard.RepeatBehavior = RepeatBehavior.Forever; + progressBar.Visibility = Visibility.Hidden; + progressBar.BeginStoryboard(progressBarStoryboard); + } + + private void InitialTray() + { + notifyIcon = new NotifyIcon { Text = "Wox", Icon = Properties.Resources.app, Visible = true }; + notifyIcon.Click += (o, e) => ShowWox(); + var open = new MenuItem("Open"); + open.Click += (o, e) => ShowWox(); + var setting = new MenuItem("Setting"); + setting.Click += (o, e) => OpenSettingDialog(); + var exit = new MenuItem("Exit"); + exit.Click += (o, e) => CloseApp(); + MenuItem[] childen = { open, setting, exit }; + notifyIcon.ContextMenu = new ContextMenu(childen); + } + + private void TextBoxBase_OnTextChanged(object sender, TextChangedEventArgs e) + { + if (ignoreTextChange) { ignoreTextChange = false; return; } + + lastQuery = tbQuery.Text; + toolTip.IsOpen = false; + resultCtrl.Dirty = true; + Dispatcher.DelayInvoke("UpdateSearch", + o => + { + Dispatcher.DelayInvoke("ClearResults", i => + { + // first try to use clear method inside resultCtrl, which is more closer to the add new results + // and this will not bring splash issues.After waiting 30ms, if there still no results added, we + // must clear the result. otherwise, it will be confused why the query changed, but the results + // didn't. + if (resultCtrl.Dirty) resultCtrl.Clear(); + }, TimeSpan.FromMilliseconds(100), null); queryHasReturn = false; - var q = new Query(lastQuery); - CommandFactory.DispatchCommand(q); - if (Plugins.HitThirdpartyKeyword(q)) { - Dispatcher.DelayInvoke("ShowProgressbar", originQuery => { - if (!queryHasReturn && originQuery == lastQuery) { - StartProgress(); - } - }, TimeSpan.FromSeconds(0), lastQuery); - } - }, TimeSpan.FromMilliseconds((isCMDMode = tbQuery.Text.StartsWith(">")) ? 0 : 150)); - } + var q = new Query(lastQuery); + CommandFactory.DispatchCommand(q); + if (Plugins.HitThirdpartyKeyword(q)) + { + Dispatcher.DelayInvoke("ShowProgressbar", originQuery => + { + if (!queryHasReturn && originQuery == lastQuery) + { + StartProgress(); + } + }, TimeSpan.FromSeconds(0), lastQuery); + } + }, TimeSpan.FromMilliseconds((isCMDMode = tbQuery.Text.StartsWith(">")) ? 0 : 150)); + } - private void Border_OnMouseDown(object sender, MouseButtonEventArgs e) { - if (e.ChangedButton == MouseButton.Left) DragMove(); - } + private void Border_OnMouseDown(object sender, MouseButtonEventArgs e) + { + if (e.ChangedButton == MouseButton.Left) DragMove(); + } - private void StartProgress() { - progressBar.Visibility = Visibility.Visible; - } + private void StartProgress() + { + progressBar.Visibility = Visibility.Visible; + } - private void StopProgress() { - progressBar.Visibility = Visibility.Hidden; - } + private void StopProgress() + { + progressBar.Visibility = Visibility.Hidden; + } - private void HideWox() { - Hide(); - } + private void HideWox() + { + Hide(); + } - private void ShowWox(bool selectAll = true) { - if (!double.IsNaN(Left) && !double.IsNaN(Top)) { - var origScreen = Screen.FromRectangle(new Rectangle((int)Left, (int)Top, (int)ActualWidth, (int)ActualHeight)); - var screen = Screen.FromPoint(System.Windows.Forms.Cursor.Position); - var coordX = (Left - origScreen.WorkingArea.Left) / (origScreen.WorkingArea.Width - ActualWidth); - var coordY = (Top - origScreen.WorkingArea.Top) / (origScreen.WorkingArea.Height - ActualHeight); - Left = (screen.WorkingArea.Width - ActualWidth) * coordX + screen.WorkingArea.Left; - Top = (screen.WorkingArea.Height - ActualHeight) * coordY + screen.WorkingArea.Top; - } + private void ShowWox(bool selectAll = true) + { + if (!double.IsNaN(Left) && !double.IsNaN(Top)) + { + var origScreen = Screen.FromRectangle(new Rectangle((int)Left, (int)Top, (int)ActualWidth, (int)ActualHeight)); + var screen = Screen.FromPoint(System.Windows.Forms.Cursor.Position); + var coordX = (Left - origScreen.WorkingArea.Left) / (origScreen.WorkingArea.Width - ActualWidth); + var coordY = (Top - origScreen.WorkingArea.Top) / (origScreen.WorkingArea.Height - ActualHeight); + Left = (screen.WorkingArea.Width - ActualWidth) * coordX + screen.WorkingArea.Left; + Top = (screen.WorkingArea.Height - ActualHeight) * coordY + screen.WorkingArea.Top; + } - Show(); - Activate(); - Focus(); - tbQuery.Focus(); - if (selectAll) tbQuery.SelectAll(); - } + Show(); + Activate(); + Focus(); + tbQuery.Focus(); + if (selectAll) tbQuery.SelectAll(); + } - public void ParseArgs(string[] args) { - if (args != null && args.Length > 0) { - switch (args[0].ToLower()) { - case "reloadplugin": - Plugins.Init(); - break; + public void ParseArgs(string[] args) + { + if (args != null && args.Length > 0) + { + switch (args[0].ToLower()) + { + case "reloadplugin": + Plugins.Init(); + break; - case "query": - if (args.Length > 1) { - string query = args[1]; - tbQuery.Text = query; - tbQuery.SelectAll(); - } - break; + case "query": + if (args.Length > 1) + { + string query = args[1]; + tbQuery.Text = query; + tbQuery.SelectAll(); + } + break; - case "hidestart": - HideApp(); - break; + case "hidestart": + HideApp(); + break; - case "installplugin": - var path = args[1]; - if (!File.Exists(path)) { - MessageBox.Show("Plugin " + path + " didn't exist"); - return; - } - PluginInstaller.Install(path); - break; - } - } - } + case "installplugin": + var path = args[1]; + if (!File.Exists(path)) + { + MessageBox.Show("Plugin " + path + " didn't exist"); + return; + } + PluginInstaller.Install(path); + break; + } + } + } - private void MainWindow_OnDeactivated(object sender, EventArgs e) { - if (UserSettingStorage.Instance.HideWhenDeactive) { - HideWox(); - } - } + private void MainWindow_OnDeactivated(object sender, EventArgs e) + { + if (UserSettingStorage.Instance.HideWhenDeactive) + { + HideWox(); + } + } - private bool KListener_hookedKeyboardCallback(KeyEvent keyevent, int vkcode, SpecialKeyState state) { - if (UserSettingStorage.Instance.ReplaceWinR) { - //todo:need refactoring. move those codes to CMD file or expose events - if (keyevent == KeyEvent.WM_KEYDOWN && vkcode == (int)Keys.R && state.WinPressed) { - WinRStroked = true; - Dispatcher.BeginInvoke(new Action(OnWinRPressed)); - return false; - } - if (keyevent == KeyEvent.WM_KEYUP && WinRStroked && vkcode == (int)Keys.LWin) { - WinRStroked = false; - keyboardSimulator.ModifiedKeyStroke(VirtualKeyCode.LWIN, VirtualKeyCode.CONTROL); - return false; - } - } - return true; - } + private bool KListener_hookedKeyboardCallback(KeyEvent keyevent, int vkcode, SpecialKeyState state) + { + if (UserSettingStorage.Instance.ReplaceWinR) + { + //todo:need refactoring. move those codes to CMD file or expose events + if (keyevent == KeyEvent.WM_KEYDOWN && vkcode == (int)Keys.R && state.WinPressed) + { + WinRStroked = true; + Dispatcher.BeginInvoke(new Action(OnWinRPressed)); + return false; + } + if (keyevent == KeyEvent.WM_KEYUP && WinRStroked && vkcode == (int)Keys.LWin) + { + WinRStroked = false; + keyboardSimulator.ModifiedKeyStroke(VirtualKeyCode.LWIN, VirtualKeyCode.CONTROL); + return false; + } + } + return true; + } - private void OnWinRPressed() { - ShowWox(false); - if (!tbQuery.Text.StartsWith(">")) { - resultCtrl.Clear(); - ChangeQuery(">"); - } - tbQuery.CaretIndex = tbQuery.Text.Length; - tbQuery.SelectionStart = 1; - tbQuery.SelectionLength = tbQuery.Text.Length - 1; - } + private void OnWinRPressed() + { + ShowWox(false); + if (!tbQuery.Text.StartsWith(">")) + { + resultCtrl.Clear(); + ChangeQuery(">"); + } + tbQuery.CaretIndex = tbQuery.Text.Length; + tbQuery.SelectionStart = 1; + tbQuery.SelectionLength = tbQuery.Text.Length - 1; + } - private void updateCmdMode() { - var selected = resultCtrl.AcceptSelect(); - if (selected != null) { - ignoreTextChange = true; - tbQuery.Text = ">" + selected.Title; - tbQuery.CaretIndex = tbQuery.Text.Length; - } - } + private void updateCmdMode() + { + var selected = resultCtrl.AcceptSelect(); + if (selected != null) + { + ignoreTextChange = true; + tbQuery.Text = ">" + selected.Title; + tbQuery.CaretIndex = tbQuery.Text.Length; + } + } - private void TbQuery_OnPreviewKeyDown(object sender, KeyEventArgs e) { - //when alt is pressed, the real key should be e.SystemKey + private void TbQuery_OnPreviewKeyDown(object sender, KeyEventArgs e) + { + //when alt is pressed, the real key should be e.SystemKey - Action Shift_GoBack = () => { - if (e.KeyboardDevice.IsKeyDown(Key.LeftShift) || e.KeyboardDevice.IsKeyDown(Key.RightShift)) { - if (tbQuery.Text.EndsWith("\\")) { - tbQuery.Text = tbQuery.Text.Remove(tbQuery.Text.Length - 1); - } + Action Shift_GoBack = () => + { + if (e.KeyboardDevice.IsKeyDown(Key.LeftShift) || e.KeyboardDevice.IsKeyDown(Key.RightShift)) + { + if (tbQuery.Text.EndsWith("\\")) + { + tbQuery.Text = tbQuery.Text.Remove(tbQuery.Text.Length - 1); + } - if (tbQuery.Text.Contains("\\")) { - var index = tbQuery.Text.LastIndexOf("\\"); - tbQuery.Text = tbQuery.Text.Remove(index) + "\\"; - } - else { - tbQuery.Text = ""; - return; - } - } + if (tbQuery.Text.Contains("\\")) + { + var index = tbQuery.Text.LastIndexOf("\\"); + tbQuery.Text = tbQuery.Text.Remove(index) + "\\"; + } + else + { + tbQuery.Text = ""; + return; + } + } - tbQuery.CaretIndex = int.MaxValue; - }; + tbQuery.CaretIndex = int.MaxValue; + }; - Key key = (e.Key == Key.System ? e.SystemKey : e.Key); - switch (key) { - case Key.Escape: - HideWox(); - e.Handled = true; - break; + Key key = (e.Key == Key.System ? e.SystemKey : e.Key); + switch (key) + { + case Key.Escape: + HideWox(); + e.Handled = true; + break; - case Key.Down: - resultCtrl.SelectNext(); - if (isCMDMode) updateCmdMode(); - toolTip.IsOpen = false; - e.Handled = true; - break; + case Key.Down: + resultCtrl.SelectNext(); + if (isCMDMode) updateCmdMode(); + toolTip.IsOpen = false; + e.Handled = true; + break; - case Key.Up: - resultCtrl.SelectPrev(); - if (isCMDMode) updateCmdMode(); - toolTip.IsOpen = false; - e.Handled = true; - break; + case Key.Up: + resultCtrl.SelectPrev(); + if (isCMDMode) updateCmdMode(); + toolTip.IsOpen = false; + e.Handled = true; + break; - case Key.PageDown: - resultCtrl.SelectNextPage(); - if (isCMDMode) updateCmdMode(); - toolTip.IsOpen = false; - e.Handled = true; - break; + case Key.PageDown: + resultCtrl.SelectNextPage(); + if (isCMDMode) updateCmdMode(); + toolTip.IsOpen = false; + e.Handled = true; + break; - case Key.PageUp: - resultCtrl.SelectPrevPage(); - if (isCMDMode) updateCmdMode(); - toolTip.IsOpen = false; - e.Handled = true; - break; + case Key.PageUp: + resultCtrl.SelectPrevPage(); + if (isCMDMode) updateCmdMode(); + toolTip.IsOpen = false; + e.Handled = true; + break; - case Key.Enter: - Shift_GoBack(); - AcceptSelect(resultCtrl.AcceptSelect()); - e.Handled = true; - break; + case Key.Enter: + Shift_GoBack(); + AcceptSelect(resultCtrl.AcceptSelect()); + e.Handled = true; + break; - case Key.Tab: - Shift_GoBack(); - AcceptSelect(resultCtrl.AcceptSelect()); - if (!tbQuery.Text.EndsWith("\\")) tbQuery.Text += "\\"; - AcceptSelect(resultCtrl.AcceptSelect()); - tbQuery.CaretIndex = int.MaxValue; - e.Handled = true; - break; - } - } + case Key.Tab: + Shift_GoBack(); + AcceptSelect(resultCtrl.AcceptSelect()); + if (!tbQuery.Text.EndsWith("\\")) tbQuery.Text += "\\"; + AcceptSelect(resultCtrl.AcceptSelect()); + tbQuery.CaretIndex = int.MaxValue; + e.Handled = true; + break; + } + } - private void AcceptSelect(Result result) { - if (!resultCtrl.Dirty && result != null) { - if (result.Action != null) { - bool hideWindow = result.Action(new ActionContext() { - SpecialKeyState = new GlobalHotkey().CheckModifiers() - }); - if (hideWindow) { - HideWox(); - } - UserSelectedRecordStorage.Instance.Add(result); - } - } - } + private void AcceptSelect(Result result) + { + if (!resultCtrl.Dirty && result != null) + { + if (result.Action != null) + { + bool hideWindow = result.Action(new ActionContext() + { + SpecialKeyState = new GlobalHotkey().CheckModifiers() + }); + if (hideWindow) + { + HideWox(); + } + UserSelectedRecordStorage.Instance.Add(result); + } + } + } - public void OnUpdateResultView(List list) { + public void OnUpdateResultView(List list) + { queryHasReturn = true; progressBar.Dispatcher.Invoke(new Action(StopProgress)); - if (list == null || list.Count == 0) return; + if (list == null || list.Count == 0) return; if (list.Count > 0) { @@ -478,58 +587,65 @@ namespace Wox { resultCtrl.AddResults(l); })), TimeSpan.FromMilliseconds(isCMDMode ? 0 : 50)); } - } + } - public void SetTheme(string themeName) { - var dict = new ResourceDictionary { - Source = new Uri(Path.Combine(Path.GetDirectoryName(System.Windows.Forms.Application.ExecutablePath), "Themes\\" + themeName + ".xaml"), UriKind.Absolute) - }; + public void SetTheme(string themeName) + { + var dict = new ResourceDictionary + { + Source = new Uri(Path.Combine(Path.GetDirectoryName(System.Windows.Forms.Application.ExecutablePath), "Themes\\" + themeName + ".xaml"), UriKind.Absolute) + }; - Style queryBoxStyle = dict["QueryBoxStyle"] as Style; - if (queryBoxStyle != null) { - queryBoxStyle.Setters.Add(new Setter(TextBox.FontFamilyProperty, new FontFamily(UserSettingStorage.Instance.QueryBoxFont))); - queryBoxStyle.Setters.Add(new Setter(TextBox.FontStyleProperty, FontHelper.GetFontStyleFromInvariantStringOrNormal(UserSettingStorage.Instance.QueryBoxFontStyle))); - queryBoxStyle.Setters.Add(new Setter(TextBox.FontWeightProperty, FontHelper.GetFontWeightFromInvariantStringOrNormal(UserSettingStorage.Instance.QueryBoxFontWeight))); - queryBoxStyle.Setters.Add(new Setter(TextBox.FontStretchProperty, FontHelper.GetFontStretchFromInvariantStringOrNormal(UserSettingStorage.Instance.QueryBoxFontStretch))); - } + Style queryBoxStyle = dict["QueryBoxStyle"] as Style; + if (queryBoxStyle != null) + { + queryBoxStyle.Setters.Add(new Setter(TextBox.FontFamilyProperty, new FontFamily(UserSettingStorage.Instance.QueryBoxFont))); + queryBoxStyle.Setters.Add(new Setter(TextBox.FontStyleProperty, FontHelper.GetFontStyleFromInvariantStringOrNormal(UserSettingStorage.Instance.QueryBoxFontStyle))); + queryBoxStyle.Setters.Add(new Setter(TextBox.FontWeightProperty, FontHelper.GetFontWeightFromInvariantStringOrNormal(UserSettingStorage.Instance.QueryBoxFontWeight))); + queryBoxStyle.Setters.Add(new Setter(TextBox.FontStretchProperty, FontHelper.GetFontStretchFromInvariantStringOrNormal(UserSettingStorage.Instance.QueryBoxFontStretch))); + } - Style resultItemStyle = dict["ItemTitleStyle"] as Style; - Style resultSubItemStyle = dict["ItemSubTitleStyle"] as Style; - Style resultItemSelectedStyle = dict["ItemTitleSelectedStyle"] as Style; - Style resultSubItemSelectedStyle = dict["ItemSubTitleSelectedStyle"] as Style; - if (resultItemStyle != null && resultSubItemStyle != null && resultSubItemSelectedStyle != null && resultItemSelectedStyle != null) { - Setter fontFamily = new Setter(TextBlock.FontFamilyProperty, new FontFamily(UserSettingStorage.Instance.ResultItemFont)); - Setter fontStyle = new Setter(TextBlock.FontStyleProperty, FontHelper.GetFontStyleFromInvariantStringOrNormal(UserSettingStorage.Instance.ResultItemFontStyle)); - Setter fontWeight = new Setter(TextBlock.FontWeightProperty, FontHelper.GetFontWeightFromInvariantStringOrNormal(UserSettingStorage.Instance.ResultItemFontWeight)); - Setter fontStretch = new Setter(TextBlock.FontStretchProperty, FontHelper.GetFontStretchFromInvariantStringOrNormal(UserSettingStorage.Instance.ResultItemFontStretch)); + Style resultItemStyle = dict["ItemTitleStyle"] as Style; + Style resultSubItemStyle = dict["ItemSubTitleStyle"] as Style; + Style resultItemSelectedStyle = dict["ItemTitleSelectedStyle"] as Style; + Style resultSubItemSelectedStyle = dict["ItemSubTitleSelectedStyle"] as Style; + if (resultItemStyle != null && resultSubItemStyle != null && resultSubItemSelectedStyle != null && resultItemSelectedStyle != null) + { + Setter fontFamily = new Setter(TextBlock.FontFamilyProperty, new FontFamily(UserSettingStorage.Instance.ResultItemFont)); + Setter fontStyle = new Setter(TextBlock.FontStyleProperty, FontHelper.GetFontStyleFromInvariantStringOrNormal(UserSettingStorage.Instance.ResultItemFontStyle)); + Setter fontWeight = new Setter(TextBlock.FontWeightProperty, FontHelper.GetFontWeightFromInvariantStringOrNormal(UserSettingStorage.Instance.ResultItemFontWeight)); + Setter fontStretch = new Setter(TextBlock.FontStretchProperty, FontHelper.GetFontStretchFromInvariantStringOrNormal(UserSettingStorage.Instance.ResultItemFontStretch)); - Setter[] setters = new Setter[] { fontFamily, fontStyle, fontWeight, fontStretch }; - Array.ForEach(new Style[] { resultItemStyle, resultSubItemStyle, resultItemSelectedStyle, resultSubItemSelectedStyle }, o => Array.ForEach(setters, p => o.Setters.Add(p))); - } + Setter[] setters = new Setter[] { fontFamily, fontStyle, fontWeight, fontStretch }; + Array.ForEach(new Style[] { resultItemStyle, resultSubItemStyle, resultItemSelectedStyle, resultSubItemSelectedStyle }, o => Array.ForEach(setters, p => o.Setters.Add(p))); + } - Application.Current.Resources.MergedDictionaries.Clear(); - Application.Current.Resources.MergedDictionaries.Add(dict); + Application.Current.Resources.MergedDictionaries.Clear(); + Application.Current.Resources.MergedDictionaries.Add(dict); - this.Opacity = this.AllowsTransparency ? UserSettingStorage.Instance.Opacity : 1; - } + this.Opacity = this.AllowsTransparency ? UserSettingStorage.Instance.Opacity : 1; + } - public bool ShellRun(string cmd) { - try { - if (string.IsNullOrEmpty(cmd)) - throw new ArgumentNullException(); + public bool ShellRun(string cmd) + { + try + { + if (string.IsNullOrEmpty(cmd)) + throw new ArgumentNullException(); - Wox.Infrastructure.WindowsShellRun.Start(cmd); - return true; - } - catch (Exception ex) { - ShowMsg("Could not start " + cmd, ex.Message, null); - } - return false; - } + Wox.Infrastructure.WindowsShellRun.Start(cmd); + return true; + } + catch (Exception ex) + { + ShowMsg("Could not start " + cmd, ex.Message, null); + } + return false; + } - private void MainWindow_OnDrop(object sender, DragEventArgs e) - { + private void MainWindow_OnDrop(object sender, DragEventArgs e) + { if (e.Data.GetDataPresent(System.Windows.DataFormats.FileDrop)) { // Note that you can have more than one file. @@ -543,11 +659,11 @@ namespace Wox { MessageBox.Show("incorrect wox plugin file."); } } - } + } - private void TbQuery_OnPreviewDragOver(object sender, DragEventArgs e) - { - e.Handled = true; - } - } + private void TbQuery_OnPreviewDragOver(object sender, DragEventArgs e) + { + e.Handled = true; + } + } } \ No newline at end of file diff --git a/Wox/PluginLoader/ExecutablePluginLoader.cs b/Wox/PluginLoader/ExecutablePluginLoader.cs new file mode 100644 index 0000000000..e49e08ae9b --- /dev/null +++ b/Wox/PluginLoader/ExecutablePluginLoader.cs @@ -0,0 +1,29 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using Wox.Plugin; + +namespace Wox.PluginLoader +{ + public class ExecutablePluginLoader : BasePluginLoader + { + public override List LoadPlugin() + { + List plugins = new List(); + List metadatas = pluginMetadatas.Where(o => o.Language.ToUpper() == AllowedLanguage.ExecutableFile.ToUpper()).ToList(); + foreach (PluginMetadata metadata in metadatas) + { + ExecutablePluginWrapper executer = new ExecutablePluginWrapper(); + PluginPair pair = new PluginPair() + { + Plugin = executer, + Metadata = metadata + }; + plugins.Add(pair); + } + + return plugins; + } + } +} diff --git a/Wox/PluginLoader/ExecutablePluginWrapper.cs b/Wox/PluginLoader/ExecutablePluginWrapper.cs new file mode 100644 index 0000000000..a638c7a51a --- /dev/null +++ b/Wox/PluginLoader/ExecutablePluginWrapper.cs @@ -0,0 +1,72 @@ +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.IO; +using System.Linq; +using System.Text; +using Newtonsoft.Json; +using Wox.Plugin; +using Wox.RPC; + +namespace Wox.PluginLoader +{ + public class ExecutablePluginWrapper : IPlugin + { + private PluginInitContext context; + private static string executeDirectory = Path.GetDirectoryName(System.Windows.Forms.Application.ExecutablePath); + + public List Query(Query query) + { + List results = new List(); + try + { + ProcessStartInfo start = new ProcessStartInfo(); + start.FileName = Path.Combine(executeDirectory, "PYTHONTHOME\\Scripts\\python.exe"); + start.Arguments = string.Format("{0} \"{1}\"", + context.CurrentPluginMetadata.ExecuteFilePath, + RPC.JsonRPC.GetRPC("query", query.GetAllRemainingParameter())); + start.UseShellExecute = false; + start.CreateNoWindow = true; + start.RedirectStandardOutput = true; + using (Process process = Process.Start(start)) + { + if (process != null) + { + using (StreamReader reader = process.StandardOutput) + { + string output = reader.ReadToEnd(); + if (!string.IsNullOrEmpty(output)) + { + JsonPRCModel rpc = JsonConvert.DeserializeObject(output); + var rpcresults = JsonConvert.DeserializeObject>(rpc.result); + List r = new List(); + foreach (ActionJsonRPCResult result in rpcresults) + { + if (!string.IsNullOrEmpty(result.ActionJSONRPC)) + { + result.Action = (context) => + { + return true; + }; + } + r.Add(result); + } + return r; + } + } + } + } + } + catch + { + } + + return results; + } + + public void Init(PluginInitContext context) + { + this.context = context; + } + } +} diff --git a/Wox/PluginLoader/Plugins.cs b/Wox/PluginLoader/Plugins.cs index d12a0240ba..03eecab4fc 100644 --- a/Wox/PluginLoader/Plugins.cs +++ b/Wox/PluginLoader/Plugins.cs @@ -1,96 +1,64 @@ using System; using System.Collections.Generic; using System.Linq; -using System.Text; -using System.Threading; -using Microsoft.CSharp; using Wox.Helper; -using Wox.Infrastructure; -using Wox.Infrastructure.Storage; -using Wox.Infrastructure.Storage.UserSettings; using Wox.Plugin; -namespace Wox.PluginLoader { - public static class Plugins { - //private static string debuggerMode = null; - public static String DebuggerMode { get; private set; } +namespace Wox.PluginLoader +{ + public static class Plugins + { + public static String DebuggerMode { get; private set; } + private static List plugins = new List(); - private static List plugins = new List(); - private static ManualResetEvent initializing = null; + public static void Init() + { + plugins.Clear(); + BasePluginLoader.ParsePluginsConfig(); - public static void Init() { - if (initializing != null) return; + plugins.AddRange(new PythonPluginLoader().LoadPlugin()); + plugins.AddRange(new CSharpPluginLoader().LoadPlugin()); + plugins.AddRange(new ExecutablePluginLoader().LoadPlugin()); - initializing = new ManualResetEvent(false); - plugins.Clear(); - BasePluginLoader.ParsePluginsConfig(); - - plugins.AddRange(new PythonPluginLoader().LoadPlugin()); - plugins.AddRange(new CSharpPluginLoader().LoadPlugin()); - Forker forker = new Forker(); - foreach (IPlugin plugin in plugins.Select(pluginPair => pluginPair.Plugin)) { - IPlugin plugin1 = plugin; - PluginPair pluginPair = plugins.FirstOrDefault(o => o.Plugin == plugin1); - if (pluginPair != null) { - PluginMetadata metadata = pluginPair.Metadata; - pluginPair.InitContext = new PluginInitContext() { - Plugins = plugins, - CurrentPluginMetadata = metadata, - ChangeQuery = s => App.Window.Dispatcher.Invoke(new Action(() => App.Window.ChangeQuery(s))), - CloseApp = () => App.Window.Dispatcher.Invoke(new Action(() => App.Window.CloseApp())), - HideApp = () => App.Window.Dispatcher.Invoke(new Action(() => App.Window.HideApp())), - ShowApp = () => App.Window.Dispatcher.Invoke(new Action(() => App.Window.ShowApp())), - ShowMsg = (title, subTitle, iconPath) => App.Window.Dispatcher.Invoke(new Action(() => - App.Window.ShowMsg(title, subTitle, iconPath))), - OpenSettingDialog = () => App.Window.Dispatcher.Invoke(new Action(() => App.Window.OpenSettingDialog())), - ShowCurrentResultItemTooltip = (msg) => App.Window.Dispatcher.Invoke(new Action(() => App.Window.ShowCurrentResultItemTooltip(msg))), - ReloadPlugins = () => App.Window.Dispatcher.Invoke(new Action(() => Init())), - InstallPlugin = (filePath) => App.Window.Dispatcher.Invoke(new Action(() => { - PluginInstaller.Install(filePath); - })), - StartLoadingBar = () => App.Window.Dispatcher.Invoke(new Action(() => App.Window.StartLoadingBar())), - StopLoadingBar = () => App.Window.Dispatcher.Invoke(new Action(() => App.Window.StopLoadingBar())), - //ShellRun = (cmd) => (bool)App.Window.Dispatcher.Invoke(new Func(() => App.Window.ShellRun(cmd))) - }; + Forker forker = new Forker(); + foreach (IPlugin plugin in plugins.Select(pluginPair => pluginPair.Plugin)) + { + IPlugin plugin1 = plugin; + PluginPair pluginPair = plugins.FirstOrDefault(o => o.Plugin == plugin1); + if (pluginPair != null) + { + PluginMetadata metadata = pluginPair.Metadata; + pluginPair.InitContext = new PluginInitContext() + { + CurrentPluginMetadata = metadata, + API = App.Window + }; - pluginPair.InitContext.ShellRun = (cmd) => { - try { - return (bool)App.Window.Dispatcher.Invoke(new Func(() => App.Window.ShellRun(cmd))); - } - catch (Exception) { - return false; - } - }; + forker.Fork(() => plugin1.Init(pluginPair.InitContext)); + } + } - forker.Fork(() => plugin1.Init(pluginPair.InitContext)); - } - } + forker.Join(); + } - ThreadPool.QueueUserWorkItem(o => { - forker.Join(); - initializing.Set(); - initializing = null; - }); - } + public static List AllPlugins + { + get + { + return plugins; + } + } - public static List AllPlugins { - get { - var init = initializing; - if (init != null) { - init.WaitOne(); - } - return plugins; - } - } + public static bool HitThirdpartyKeyword(Query query) + { + if (string.IsNullOrEmpty(query.ActionName)) return false; - public static bool HitThirdpartyKeyword(Query query) { - if (string.IsNullOrEmpty(query.ActionName)) return false; + return plugins.Any(o => o.Metadata.PluginType == PluginType.ThirdParty && o.Metadata.ActionKeyword == query.ActionName); + } - return plugins.Any(o => o.Metadata.PluginType == PluginType.ThirdParty && o.Metadata.ActionKeyword == query.ActionName); - } - - public static void ActivatePluginDebugger(string path) { - DebuggerMode = path; - } - } + public static void ActivatePluginDebugger(string path) + { + DebuggerMode = path; + } + } } diff --git a/Wox/RPC/JsonPRCModel.cs b/Wox/RPC/JsonPRCModel.cs new file mode 100644 index 0000000000..79d133b535 --- /dev/null +++ b/Wox/RPC/JsonPRCModel.cs @@ -0,0 +1,17 @@ +using Wox.Plugin; + +namespace Wox.RPC +{ + public class JsonPRCModel + { + public int id { get; set; } + public string jsonrpc { get; set; } + + public string result { get; set; } + } + + public class ActionJsonRPCResult : Result + { + public string ActionJSONRPC { get; set; } + } +} diff --git a/Wox/RPC/JsonRPC.cs b/Wox/RPC/JsonRPC.cs new file mode 100644 index 0000000000..3ce2cb5725 --- /dev/null +++ b/Wox/RPC/JsonRPC.cs @@ -0,0 +1,20 @@ +using System.Collections.Generic; +using System.Linq; + +namespace Wox.RPC +{ + public class JsonRPC + { + public static string GetRPC(string method, List paras) + { + var list = paras.Select(s => string.Format(@"\""{0}\""", s)); + return string.Format(@"{{\""jsonrpc\"": \""2.0\"",\""method\"": \""{0}\"", \""params\"": [{1}], \""id\"": 1}}", + method, string.Join(",", list.ToArray())); + } + + public static string GetRPC(string method, string para) + { + return GetRPC(method, new List() { para }); + } + } +} diff --git a/Wox/Wox.csproj b/Wox/Wox.csproj index 53e586e22b..c67f6f5efc 100644 --- a/Wox/Wox.csproj +++ b/Wox/Wox.csproj @@ -138,11 +138,15 @@ HotkeyControl.xaml + Msg.xaml + + + From 55c27516b258187ffe2d9755d42ec983a07f4c21 Mon Sep 17 00:00:00 2001 From: qianlifeng Date: Sun, 6 Jul 2014 22:57:11 +0800 Subject: [PATCH 02/10] Refactoring Plugin Loader [WIP]. --- Wox.Plugin/AllowedLanguage.cs | 2 +- Wox/PluginLoader/BasePluginLoader.cs | 134 +++-------------- Wox/PluginLoader/BasePluginWrapper.cs | 92 ++++++++++++ ...nLoader.cs => CSharpPluginConfigLoader.cs} | 7 +- Wox/PluginLoader/ExecutablePluginLoader.cs | 29 ---- Wox/PluginLoader/ExecutablePluginWrapper.cs | 72 --------- Wox/PluginLoader/PluginConfigLoader.cs | 119 +++++++++++++++ Wox/PluginLoader/Plugins.cs | 7 +- Wox/PluginLoader/PythonPluginLoader.cs | 55 ------- Wox/PluginLoader/PythonPluginWrapper.cs | 139 +++--------------- Wox/Wox.csproj | 7 +- 11 files changed, 266 insertions(+), 397 deletions(-) create mode 100644 Wox/PluginLoader/BasePluginWrapper.cs rename Wox/PluginLoader/{CSharpPluginLoader.cs => CSharpPluginConfigLoader.cs} (91%) delete mode 100644 Wox/PluginLoader/ExecutablePluginLoader.cs delete mode 100644 Wox/PluginLoader/ExecutablePluginWrapper.cs create mode 100644 Wox/PluginLoader/PluginConfigLoader.cs delete mode 100644 Wox/PluginLoader/PythonPluginLoader.cs diff --git a/Wox.Plugin/AllowedLanguage.cs b/Wox.Plugin/AllowedLanguage.cs index 32262b48f2..f226bb5815 100644 --- a/Wox.Plugin/AllowedLanguage.cs +++ b/Wox.Plugin/AllowedLanguage.cs @@ -19,7 +19,7 @@ namespace Wox.Plugin public static string ExecutableFile { - get { return "ExecutableFile"; } + get { return "executablefile"; } } public static bool IsAllowed(string language) diff --git a/Wox/PluginLoader/BasePluginLoader.cs b/Wox/PluginLoader/BasePluginLoader.cs index 6e13fec2b9..98b8e7b63f 100644 --- a/Wox/PluginLoader/BasePluginLoader.cs +++ b/Wox/PluginLoader/BasePluginLoader.cs @@ -1,118 +1,32 @@ using System; using System.Collections.Generic; -using System.IO; using System.Linq; -using System.Reflection; -using System.Windows.Forms; -using Newtonsoft.Json; -using Wox.Helper; -using Wox.Infrastructure.Storage.UserSettings; +using System.Text; using Wox.Plugin; -using Wox.Plugin.SystemPlugins; +using Wox.RPC; -namespace Wox.PluginLoader { - public abstract class BasePluginLoader { - private static string PluginPath = Path.Combine(Path.GetDirectoryName(System.Windows.Forms.Application.ExecutablePath), "Plugins"); - private static string PluginConfigName = "plugin.json"; - protected static List pluginMetadatas = new List(); - public abstract List LoadPlugin(); +namespace Wox.PluginLoader +{ + public class BasePluginLoader where T :BasePluginWrapper,new() + { + public List LoadPlugin(List pluginMetadatas) + { + List plugins = new List(); - public static void ParsePluginsConfig() { - pluginMetadatas.Clear(); - ParseSystemPlugins(); - ParseThirdPartyPlugins(); + T pluginWrapper = new T(); + List allowedLanguages = pluginWrapper.GetAllowedLanguages(); + List metadatas = pluginMetadatas.Where(o => allowedLanguages.Contains(o.Language.ToUpper())).ToList(); + foreach (PluginMetadata metadata in metadatas) + { + PluginPair pair = new PluginPair() + { + Plugin = pluginWrapper, + Metadata = metadata + }; + plugins.Add(pair); + } - if (Plugins.DebuggerMode != null) { - PluginMetadata metadata = GetMetadataFromJson(Plugins.DebuggerMode); - if (metadata != null) pluginMetadatas.Add(metadata); - } - } - - private static void ParseSystemPlugins() { - pluginMetadatas.Add(new PluginMetadata() { - Name = "System Plugins", - Author = "System", - Description = "system plugins collection", - Website = "http://www.getwox.com", - Language = AllowedLanguage.CSharp, - Version = "1.0", - PluginType = PluginType.System, - ActionKeyword = "*", - ExecuteFileName = "Wox.Plugin.SystemPlugins.dll", - PluginDirecotry = Path.GetDirectoryName(System.Windows.Forms.Application.ExecutablePath) - }); - } - - private static void ParseThirdPartyPlugins() { - if (!Directory.Exists(PluginPath)) - Directory.CreateDirectory(PluginPath); - - string[] directories = Directory.GetDirectories(PluginPath); - foreach (string directory in directories) { - if (File.Exists((Path.Combine(directory, "NeedDelete.txt")))) { - Directory.Delete(directory, true); - continue; - } - PluginMetadata metadata = GetMetadataFromJson(directory); - if (metadata != null) pluginMetadatas.Add(metadata); - } - } - - private static PluginMetadata GetMetadataFromJson(string pluginDirectory) { - string configPath = Path.Combine(pluginDirectory, PluginConfigName); - PluginMetadata metadata; - - if (!File.Exists(configPath)) { - Log.Warn(string.Format("parse plugin {0} failed: didn't find config file.", configPath)); - return null; - } - - try { - metadata = JsonConvert.DeserializeObject(File.ReadAllText(configPath)); - metadata.PluginType = PluginType.ThirdParty; - metadata.PluginDirecotry = pluginDirectory; - } - catch (Exception) { - string error = string.Format("Parse plugin config {0} failed: json format is not valid", configPath); - Log.Warn(error); -#if (DEBUG) - { - throw new WoxException(error); - } -#endif - return null; - } - - - if (!AllowedLanguage.IsAllowed(metadata.Language)) { - string error = string.Format("Parse plugin config {0} failed: invalid language {1}", configPath, metadata.Language); - Log.Warn(error); -#if (DEBUG) - { - throw new WoxException(error); - } -#endif - return null; - } - if (!File.Exists(metadata.ExecuteFilePath)) { - string error = string.Format("Parse plugin config {0} failed: ExecuteFile {1} didn't exist", configPath, metadata.ExecuteFilePath); - Log.Warn(error); -#if (DEBUG) - { - throw new WoxException(error); - } -#endif - return null; - } - - var customizedPluginConfig = - UserSettingStorage.Instance.CustomizedPluginConfigs.FirstOrDefault(o => o.ID == metadata.ID); - if (customizedPluginConfig != null && !string.IsNullOrEmpty(customizedPluginConfig.Actionword)) - { - metadata.ActionKeyword = customizedPluginConfig.Actionword; - } - - return metadata; - } - } + return plugins; + } + } } diff --git a/Wox/PluginLoader/BasePluginWrapper.cs b/Wox/PluginLoader/BasePluginWrapper.cs new file mode 100644 index 0000000000..ff450f8fb7 --- /dev/null +++ b/Wox/PluginLoader/BasePluginWrapper.cs @@ -0,0 +1,92 @@ +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.IO; +using System.Linq; +using System.Text; +using Newtonsoft.Json; +using Wox.Plugin; +using Wox.RPC; + +namespace Wox.PluginLoader +{ + public abstract class BasePluginWrapper : IPlugin + { + protected PluginInitContext context; + + public abstract List GetAllowedLanguages(); + protected abstract string GetFileName(); + + protected abstract string GetQueryArguments(Query query); + + protected abstract string GetActionJsonRPCArguments(ActionJsonRPCResult result); + + public List Query(Query query) + { + string fileName = GetFileName(); + string arguments = GetQueryArguments(query); + string output = Execute(fileName, arguments); + if (!string.IsNullOrEmpty(output)) + { + try + { + JsonPRCModel rpc = JsonConvert.DeserializeObject(output); + List rpcresults = + JsonConvert.DeserializeObject>(rpc.result); + List results = new List(); + foreach (ActionJsonRPCResult result in rpcresults) + { + if (!string.IsNullOrEmpty(result.ActionJSONRPC)) + { + ActionJsonRPCResult resultCopy = result; + result.Action = (c) => + { + Execute(fileName, GetActionJsonRPCArguments(resultCopy)); + return true; + }; + } + results.Add(result); + } + return results; + } + catch + { + } + } + return null; + } + + private string Execute(string fileName, string arguments) + { + try + { + ProcessStartInfo start = new ProcessStartInfo(); + start.FileName = fileName; + start.Arguments = arguments; + start.UseShellExecute = false; + start.CreateNoWindow = true; + start.RedirectStandardOutput = true; + using (Process process = Process.Start(start)) + { + if (process != null) + { + using (StreamReader reader = process.StandardOutput) + { + return reader.ReadToEnd(); + } + } + } + } + catch + { + return null; + } + return null; + } + + public void Init(PluginInitContext ctx) + { + this.context = ctx; + } + } +} diff --git a/Wox/PluginLoader/CSharpPluginLoader.cs b/Wox/PluginLoader/CSharpPluginConfigLoader.cs similarity index 91% rename from Wox/PluginLoader/CSharpPluginLoader.cs rename to Wox/PluginLoader/CSharpPluginConfigLoader.cs index 065a824558..088817792f 100644 --- a/Wox/PluginLoader/CSharpPluginLoader.cs +++ b/Wox/PluginLoader/CSharpPluginConfigLoader.cs @@ -8,9 +8,10 @@ using Wox.Plugin.SystemPlugins; namespace Wox.PluginLoader { - public class CSharpPluginLoader : BasePluginLoader { - - public override List LoadPlugin() { + public class CSharpPluginConfigLoader + { + public List LoadPlugin(List pluginMetadatas) + { var plugins = new List(); List metadatas = pluginMetadatas.Where(o => o.Language.ToUpper() == AllowedLanguage.CSharp.ToUpper()).ToList(); diff --git a/Wox/PluginLoader/ExecutablePluginLoader.cs b/Wox/PluginLoader/ExecutablePluginLoader.cs deleted file mode 100644 index e49e08ae9b..0000000000 --- a/Wox/PluginLoader/ExecutablePluginLoader.cs +++ /dev/null @@ -1,29 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using Wox.Plugin; - -namespace Wox.PluginLoader -{ - public class ExecutablePluginLoader : BasePluginLoader - { - public override List LoadPlugin() - { - List plugins = new List(); - List metadatas = pluginMetadatas.Where(o => o.Language.ToUpper() == AllowedLanguage.ExecutableFile.ToUpper()).ToList(); - foreach (PluginMetadata metadata in metadatas) - { - ExecutablePluginWrapper executer = new ExecutablePluginWrapper(); - PluginPair pair = new PluginPair() - { - Plugin = executer, - Metadata = metadata - }; - plugins.Add(pair); - } - - return plugins; - } - } -} diff --git a/Wox/PluginLoader/ExecutablePluginWrapper.cs b/Wox/PluginLoader/ExecutablePluginWrapper.cs deleted file mode 100644 index a638c7a51a..0000000000 --- a/Wox/PluginLoader/ExecutablePluginWrapper.cs +++ /dev/null @@ -1,72 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Diagnostics; -using System.IO; -using System.Linq; -using System.Text; -using Newtonsoft.Json; -using Wox.Plugin; -using Wox.RPC; - -namespace Wox.PluginLoader -{ - public class ExecutablePluginWrapper : IPlugin - { - private PluginInitContext context; - private static string executeDirectory = Path.GetDirectoryName(System.Windows.Forms.Application.ExecutablePath); - - public List Query(Query query) - { - List results = new List(); - try - { - ProcessStartInfo start = new ProcessStartInfo(); - start.FileName = Path.Combine(executeDirectory, "PYTHONTHOME\\Scripts\\python.exe"); - start.Arguments = string.Format("{0} \"{1}\"", - context.CurrentPluginMetadata.ExecuteFilePath, - RPC.JsonRPC.GetRPC("query", query.GetAllRemainingParameter())); - start.UseShellExecute = false; - start.CreateNoWindow = true; - start.RedirectStandardOutput = true; - using (Process process = Process.Start(start)) - { - if (process != null) - { - using (StreamReader reader = process.StandardOutput) - { - string output = reader.ReadToEnd(); - if (!string.IsNullOrEmpty(output)) - { - JsonPRCModel rpc = JsonConvert.DeserializeObject(output); - var rpcresults = JsonConvert.DeserializeObject>(rpc.result); - List r = new List(); - foreach (ActionJsonRPCResult result in rpcresults) - { - if (!string.IsNullOrEmpty(result.ActionJSONRPC)) - { - result.Action = (context) => - { - return true; - }; - } - r.Add(result); - } - return r; - } - } - } - } - } - catch - { - } - - return results; - } - - public void Init(PluginInitContext context) - { - this.context = context; - } - } -} diff --git a/Wox/PluginLoader/PluginConfigLoader.cs b/Wox/PluginLoader/PluginConfigLoader.cs new file mode 100644 index 0000000000..591af2143b --- /dev/null +++ b/Wox/PluginLoader/PluginConfigLoader.cs @@ -0,0 +1,119 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Reflection; +using System.Windows.Forms; +using Newtonsoft.Json; +using Wox.Helper; +using Wox.Infrastructure.Storage.UserSettings; +using Wox.Plugin; +using Wox.Plugin.SystemPlugins; + +namespace Wox.PluginLoader { + public abstract class PluginConfigLoader { + private static string PluginPath = Path.Combine(Path.GetDirectoryName(System.Windows.Forms.Application.ExecutablePath), "Plugins"); + private static string PluginConfigName = "plugin.json"; + private static List pluginMetadatas = new List(); + + public static List ParsePluginsConfig() + { + pluginMetadatas.Clear(); + ParseSystemPlugins(); + ParseThirdPartyPlugins(); + + if (Plugins.DebuggerMode != null) { + PluginMetadata metadata = GetMetadataFromJson(Plugins.DebuggerMode); + if (metadata != null) pluginMetadatas.Add(metadata); + } + return pluginMetadatas; + } + + private static void ParseSystemPlugins() { + pluginMetadatas.Add(new PluginMetadata() { + Name = "System Plugins", + Author = "System", + Description = "system plugins collection", + Website = "http://www.getwox.com", + Language = AllowedLanguage.CSharp, + Version = "1.0", + PluginType = PluginType.System, + ActionKeyword = "*", + ExecuteFileName = "Wox.Plugin.SystemPlugins.dll", + PluginDirecotry = Path.GetDirectoryName(System.Windows.Forms.Application.ExecutablePath) + }); + } + + private static void ParseThirdPartyPlugins() { + if (!Directory.Exists(PluginPath)) + Directory.CreateDirectory(PluginPath); + + string[] directories = Directory.GetDirectories(PluginPath); + foreach (string directory in directories) { + if (File.Exists((Path.Combine(directory, "NeedDelete.txt")))) { + Directory.Delete(directory, true); + continue; + } + PluginMetadata metadata = GetMetadataFromJson(directory); + if (metadata != null) pluginMetadatas.Add(metadata); + } + } + + private static PluginMetadata GetMetadataFromJson(string pluginDirectory) { + string configPath = Path.Combine(pluginDirectory, PluginConfigName); + PluginMetadata metadata; + + if (!File.Exists(configPath)) { + Log.Warn(string.Format("parse plugin {0} failed: didn't find config file.", configPath)); + return null; + } + + try { + metadata = JsonConvert.DeserializeObject(File.ReadAllText(configPath)); + metadata.PluginType = PluginType.ThirdParty; + metadata.PluginDirecotry = pluginDirectory; + } + catch (Exception) { + string error = string.Format("Parse plugin config {0} failed: json format is not valid", configPath); + Log.Warn(error); +#if (DEBUG) + { + throw new WoxException(error); + } +#endif + return null; + } + + + if (!AllowedLanguage.IsAllowed(metadata.Language)) { + string error = string.Format("Parse plugin config {0} failed: invalid language {1}", configPath, metadata.Language); + Log.Warn(error); +#if (DEBUG) + { + throw new WoxException(error); + } +#endif + return null; + } + if (!File.Exists(metadata.ExecuteFilePath)) { + string error = string.Format("Parse plugin config {0} failed: ExecuteFile {1} didn't exist", configPath, metadata.ExecuteFilePath); + Log.Warn(error); +#if (DEBUG) + { + throw new WoxException(error); + } +#endif + return null; + } + + var customizedPluginConfig = + UserSettingStorage.Instance.CustomizedPluginConfigs.FirstOrDefault(o => o.ID == metadata.ID); + if (customizedPluginConfig != null && !string.IsNullOrEmpty(customizedPluginConfig.Actionword)) + { + metadata.ActionKeyword = customizedPluginConfig.Actionword; + } + + return metadata; + } + } +} diff --git a/Wox/PluginLoader/Plugins.cs b/Wox/PluginLoader/Plugins.cs index 03eecab4fc..5d10e0da6c 100644 --- a/Wox/PluginLoader/Plugins.cs +++ b/Wox/PluginLoader/Plugins.cs @@ -14,11 +14,10 @@ namespace Wox.PluginLoader public static void Init() { plugins.Clear(); - BasePluginLoader.ParsePluginsConfig(); + List pluginMetadatas = PluginConfigLoader.ParsePluginsConfig(); - plugins.AddRange(new PythonPluginLoader().LoadPlugin()); - plugins.AddRange(new CSharpPluginLoader().LoadPlugin()); - plugins.AddRange(new ExecutablePluginLoader().LoadPlugin()); + plugins.AddRange(new CSharpPluginConfigLoader().LoadPlugin(pluginMetadatas)); + plugins.AddRange(new BasePluginLoader().LoadPlugin(pluginMetadatas)); Forker forker = new Forker(); foreach (IPlugin plugin in plugins.Select(pluginPair => pluginPair.Plugin)) diff --git a/Wox/PluginLoader/PythonPluginLoader.cs b/Wox/PluginLoader/PythonPluginLoader.cs deleted file mode 100644 index e5bd223b3f..0000000000 --- a/Wox/PluginLoader/PythonPluginLoader.cs +++ /dev/null @@ -1,55 +0,0 @@ -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using System.Threading; -using Python.Runtime; -using Wox.Plugin; -using Wox.Helper; - -namespace Wox.PluginLoader -{ - public class PythonPluginLoader : BasePluginLoader - { - public override List LoadPlugin() - { - if (!CheckPythonEnvironmentInstalled()) return new List(); - - List plugins = new List(); - List metadatas = pluginMetadatas.Where(o => o.Language.ToUpper() == AllowedLanguage.Python.ToUpper()).ToList(); - foreach (PluginMetadata metadata in metadatas) - { - PythonPluginWrapper python = new PythonPluginWrapper(metadata); - PluginPair pair = new PluginPair() - { - Plugin = python, - Metadata = metadata - }; - plugins.Add(pair); - } - - return plugins; - } - - private bool CheckPythonEnvironmentInstalled() { - try - { - SetPythonHome(); - PythonEngine.Initialize(); - PythonEngine.Shutdown(); - } - catch { - Log.Warn("Could't find python environment, all python plugins disabled."); - return false; - } - return true; - } - - private void SetPythonHome() - { - //Environment.SetEnvironmentVariable("PYTHONHOME",Path.Combine(Path.GetDirectoryName(Application.ExecutablePath),"PythonHome")); - //PythonEngine.PythonHome = - //PythonEngine.ProgramName - } - } -} diff --git a/Wox/PluginLoader/PythonPluginWrapper.cs b/Wox/PluginLoader/PythonPluginWrapper.cs index a021f7796d..f6c1f39667 100644 --- a/Wox/PluginLoader/PythonPluginWrapper.cs +++ b/Wox/PluginLoader/PythonPluginWrapper.cs @@ -1,142 +1,43 @@ using System; using System.Collections.Generic; +using System.IO; using System.Linq; -using Newtonsoft.Json; +using System.Threading; using Python.Runtime; -using Wox.Helper; using Wox.Plugin; +using Wox.Helper; +using Wox.RPC; namespace Wox.PluginLoader { - public class PythonPluginWrapper : IPlugin + public class PythonPluginWrapper : BasePluginWrapper { - private PluginMetadata metadata; - private string moduleName; + private static string woxDirectory = Path.GetDirectoryName(System.Windows.Forms.Application.ExecutablePath); - public PythonPluginWrapper(PluginMetadata metadata) + public override List GetAllowedLanguages() { - this.metadata = metadata; - moduleName = metadata.ExecuteFileName.Replace(".py", ""); + return new List() + { + AllowedLanguage.Python + }; } - public List Query(Query query) + protected override string GetFileName() { - try - { - string jsonResult = InvokeFunc("query", query.RawQuery); - if (string.IsNullOrEmpty(jsonResult)) - { - return new List(); - } - - List o = JsonConvert.DeserializeObject>(jsonResult); - List r = new List(); - foreach (PythonResult pythonResult in o) - { - PythonResult ps = pythonResult; - if (!string.IsNullOrEmpty(ps.ActionName)) - { - ps.Action = (context) => - { - InvokeFunc(ps.ActionName, GetPythonActionContext(context), new PyString(ps.ActionPara)); - return true; - }; - } - r.Add(ps); - } - return r; - } - catch (Exception e) - { -#if (DEBUG) - { - throw new WoxPythonException(e.Message); - } -#endif - Log.Error(string.Format("Python Plugin {0} query failed: {1}", metadata.Name, e.Message)); - } - - return new List(); + return Path.Combine(woxDirectory, "PYTHONTHOME\\Scripts\\python.exe"); } - private PyObject GetPythonActionContext(ActionContext context) + protected override string GetQueryArguments(Query query) { - PyDict dict = new PyDict(); - PyDict specialKeyStateDict = new PyDict(); - specialKeyStateDict["CtrlPressed"] = new PyString(context.SpecialKeyState.CtrlPressed.ToString()); - specialKeyStateDict["AltPressed"] = new PyString(context.SpecialKeyState.AltPressed.ToString()); - specialKeyStateDict["WinPressed"] = new PyString(context.SpecialKeyState.WinPressed.ToString()); - specialKeyStateDict["ShiftPressed"] = new PyString(context.SpecialKeyState.ShiftPressed.ToString()); - - dict["SpecialKeyState"] = specialKeyStateDict; - return dict; + return string.Format("{0} \"{1}\"", + context.CurrentPluginMetadata.ExecuteFilePath, + JsonRPC.GetRPC("query", query.GetAllRemainingParameter())); } - private string InvokeFunc(string func, params PyObject[] paras) + protected override string GetActionJsonRPCArguments(ActionJsonRPCResult result) { - string json = null; - - //if pythobn plugin folder name is chinese, here will deadlock. - IntPtr gs = PythonEngine.AcquireLock(); - - PyObject module = PythonEngine.ImportModule(moduleName); - if (module == null) - { - string error = string.Format("Python Invoke failed: {0} doesn't has module {1}", - metadata.ExecuteFilePath, moduleName); - Log.Error(error); - return json; - } - - if (module.HasAttr(func)) - { - try - { - PyObject res = paras.Length > 0 ? module.InvokeMethod(func, paras) : module.InvokeMethod(func); - json = Runtime.GetManagedString(res.Handle); - } - catch (Exception e) - { - string error = string.Format("Python Invoke failed: {0}", e.Message); - Log.Error(error); -#if (DEBUG) - { - throw new WoxPythonException(error); - } -#endif - } - - } - else - { - string error = string.Format("Python Invoke failed: {0} doesn't has function {1}", - metadata.ExecuteFilePath, func); - Log.Error(error); -#if (DEBUG) - { - throw new WoxPythonException(error); - } -#endif - } - - PythonEngine.ReleaseLock(gs); - - return json; - } - - private string InvokeFunc(string func, params string[] para) - { - PyObject[] paras = { }; - if (para != null && para.Length > 0) - { - paras = para.Select(o => new PyString(o)).ToArray(); - } - return InvokeFunc(func, paras); - } - - public void Init(PluginInitContext context) - { - + return string.Format("{0} \"{1}\"", context.CurrentPluginMetadata.ExecuteFilePath, + result.ActionJSONRPC); } } } diff --git a/Wox/Wox.csproj b/Wox/Wox.csproj index c67f6f5efc..384a3bc2bc 100644 --- a/Wox/Wox.csproj +++ b/Wox/Wox.csproj @@ -142,13 +142,12 @@ Msg.xaml + + - - - + - From 3efe3d63ce20e2668d4168adf6fd4a4b4f2ed938 Mon Sep 17 00:00:00 2001 From: qianlifeng Date: Mon, 7 Jul 2014 23:05:06 +0800 Subject: [PATCH 03/10] Refactoring [WIP] --- Pythonnet.Runtime/Python.Runtime.csproj | 111 -- Pythonnet.Runtime/Python.Runtime.mdp | 78 - Pythonnet.Runtime/arrayobject.cs | 252 --- Pythonnet.Runtime/assemblyinfo.cs | 48 - Pythonnet.Runtime/assemblymanager.cs | 376 ---- Pythonnet.Runtime/buildclrmodule.bat | 36 - Pythonnet.Runtime/classbase.cs | 170 -- Pythonnet.Runtime/classmanager.cs | 368 ---- Pythonnet.Runtime/classobject.cs | 299 ---- Pythonnet.Runtime/clrmodule.il | 278 --- Pythonnet.Runtime/clrmodule.pp.il | 279 --- Pythonnet.Runtime/clrobject.cs | 78 - Pythonnet.Runtime/codegenerator.cs | 62 - Pythonnet.Runtime/constructorbinder.cs | 96 -- Pythonnet.Runtime/constructorbinding.cs | 237 --- Pythonnet.Runtime/converter.cs | 714 -------- Pythonnet.Runtime/debughelper.cs | 128 -- Pythonnet.Runtime/delegatemanager.cs | 289 ---- Pythonnet.Runtime/delegateobject.cs | 119 -- Pythonnet.Runtime/eventbinding.cs | 132 -- Pythonnet.Runtime/eventobject.cs | 230 --- Pythonnet.Runtime/exceptions.cs | 638 ------- Pythonnet.Runtime/extensiontype.cs | 129 -- Pythonnet.Runtime/fieldobject.cs | 150 -- Pythonnet.Runtime/generictype.cs | 100 -- Pythonnet.Runtime/genericutil.cs | 141 -- Pythonnet.Runtime/importhook.cs | 243 --- Pythonnet.Runtime/indexer.cs | 68 - Pythonnet.Runtime/interfaceobject.cs | 89 - Pythonnet.Runtime/interfaces.cs | 40 - Pythonnet.Runtime/interop.cs | 544 ------ Pythonnet.Runtime/iterator.cs | 52 - Pythonnet.Runtime/managedtype.cs | 97 -- Pythonnet.Runtime/metatype.cs | 264 --- Pythonnet.Runtime/methodbinder.cs | 465 ----- Pythonnet.Runtime/methodbinding.cs | 193 --- Pythonnet.Runtime/methodobject.cs | 188 -- Pythonnet.Runtime/methodwrapper.cs | 61 - Pythonnet.Runtime/modulefunctionobject.cs | 58 - Pythonnet.Runtime/moduleobject.cs | 432 ----- Pythonnet.Runtime/modulepropertyobject.cs | 30 - Pythonnet.Runtime/monosupport.cs | 60 - Pythonnet.Runtime/nativecall.cs | 166 -- Pythonnet.Runtime/oldmodule.il | 274 --- Pythonnet.Runtime/overload.cs | 83 - Pythonnet.Runtime/propertyobject.cs | 164 -- Pythonnet.Runtime/pyansistring.cs | 82 - Pythonnet.Runtime/pydict.cs | 208 --- Pythonnet.Runtime/pyfloat.cs | 122 -- Pythonnet.Runtime/pyint.cs | 257 --- Pythonnet.Runtime/pyiter.cs | 76 - Pythonnet.Runtime/pylist.cs | 189 --- Pythonnet.Runtime/pylong.cs | 291 ---- Pythonnet.Runtime/pynumber.cs | 42 - Pythonnet.Runtime/pyobject.cs | 869 ---------- Pythonnet.Runtime/pysequence.cs | 172 -- Pythonnet.Runtime/pystring.cs | 85 - Pythonnet.Runtime/pythonengine.cs | 355 ---- Pythonnet.Runtime/pythonexception.cs | 150 -- Pythonnet.Runtime/pytuple.cs | 126 -- Pythonnet.Runtime/runtime.cs | 1606 ------------------ Pythonnet.Runtime/typemanager.cs | 452 ----- Pythonnet.Runtime/typemethod.cs | 54 - Pythonnet.Runtime/x64/clrmodule-platform.il | 11 - Pythonnet.Runtime/x86/clrmodule-platform.il | 11 - Wox.sln | 6 - Wox/Commands/PluginCommand.cs | 27 - Wox/PluginLoader/BasePluginLoader.cs | 4 +- Wox/PluginLoader/BasePluginWrapper.cs | 30 +- Wox/PluginLoader/CSharpPluginConfigLoader.cs | 2 +- Wox/PluginLoader/IPluginLoader.cs | 13 + Wox/PluginLoader/PythonPluginWrapper.cs | 31 +- Wox/RPC/JsonPRCModel.cs | 59 +- Wox/RPC/JsonRPC.cs | 6 +- Wox/Wox.csproj | 5 +- 75 files changed, 99 insertions(+), 14351 deletions(-) delete mode 100644 Pythonnet.Runtime/Python.Runtime.csproj delete mode 100644 Pythonnet.Runtime/Python.Runtime.mdp delete mode 100644 Pythonnet.Runtime/arrayobject.cs delete mode 100644 Pythonnet.Runtime/assemblyinfo.cs delete mode 100644 Pythonnet.Runtime/assemblymanager.cs delete mode 100644 Pythonnet.Runtime/buildclrmodule.bat delete mode 100644 Pythonnet.Runtime/classbase.cs delete mode 100644 Pythonnet.Runtime/classmanager.cs delete mode 100644 Pythonnet.Runtime/classobject.cs delete mode 100644 Pythonnet.Runtime/clrmodule.il delete mode 100644 Pythonnet.Runtime/clrmodule.pp.il delete mode 100644 Pythonnet.Runtime/clrobject.cs delete mode 100644 Pythonnet.Runtime/codegenerator.cs delete mode 100644 Pythonnet.Runtime/constructorbinder.cs delete mode 100644 Pythonnet.Runtime/constructorbinding.cs delete mode 100644 Pythonnet.Runtime/converter.cs delete mode 100644 Pythonnet.Runtime/debughelper.cs delete mode 100644 Pythonnet.Runtime/delegatemanager.cs delete mode 100644 Pythonnet.Runtime/delegateobject.cs delete mode 100644 Pythonnet.Runtime/eventbinding.cs delete mode 100644 Pythonnet.Runtime/eventobject.cs delete mode 100644 Pythonnet.Runtime/exceptions.cs delete mode 100644 Pythonnet.Runtime/extensiontype.cs delete mode 100644 Pythonnet.Runtime/fieldobject.cs delete mode 100644 Pythonnet.Runtime/generictype.cs delete mode 100644 Pythonnet.Runtime/genericutil.cs delete mode 100644 Pythonnet.Runtime/importhook.cs delete mode 100644 Pythonnet.Runtime/indexer.cs delete mode 100644 Pythonnet.Runtime/interfaceobject.cs delete mode 100644 Pythonnet.Runtime/interfaces.cs delete mode 100644 Pythonnet.Runtime/interop.cs delete mode 100644 Pythonnet.Runtime/iterator.cs delete mode 100644 Pythonnet.Runtime/managedtype.cs delete mode 100644 Pythonnet.Runtime/metatype.cs delete mode 100644 Pythonnet.Runtime/methodbinder.cs delete mode 100644 Pythonnet.Runtime/methodbinding.cs delete mode 100644 Pythonnet.Runtime/methodobject.cs delete mode 100644 Pythonnet.Runtime/methodwrapper.cs delete mode 100644 Pythonnet.Runtime/modulefunctionobject.cs delete mode 100644 Pythonnet.Runtime/moduleobject.cs delete mode 100644 Pythonnet.Runtime/modulepropertyobject.cs delete mode 100644 Pythonnet.Runtime/monosupport.cs delete mode 100644 Pythonnet.Runtime/nativecall.cs delete mode 100644 Pythonnet.Runtime/oldmodule.il delete mode 100644 Pythonnet.Runtime/overload.cs delete mode 100644 Pythonnet.Runtime/propertyobject.cs delete mode 100644 Pythonnet.Runtime/pyansistring.cs delete mode 100644 Pythonnet.Runtime/pydict.cs delete mode 100644 Pythonnet.Runtime/pyfloat.cs delete mode 100644 Pythonnet.Runtime/pyint.cs delete mode 100644 Pythonnet.Runtime/pyiter.cs delete mode 100644 Pythonnet.Runtime/pylist.cs delete mode 100644 Pythonnet.Runtime/pylong.cs delete mode 100644 Pythonnet.Runtime/pynumber.cs delete mode 100644 Pythonnet.Runtime/pyobject.cs delete mode 100644 Pythonnet.Runtime/pysequence.cs delete mode 100644 Pythonnet.Runtime/pystring.cs delete mode 100644 Pythonnet.Runtime/pythonengine.cs delete mode 100644 Pythonnet.Runtime/pythonexception.cs delete mode 100644 Pythonnet.Runtime/pytuple.cs delete mode 100644 Pythonnet.Runtime/runtime.cs delete mode 100644 Pythonnet.Runtime/typemanager.cs delete mode 100644 Pythonnet.Runtime/typemethod.cs delete mode 100644 Pythonnet.Runtime/x64/clrmodule-platform.il delete mode 100644 Pythonnet.Runtime/x86/clrmodule-platform.il create mode 100644 Wox/PluginLoader/IPluginLoader.cs diff --git a/Pythonnet.Runtime/Python.Runtime.csproj b/Pythonnet.Runtime/Python.Runtime.csproj deleted file mode 100644 index 613d3fb5d3..0000000000 --- a/Pythonnet.Runtime/Python.Runtime.csproj +++ /dev/null @@ -1,111 +0,0 @@ - - - - Debug - AnyCPU - {097B4AC0-74E9-4C58-BCF8-C69746EC8271} - Library - false - Python.Runtime - Python.Runtime - OnBuildSuccess - v3.5 - - - - true - full - true - ..\Output\Debug\ - TRACE;DEBUG;PYTHON27,UCS2 - true - - - pdbonly - true - ..\Output\Release\ - TRACE;PYTHON27, UCS2 - true - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - call "$(ProjectDir)buildclrmodule.bat" AnyCPU "$(ProjectDir)" "$(TargetDir)clr.pyd" -call "$(ProjectDir)buildclrmodule.bat" x64 "$(ProjectDir)" "$(TargetDir)clr64.pyd" - del "$(TargetDir)clr.pyd" -del "$(TargetDir)clr64.pyd" - - \ No newline at end of file diff --git a/Pythonnet.Runtime/Python.Runtime.mdp b/Pythonnet.Runtime/Python.Runtime.mdp deleted file mode 100644 index 845407ec2f..0000000000 --- a/Pythonnet.Runtime/Python.Runtime.mdp +++ /dev/null @@ -1,78 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/Pythonnet.Runtime/arrayobject.cs b/Pythonnet.Runtime/arrayobject.cs deleted file mode 100644 index c96fbd23c4..0000000000 --- a/Pythonnet.Runtime/arrayobject.cs +++ /dev/null @@ -1,252 +0,0 @@ -// ========================================================================== -// This software is subject to the provisions of the Zope Public License, -// Version 2.0 (ZPL). A copy of the ZPL should accompany this distribution. -// THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED -// WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -// WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS -// FOR A PARTICULAR PURPOSE. -// ========================================================================== - -using System; -using System.Collections; -using System.Reflection; - -namespace Python.Runtime { - - /// - /// Implements a Python type for managed arrays. This type is essentially - /// the same as a ClassObject, except that it provides sequence semantics - /// to support natural array usage (indexing) from Python. - /// - - internal class ArrayObject : ClassBase { - - internal ArrayObject(Type tp) : base(tp) {} - - internal override bool CanSubclass() { - return false; - } - - public static IntPtr tp_new(IntPtr tp, IntPtr args, IntPtr kw) { - ArrayObject self = GetManagedObject(tp) as ArrayObject; - if (Runtime.PyTuple_Size(args) != 1) { - return Exceptions.RaiseTypeError("array expects 1 argument"); - } - IntPtr op = Runtime.PyTuple_GetItem(args, 0); - Object result; - - if (!Converter.ToManaged(op, self.type, out result, true)) { - return IntPtr.Zero; - } - return CLRObject.GetInstHandle(result, tp); - } - - - //==================================================================== - // Implements __getitem__ for array types. - //==================================================================== - - public static IntPtr mp_subscript(IntPtr ob, IntPtr idx) { - CLRObject obj = (CLRObject)ManagedType.GetManagedObject(ob); - Array items = obj.inst as Array; - Type itemType = obj.inst.GetType().GetElementType(); - int rank = items.Rank; - int index = 0; - object value; - - // Note that CLR 1.0 only supports int indexes - methods to - // support long indices were introduced in 1.1. We could - // support long indices automatically, but given that long - // indices are not backward compatible and a relative edge - // case, we won't bother for now. - - // Single-dimensional arrays are the most common case and are - // cheaper to deal with than multi-dimensional, so check first. - - if (rank == 1) { - index = (int)Runtime.PyInt_AsLong(idx); - - if (Exceptions.ErrorOccurred()) { - return Exceptions.RaiseTypeError("invalid index value"); - } - - if (index < 0) { - index = items.Length + index; - } - - try { - value = items.GetValue(index); - } - catch (IndexOutOfRangeException) { - Exceptions.SetError(Exceptions.IndexError, - "array index out of range" - ); - return IntPtr.Zero; - } - - return Converter.ToPython(items.GetValue(index), itemType); - } - - // Multi-dimensional arrays can be indexed a la: list[1, 2, 3]. - - if (!Runtime.PyTuple_Check(idx)) { - Exceptions.SetError(Exceptions.TypeError, - "invalid index value" - ); - return IntPtr.Zero; - } - - int count = Runtime.PyTuple_Size(idx); - - Array args = Array.CreateInstance(typeof(Int32), count); - - for (int i = 0; i < count; i++) { - IntPtr op = Runtime.PyTuple_GetItem(idx, i); - index = (int)Runtime.PyInt_AsLong(op); - - if (Exceptions.ErrorOccurred()) { - return Exceptions.RaiseTypeError("invalid index value"); - } - - if (index < 0) { - index = items.GetLength(i) + index; - } - - args.SetValue(index, i); - } - - try { - value = items.GetValue((int[]) args); - } - catch (IndexOutOfRangeException) { - Exceptions.SetError(Exceptions.IndexError, - "array index out of range" - ); - return IntPtr.Zero; - } - - return Converter.ToPython(value, itemType); - } - - - //==================================================================== - // Implements __setitem__ for array types. - //==================================================================== - - public static int mp_ass_subscript(IntPtr ob, IntPtr idx, IntPtr v) { - CLRObject obj = (CLRObject)ManagedType.GetManagedObject(ob); - Array items = obj.inst as Array; - Type itemType = obj.inst.GetType().GetElementType(); - int rank = items.Rank; - int index = 0; - object value; - - if (items.IsReadOnly) { - Exceptions.RaiseTypeError("array is read-only"); - return -1; - } - - if (!Converter.ToManaged(v, itemType, out value, true)) { - return -1; - } - - if (rank == 1) { - index = (int)Runtime.PyInt_AsLong(idx); - - if (Exceptions.ErrorOccurred()) { - Exceptions.RaiseTypeError("invalid index value"); - return -1; - } - - if (index < 0) { - index = items.Length + index; - } - - try { - items.SetValue(value, index); - } - catch (IndexOutOfRangeException) { - Exceptions.SetError(Exceptions.IndexError, - "array index out of range" - ); - return -1; - } - - return 0; - } - - if (!Runtime.PyTuple_Check(idx)) { - Exceptions.RaiseTypeError("invalid index value"); - return -1; - } - - int count = Runtime.PyTuple_Size(idx); - - Array args = Array.CreateInstance(typeof(Int32), count); - - for (int i = 0; i < count; i++) { - IntPtr op = Runtime.PyTuple_GetItem(idx, i); - index = (int)Runtime.PyInt_AsLong(op); - - if (Exceptions.ErrorOccurred()) { - Exceptions.RaiseTypeError("invalid index value"); - return -1; - } - - if (index < 0) { - index = items.GetLength(i) + index; - } - - args.SetValue(index, i); - } - - try { - items.SetValue(value, (int[])args); - } - catch (IndexOutOfRangeException) { - Exceptions.SetError(Exceptions.IndexError, - "array index out of range" - ); - return -1; - } - - return 0; - } - - - //==================================================================== - // Implements __contains__ for array types. - //==================================================================== - - public static int sq_contains(IntPtr ob, IntPtr v) { - CLRObject obj = (CLRObject)ManagedType.GetManagedObject(ob); - Type itemType = obj.inst.GetType().GetElementType(); - IList items = obj.inst as IList; - object value; - - if (!Converter.ToManaged(v, itemType, out value, false)) { - return 0; - } - - if (items.Contains(value)) { - return 1; - } - - return 0; - } - - - //==================================================================== - // Implements __len__ for array types. - //==================================================================== - - public static int mp_length(IntPtr ob) { - CLRObject self = (CLRObject)ManagedType.GetManagedObject(ob); - Array items = self.inst as Array; - return items.Length; - } - - - } - -} diff --git a/Pythonnet.Runtime/assemblyinfo.cs b/Pythonnet.Runtime/assemblyinfo.cs deleted file mode 100644 index 2e15409e73..0000000000 --- a/Pythonnet.Runtime/assemblyinfo.cs +++ /dev/null @@ -1,48 +0,0 @@ -// ========================================================================== -// This software is subject to the provisions of the Zope Public License, -// Version 2.0 (ZPL). A copy of the ZPL should accompany this distribution. -// THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED -// WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -// WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS -// FOR A PARTICULAR PURPOSE. -// ========================================================================== - -using System; -using System.Reflection; -using System.Security.Permissions; -using System.Runtime.InteropServices; -using System.Resources; - -[assembly: System.Reflection.AssemblyProduct("Python for .NET")] -[assembly: System.Reflection.AssemblyVersion("2.0.0.2")] -[assembly: AssemblyDefaultAliasAttribute("Python.Runtime.dll")] -[assembly: CLSCompliant(true)] -[assembly: ComVisible(false)] - - -[assembly:PermissionSetAttribute(SecurityAction.RequestMinimum, - Name = "FullTrust")] -[assembly: AssemblyCopyrightAttribute("Zope Public License, Version 2.0 (ZPL)")] -[assembly: AssemblyFileVersionAttribute("2.0.0.2")] -[assembly: NeutralResourcesLanguageAttribute("en")] - -#if (PYTHON23) -[assembly: AssemblyTitleAttribute("Python.Runtime for Python 2.3")] -[assembly: AssemblyDescriptionAttribute("Python Runtime for Python 2.3")] -#endif -#if (PYTHON24) -[assembly: AssemblyTitleAttribute("Python.Runtime for Python 2.4")] -[assembly: AssemblyDescriptionAttribute("Python Runtime for Python 2.4")] -#endif -#if (PYTHON25) -[assembly: AssemblyTitleAttribute("Python.Runtime for Python 2.5")] -[assembly: AssemblyDescriptionAttribute("Python Runtime for Python 2.5")] -#endif -#if (PYTHON26) -[assembly: AssemblyTitleAttribute("Python.Runtime for Python 2.6")] -[assembly: AssemblyDescriptionAttribute("Python Runtime for Python 2.6")] -#endif -#if (PYTHON27) -[assembly: AssemblyTitle("Python.Runtime for Python 2.7")] -[assembly: AssemblyDescription("Python Runtime for Python 2.7")] -#endif diff --git a/Pythonnet.Runtime/assemblymanager.cs b/Pythonnet.Runtime/assemblymanager.cs deleted file mode 100644 index e723ca6590..0000000000 --- a/Pythonnet.Runtime/assemblymanager.cs +++ /dev/null @@ -1,376 +0,0 @@ -// ========================================================================== -// This software is subject to the provisions of the Zope Public License, -// Version 2.0 (ZPL). A copy of the ZPL should accompany this distribution. -// THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED -// WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -// WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS -// FOR A PARTICULAR PURPOSE. -// ========================================================================== - -using System; -using System.IO; -using System.Collections; -using System.Collections.Specialized; -using System.Collections.Generic; -using System.Reflection; -using System.Reflection.Emit; - -namespace Python.Runtime { - - /// - /// The AssemblyManager maintains information about loaded assemblies - /// namespaces and provides an interface for name-based type lookup. - /// - - internal class AssemblyManager { - - static Dictionary> namespaces; - //static Dictionary> generics; - static AssemblyLoadEventHandler lhandler; - static ResolveEventHandler rhandler; - static Dictionary probed; - static List assemblies; - internal static List pypath; - - private AssemblyManager() {} - - //=================================================================== - // Initialization performed on startup of the Python runtime. Here we - // scan all of the currently loaded assemblies to determine exported - // names, and register to be notified of new assembly loads. - //=================================================================== - - internal static void Initialize() { - namespaces = new - Dictionary>(32); - probed = new Dictionary(32); - //generics = new Dictionary>(); - assemblies = new List(16); - pypath = new List(16); - - AppDomain domain = AppDomain.CurrentDomain; - - lhandler = new AssemblyLoadEventHandler(AssemblyLoadHandler); - domain.AssemblyLoad += lhandler; - - rhandler = new ResolveEventHandler(ResolveHandler); - domain.AssemblyResolve += rhandler; - - Assembly[] items = domain.GetAssemblies(); - for (int i = 0; i < items.Length; i++) { - Assembly a = items[i]; - assemblies.Add(a); - ScanAssembly(a); - } - } - - - //=================================================================== - // Cleanup resources upon shutdown of the Python runtime. - //=================================================================== - - internal static void Shutdown() { - AppDomain domain = AppDomain.CurrentDomain; - domain.AssemblyLoad -= lhandler; - domain.AssemblyResolve -= rhandler; - } - - - //=================================================================== - // Event handler for assembly load events. At the time the Python - // runtime loads, we scan the app domain to map the assemblies that - // are loaded at the time. We also have to register this event handler - // so that we can know about assemblies that get loaded after the - // Python runtime is initialized. - //=================================================================== - - static void AssemblyLoadHandler(Object ob, AssemblyLoadEventArgs args){ - Assembly assembly = args.LoadedAssembly; - assemblies.Add(assembly); - ScanAssembly(assembly); - } - - - //=================================================================== - // Event handler for assembly resolve events. This is needed because - // we augment the assembly search path with the PYTHONPATH when we - // load an assembly from Python. Because of that, we need to listen - // for failed loads, because they might be dependencies of something - // we loaded from Python which also needs to be found on PYTHONPATH. - //=================================================================== - - static Assembly ResolveHandler(Object ob, ResolveEventArgs args){ - string name = args.Name.ToLower(); - for (int i = 0; i < assemblies.Count; i++) { - Assembly a = (Assembly)assemblies[i]; - string full = a.FullName.ToLower(); - if (full.StartsWith(name)) { - return a; - } - } - return LoadAssemblyPath(args.Name); - } - - - //=================================================================== - // We __really__ want to avoid using Python objects or APIs when - // probing for assemblies to load, since our ResolveHandler may be - // called in contexts where we don't have the Python GIL and can't - // even safely try to get it without risking a deadlock ;( - // - // To work around that, we update a managed copy of sys.path (which - // is the main thing we care about) when UpdatePath is called. The - // import hook calls this whenever it knows its about to use the - // assembly manager, which lets us keep up with changes to sys.path - // in a relatively lightweight and low-overhead way. - //=================================================================== - - internal static void UpdatePath() { - IntPtr list = Runtime.PySys_GetObject("path"); - int count = Runtime.PyList_Size(list); - if (count != pypath.Count) { - pypath.Clear(); - probed.Clear(); - for (int i = 0; i < count; i++) { - IntPtr item = Runtime.PyList_GetItem(list, i); - string path = Runtime.GetManagedString(item); - if (path != null) { - pypath.Add(path); - } - } - } - } - - - //=================================================================== - // Given an assembly name, try to find this assembly file using the - // PYTHONPATH. If not found, return null to indicate implicit load - // using standard load semantics (app base directory then GAC, etc.) - //=================================================================== - - public static string FindAssembly(string name) { - char sep = Path.DirectorySeparatorChar; - string path; - string temp; - - for (int i = 0; i < pypath.Count; i++) { - string head = pypath[i]; - if (head == null || head.Length == 0) { - path = name; - } - else { - path = head + sep + name; - } - - temp = path + ".dll"; - if (File.Exists(temp)) { - return temp; - } - temp = path + ".exe"; - if (File.Exists(temp)) { - return temp; - } - } - return null; - } - - - //=================================================================== - // Loads an assembly from the application directory or the GAC - // given a simple assembly name. Returns the assembly if loaded. - //=================================================================== - - public static Assembly LoadAssembly(string name) { - Assembly assembly = null; - try { - assembly = Assembly.Load(name); - } - catch { } - return assembly; - } - - - //=================================================================== - // Loads an assembly using an augmented search path (the python path). - //=================================================================== - - public static Assembly LoadAssemblyPath(string name) { - string path = FindAssembly(name); - Assembly assembly = null; - if (path != null) { - try { assembly = Assembly.LoadFrom(path); } - catch {} - } - return assembly; - } - - - //=================================================================== - // Given a qualified name of the form A.B.C.D, attempt to load - // an assembly named after each of A.B.C.D, A.B.C, A.B, A. This - // will only actually probe for the assembly once for each unique - // namespace. Returns true if any assemblies were loaded. - // TODO item 3 "* Deprecate implicit loading of assemblies": - // Set the fromFile flag if the name of the loaded assembly matches - // the fully qualified name that was requested if the framework - // actually loads an assembly. - // Call ONLY for namespaces that HAVE NOT been cached yet. - //=================================================================== - - public static bool LoadImplicit(string name, out bool fromFile) { - // 2010-08-16: Deprecation support - // Added out param to detect fully qualified name load - fromFile = false; - string[] names = name.Split('.'); - bool loaded = false; - string s = ""; - for (int i = 0; i < names.Length; i++) { - s = (i == 0) ? names[0] : s + "." + names[i]; - if (!probed.ContainsKey(s)) { - if (LoadAssemblyPath(s) != null) { - loaded = true; - /* 2010-08-16: Deprecation support */ - if (s == name) { - fromFile = true; - } - } - else if (LoadAssembly(s) != null) { - loaded = true; - /* 2010-08-16: Deprecation support */ - if (s == name) { - fromFile = true; - } - } - probed[s] = 1; - // 2010-12-24: Deprecation logic - /* if (loaded && (s == name)) { - fromFile = true; - break; - } */ - } - } - return loaded; - } - - - //=================================================================== - // Scans an assembly for exported namespaces, adding them to the - // mapping of valid namespaces. Note that for a given namespace - // a.b.c.d, each of a, a.b, a.b.c and a.b.c.d are considered to - // be valid namespaces (to better match Python import semantics). - //=================================================================== - - static void ScanAssembly(Assembly assembly) { - - // A couple of things we want to do here: first, we want to - // gather a list of all of the namespaces contributed to by - // the assembly. - - Type[] types = assembly.GetTypes(); - for (int i = 0; i < types.Length; i++) { - Type t = types[i]; - string ns = t.Namespace; - if ((ns != null) && (!namespaces.ContainsKey(ns))) { - string[] names = ns.Split('.'); - string s = ""; - for (int n = 0; n < names.Length; n++) { - s = (n == 0) ? names[0] : s + "." + names[n]; - if (!namespaces.ContainsKey(s)) { - namespaces.Add(s, - new Dictionary() - ); - } - } - } - - if (ns != null && !namespaces[ns].ContainsKey(assembly)) { - namespaces[ns].Add(assembly, String.Empty); - } - - if (t.IsGenericTypeDefinition) { - GenericUtil.Register(t); - } - } - } - - public static AssemblyName[] ListAssemblies() - { - AssemblyName[] names = new AssemblyName[assemblies.Count]; - Assembly assembly; - for (int i=0; i < assemblies.Count; i++) - { - assembly = assemblies[i]; - names.SetValue(assembly.GetName(), i); - } - return names; - } - - //=================================================================== - // Returns true if the given qualified name matches a namespace - // exported by an assembly loaded in the current app domain. - //=================================================================== - - public static bool IsValidNamespace(string name) { - return namespaces.ContainsKey(name); - } - - - //=================================================================== - // Returns the current list of valid names for the input namespace. - //=================================================================== - - public static List GetNames(string nsname) { - //Dictionary seen = new Dictionary(); - List names = new List(8); - - List g = GenericUtil.GetGenericBaseNames(nsname); - if (g != null) { - foreach (string n in g) { - names.Add(n); - } - } - - if (namespaces.ContainsKey(nsname)) { - foreach (Assembly a in namespaces[nsname].Keys) { - Type[] types = a.GetTypes(); - for (int i = 0; i < types.Length; i++) { - Type t = types[i]; - if (t.Namespace == nsname) { - names.Add(t.Name); - } - } - } - int nslen = nsname.Length; - foreach (string key in namespaces.Keys) { - if (key.Length > nslen && key.StartsWith(nsname)) { - //string tail = key.Substring(nslen); - if (key.IndexOf('.') == -1) { - names.Add(key); - } - } - } - } - return names; - } - - //=================================================================== - // Returns the System.Type object for a given qualified name, - // looking in the currently loaded assemblies for the named - // type. Returns null if the named type cannot be found. - //=================================================================== - - public static Type LookupType(string qname) { - for (int i = 0; i < assemblies.Count; i++) { - Assembly assembly = (Assembly)assemblies[i]; - Type type = assembly.GetType(qname); - if (type != null) { - return type; - } - } - return null; - } - - } - - -} diff --git a/Pythonnet.Runtime/buildclrmodule.bat b/Pythonnet.Runtime/buildclrmodule.bat deleted file mode 100644 index a7a7c7a8fb..0000000000 --- a/Pythonnet.Runtime/buildclrmodule.bat +++ /dev/null @@ -1,36 +0,0 @@ -:: Call with buildclrmodule.bat - -@echo off - -set TARGET_PLATFORM=%1 -set INPUT_DIRECTORY=%~2 -set INPUT_PATH="%INPUT_DIRECTORY%\clrmodule.il" -set OUTPUT_PATH=%3 - -if %TARGET_PLATFORM%==AnyCPU goto SETUP32 -if %TARGET_PLATFORM%==x64 goto SETUP64 -goto ERROR_BAD_PLATFORM - -:SETUP32 -set INCLUDE_PATH="%INPUT_DIRECTORY%\x86" -goto BUILD_CLR_MODULE - -:SETUP64 -set INCLUDE_PATH="%INPUT_DIRECTORY%\x64" -set ILASM_EXTRA_ARGS=/pe64 /x64 -goto BUILD_CLR_MODULE - -:ERROR_BAD_PLATFORM -echo Unknown target platform: %TARGET_PLATFORM% -exit /b 1 - -:ERROR_MISSING_INPUT -echo Can't find input file: %INPUT_PATH% -exit /b 1 - -:BUILD_CLR_MODULE -if not exist %INPUT_PATH% goto ERROR_MISSING_INPUT -%windir%\Microsoft.NET\Framework\v4.0.30319\ilasm /nologo /quiet /dll %ILASM_EXTRA_ARGS% /include=%INCLUDE_PATH% /output=%OUTPUT_PATH% %INPUT_PATH% - -::: 2.0 -:::%windir%\Microsoft.NET\Framework\v2.0.50727\ilasm /nologo /quiet /dll %ILASM_EXTRA_ARGS% /include=%INCLUDE_PATH% /output=%OUTPUT_PATH% %INPUT_PATH% diff --git a/Pythonnet.Runtime/classbase.cs b/Pythonnet.Runtime/classbase.cs deleted file mode 100644 index 1541b12cd2..0000000000 --- a/Pythonnet.Runtime/classbase.cs +++ /dev/null @@ -1,170 +0,0 @@ -// ========================================================================== -// This software is subject to the provisions of the Zope Public License, -// Version 2.0 (ZPL). A copy of the ZPL should accompany this distribution. -// THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED -// WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -// WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS -// FOR A PARTICULAR PURPOSE. -// ========================================================================== - -using System; -using System.Collections; -using System.Reflection; -using System.Security; -using System.Runtime.InteropServices; - -namespace Python.Runtime { - - /// - /// Base class for Python types that reflect managed types / classes. - /// Concrete subclasses include ClassObject and DelegateObject. This - /// class provides common attributes and common machinery for doing - /// class initialization (initialization of the class __dict__). The - /// concrete subclasses provide slot implementations appropriate for - /// each variety of reflected type. - /// - - internal class ClassBase : ManagedType { - - internal Indexer indexer; - internal Type type; - - internal ClassBase(Type tp) : base() { - indexer = null; - type = tp; - } - - internal virtual bool CanSubclass() { - return (!this.type.IsEnum); - } - - //==================================================================== - // Implements __init__ for reflected classes and value types. - //==================================================================== - - public static int tp_init(IntPtr ob, IntPtr args, IntPtr kw) { - return 0; - } - - //==================================================================== - // Default implementation of [] semantics for reflected types. - //==================================================================== - - public virtual IntPtr type_subscript(IntPtr idx) { - return Exceptions.RaiseTypeError("unsubscriptable object"); - } - - //==================================================================== - // Standard comparison implementation for instances of reflected types. - //==================================================================== - - public static int tp_compare(IntPtr ob, IntPtr other) { - if (ob == other) { - return 0; - } - - CLRObject co1 = GetManagedObject(ob) as CLRObject; - CLRObject co2 = GetManagedObject(other) as CLRObject; - Object o1 = co1.inst; - Object o2 = co2.inst; - - if (Object.Equals(o1, o2)) { - return 0; - } - return -1; - } - - - //==================================================================== - // Standard iteration support for instances of reflected types. This - // allows natural iteration over objects that either are IEnumerable - // or themselves support IEnumerator directly. - //==================================================================== - - public static IntPtr tp_iter(IntPtr ob) { - CLRObject co = GetManagedObject(ob) as CLRObject; - if (co == null) { - return Exceptions.RaiseTypeError("invalid object"); - } - - IEnumerable e = co.inst as IEnumerable; - IEnumerator o; - - if (e != null) { - o = e.GetEnumerator(); - } - else { - o = co.inst as IEnumerator; - - if (o == null) { - string message = "iteration over non-sequence"; - return Exceptions.RaiseTypeError(message); - } - } - - return new Iterator(o).pyHandle; - } - - - //==================================================================== - // Standard __hash__ implementation for instances of reflected types. - //==================================================================== - - public static IntPtr tp_hash(IntPtr ob) { - CLRObject co = GetManagedObject(ob) as CLRObject; - if (co == null) { - return Exceptions.RaiseTypeError("unhashable type"); - } - return new IntPtr(co.inst.GetHashCode()); - } - - - //==================================================================== - // Standard __str__ implementation for instances of reflected types. - //==================================================================== - - public static IntPtr tp_str(IntPtr ob) { - CLRObject co = GetManagedObject(ob) as CLRObject; - if (co == null) { - return Exceptions.RaiseTypeError("invalid object"); - } - return Runtime.PyString_FromString(co.inst.ToString()); - } - - - //==================================================================== - // Default implementations for required Python GC support. - //==================================================================== - - public static int tp_traverse(IntPtr ob, IntPtr func, IntPtr args) { - return 0; - } - - public static int tp_clear(IntPtr ob) { - return 0; - } - - public static int tp_is_gc(IntPtr type) { - return 1; - } - - //==================================================================== - // Standard dealloc implementation for instances of reflected types. - //==================================================================== - - public static void tp_dealloc(IntPtr ob) { - ManagedType self = GetManagedObject(ob); - IntPtr dict = Marshal.ReadIntPtr(ob, ObjectOffset.ob_dict); - if (dict != IntPtr.Zero) { - Runtime.Decref(dict); - } - Runtime.PyObject_GC_UnTrack(self.pyHandle); - Runtime.PyObject_GC_Del(self.pyHandle); - Runtime.Decref(self.tpHandle); - self.gcHandle.Free(); - } - - - } - -} diff --git a/Pythonnet.Runtime/classmanager.cs b/Pythonnet.Runtime/classmanager.cs deleted file mode 100644 index 088905b380..0000000000 --- a/Pythonnet.Runtime/classmanager.cs +++ /dev/null @@ -1,368 +0,0 @@ -// ========================================================================== -// This software is subject to the provisions of the Zope Public License, -// Version 2.0 (ZPL). A copy of the ZPL should accompany this distribution. -// THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED -// WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -// WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS -// FOR A PARTICULAR PURPOSE. -// ========================================================================== - -using System; -using System.Runtime.InteropServices; -using System.Collections.Generic; -using System.Collections; -using System.Reflection; -using System.Security; - -namespace Python.Runtime { - - /// - /// The ClassManager is responsible for creating and managing instances - /// that implement the Python type objects that reflect managed classes. - /// - /// Each managed type reflected to Python is represented by an instance - /// of a concrete subclass of ClassBase. Each instance is associated with - /// a generated Python type object, whose slots point to static methods - /// of the managed instance's class. - /// - - internal class ClassManager { - - static Dictionary cache; - static Type dtype; - - private ClassManager() {} - - static ClassManager() { - cache = new Dictionary(128); - // SEE: http://msdn.microsoft.com/en-us/library/96b1ayy4%28VS.90%29.aspx - // ""All delegates inherit from MulticastDelegate, which inherits from Delegate."" - // Was Delegate, which caused a null MethodInfo returned from GetMethode("Invoke") - // and crashed on Linux under Mono. - dtype = typeof(System.MulticastDelegate); - } - - //==================================================================== - // Return the ClassBase-derived instance that implements a particular - // reflected managed type, creating it if it doesn't yet exist. - //==================================================================== - - internal static ClassBase GetClass(Type type) { - ClassBase cb = null; - cache.TryGetValue(type, out cb); - if (cb != null) { - return cb; - } - cb = CreateClass(type); - cache.Add(type, cb); - return cb; - } - - - //==================================================================== - // Create a new ClassBase-derived instance that implements a reflected - // managed type. The new object will be associated with a generated - // Python type object. - //==================================================================== - - private static ClassBase CreateClass(Type type) { - - // First, we introspect the managed type and build some class - // information, including generating the member descriptors - // that we'll be putting in the Python class __dict__. - - ClassInfo info = GetClassInfo(type); - - // Next, select the appropriate managed implementation class. - // Different kinds of types, such as array types or interface - // types, want to vary certain implementation details to make - // sure that the type semantics are consistent in Python. - - ClassBase impl; - - // Check to see if the given type extends System.Exception. This - // lets us check once (vs. on every lookup) in case we need to - // wrap Exception-derived types in old-style classes - - if (type.ContainsGenericParameters) { - impl = new GenericType(type); - } - - else if (type.IsSubclassOf(dtype)) { - impl = new DelegateObject(type); - } - - else if (type.IsArray) { - impl = new ArrayObject(type); - } - - else if (type.IsInterface) { - impl = new InterfaceObject(type); - } - - else if (type == typeof(Exception) || - type.IsSubclassOf(typeof(Exception))) { - impl = new ExceptionClassObject(type); - } - - else { - impl = new ClassObject(type); - } - - impl.indexer = info.indexer; - - // Now we allocate the Python type object to reflect the given - // managed type, filling the Python type slots with thunks that - // point to the managed methods providing the implementation. - - - IntPtr tp = TypeManager.GetTypeHandle(impl, type); - impl.tpHandle = tp; - - // Finally, initialize the class __dict__ and return the object. - IntPtr dict = Marshal.ReadIntPtr(tp, TypeOffset.tp_dict); - - - IDictionaryEnumerator iter = info.members.GetEnumerator(); - while(iter.MoveNext()) { - ManagedType item = (ManagedType)iter.Value; - string name = (string)iter.Key; - Runtime.PyDict_SetItemString(dict, name, item.pyHandle); - } - - // If class has constructors, generate an __doc__ attribute. - - IntPtr doc; - Type marker = typeof(DocStringAttribute); - Attribute[] attrs = (Attribute[])type.GetCustomAttributes(marker, false); - if (attrs.Length == 0) { - doc = IntPtr.Zero; - } - else { - DocStringAttribute attr = (DocStringAttribute)attrs[0]; - string docStr = attr.DocString; - doc = Runtime.PyString_FromString(docStr); - Runtime.PyDict_SetItemString(dict, "__doc__", doc); - Runtime.Decref(doc); - } - - ClassObject co = impl as ClassObject; - // If this is a ClassObject AND it has constructors, generate a __doc__ attribute. - // required that the ClassObject.ctors be changed to internal - if (co != null) { - if (co.ctors.Length > 0) { - // Implement Overloads on the class object - ConstructorBinding ctors = new ConstructorBinding(type, tp, co.binder); - // ExtensionType types are untracked, so don't Incref() them. - // XXX deprecate __overloads__ soon... - Runtime.PyDict_SetItemString(dict, "__overloads__", ctors.pyHandle); - Runtime.PyDict_SetItemString(dict, "Overloads", ctors.pyHandle); - - if (doc == IntPtr.Zero) { - doc = co.GetDocString(); - Runtime.PyDict_SetItemString(dict, "__doc__", doc); - Runtime.Decref(doc); - } - } - } - - return impl; - } - - - - - private static ClassInfo GetClassInfo(Type type) { - ClassInfo ci = new ClassInfo(type); - Hashtable methods = new Hashtable(); - ArrayList list; - MethodInfo meth; - ManagedType ob; - String name; - Object item; - Type tp; - int i, n; - - // This is complicated because inheritance in Python is name - // based. We can't just find DeclaredOnly members, because we - // could have a base class A that defines two overloads of a - // method and a class B that defines two more. The name-based - // descriptor Python will find needs to know about inherited - // overloads as well as those declared on the sub class. - - BindingFlags flags = BindingFlags.Static | - BindingFlags.Instance | - BindingFlags.Public | - BindingFlags.NonPublic; - - MemberInfo[] info = type.GetMembers(flags); - Hashtable local = new Hashtable(); - ArrayList items = new ArrayList(); - MemberInfo m; - - // Loop through once to find out which names are declared - for (i = 0; i < info.Length; i++) { - m = info[i]; - if (m.DeclaringType == type) { - local[m.Name] = 1; - } - } - - // Now again to filter w/o losing overloaded member info - for (i = 0; i < info.Length; i++) { - m = info[i]; - if (local[m.Name] != null) { - items.Add(m); - } - } - - if (type.IsInterface) { - // Interface inheritance seems to be a different animal: - // more contractual, less structural. Thus, a Type that - // represents an interface that inherits from another - // interface does not return the inherited interface's - // methods in GetMembers. For example ICollection inherits - // from IEnumerable, but ICollection's GetMemebers does not - // return GetEnumerator. - // - // Not sure if this is the correct way to fix this, but it - // seems to work. Thanks to Bruce Dodson for the fix. - - Type[] inheritedInterfaces = type.GetInterfaces(); - - for (i = 0; i < inheritedInterfaces.Length; ++i) { - Type inheritedType = inheritedInterfaces[i]; - MemberInfo[] imembers = inheritedType.GetMembers(flags); - for (n = 0; n < imembers.Length; n++) { - m = imembers[n]; - if (local[m.Name] == null) { - items.Add(m); - } - } - } - } - - for (i = 0; i < items.Count; i++) { - - MemberInfo mi = (MemberInfo)items[i]; - - switch(mi.MemberType) { - - case MemberTypes.Method: - meth = (MethodInfo) mi; - if (!(meth.IsPublic || meth.IsFamily || - meth.IsFamilyOrAssembly)) - continue; - name = meth.Name; - item = methods[name]; - if (item == null) { - item = methods[name] = new ArrayList(); - } - list = (ArrayList) item; - list.Add(meth); - continue; - - case MemberTypes.Property: - PropertyInfo pi = (PropertyInfo) mi; - - MethodInfo mm = null; - try { - mm = pi.GetGetMethod(true); - if (mm == null) { - mm = pi.GetSetMethod(true); - } - } - catch (SecurityException) { - // GetGetMethod may try to get a method protected by - // StrongNameIdentityPermission - effectively private. - continue; - } - - if (mm == null) { - continue; - } - - if (!(mm.IsPublic || mm.IsFamily || mm.IsFamilyOrAssembly)) - continue; - - // Check for indexer - ParameterInfo[] args = pi.GetIndexParameters(); - if (args.GetLength(0) > 0) { - Indexer idx = ci.indexer; - if (idx == null) { - ci.indexer = new Indexer(); - idx = ci.indexer; - } - idx.AddProperty(pi); - continue; - } - - ob = new PropertyObject(pi); - ci.members[pi.Name] = ob; - continue; - - case MemberTypes.Field: - FieldInfo fi = (FieldInfo) mi; - if (!(fi.IsPublic || fi.IsFamily || fi.IsFamilyOrAssembly)) - continue; - ob = new FieldObject(fi); - ci.members[mi.Name] = ob; - continue; - - case MemberTypes.Event: - EventInfo ei = (EventInfo)mi; - MethodInfo me = ei.GetAddMethod(true); - if (!(me.IsPublic || me.IsFamily || me.IsFamilyOrAssembly)) - continue; - ob = new EventObject(ei); - ci.members[ei.Name] = ob; - continue; - - case MemberTypes.NestedType: - tp = (Type) mi; - if (!(tp.IsNestedPublic || tp.IsNestedFamily || - tp.IsNestedFamORAssem)) - continue; - ob = ClassManager.GetClass(tp); - ci.members[mi.Name] = ob; - continue; - - } - } - - IDictionaryEnumerator iter = methods.GetEnumerator(); - - while(iter.MoveNext()) { - name = (string) iter.Key; - list = (ArrayList) iter.Value; - - MethodInfo[] mlist = (MethodInfo[])list.ToArray( - typeof(MethodInfo) - ); - - ob = new MethodObject(name, mlist); - ci.members[name] = ob; - } - - return ci; - - } - - - } - - - internal class ClassInfo { - - internal ClassInfo(Type t) { - members = new Hashtable(); - indexer = null; - } - - public Hashtable members; - public Indexer indexer; - } - - - -} diff --git a/Pythonnet.Runtime/classobject.cs b/Pythonnet.Runtime/classobject.cs deleted file mode 100644 index c331637be0..0000000000 --- a/Pythonnet.Runtime/classobject.cs +++ /dev/null @@ -1,299 +0,0 @@ -// ========================================================================== -// This software is subject to the provisions of the Zope Public License, -// Version 2.0 (ZPL). A copy of the ZPL should accompany this distribution. -// THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED -// WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -// WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS -// FOR A PARTICULAR PURPOSE. -// ========================================================================== - -using System; -using System.Reflection; - -namespace Python.Runtime { - - /// - /// Managed class that provides the implementation for reflected types. - /// Managed classes and value types are represented in Python by actual - /// Python type objects. Each of those type objects is associated with - /// an instance of ClassObject, which provides its implementation. - /// - - internal class ClassObject : ClassBase { - - internal ConstructorBinder binder; - internal ConstructorInfo[] ctors; - - internal ClassObject(Type tp) : base(tp) { - ctors = type.GetConstructors(); - binder = new ConstructorBinder(); - - for (int i = 0; i < ctors.Length; i++) { - binder.AddMethod(ctors[i]); - } - } - - - //==================================================================== - // Helper to get docstring from reflected constructor info. - //==================================================================== - - internal IntPtr GetDocString() { - MethodBase[] methods = binder.GetMethods(); - string str = ""; - for (int i = 0; i < methods.Length; i++) { - if (str.Length > 0) - str += Environment.NewLine; - str += methods[i].ToString(); - } - return Runtime.PyString_FromString(str); - } - - - //==================================================================== - // Implements __new__ for reflected classes and value types. - //==================================================================== - - public static IntPtr tp_new(IntPtr tp, IntPtr args, IntPtr kw) { - - ClassObject self = GetManagedObject(tp) as ClassObject; - - // Sanity check: this ensures a graceful error if someone does - // something intentially wrong like use the managed metatype for - // a class that is not really derived from a managed class. - - if (self == null) { - return Exceptions.RaiseTypeError("invalid object"); - } - - Type type = self.type; - - // Primitive types do not have constructors, but they look like - // they do from Python. If the ClassObject represents one of the - // convertible primitive types, just convert the arg directly. - - if (type.IsPrimitive || type == typeof(String)) { - if (Runtime.PyTuple_Size(args) != 1) { - Exceptions.SetError(Exceptions.TypeError, - "no constructors match given arguments" - ); - return IntPtr.Zero; - } - - IntPtr op = Runtime.PyTuple_GetItem(args, 0); - Object result; - - if (!Converter.ToManaged(op, type, out result, true)) { - return IntPtr.Zero; - } - - return CLRObject.GetInstHandle(result, tp); - } - - if (type.IsAbstract) { - Exceptions.SetError(Exceptions.TypeError, - "cannot instantiate abstract class" - ); - return IntPtr.Zero; - } - - if (type.IsEnum) { - Exceptions.SetError(Exceptions.TypeError, - "cannot instantiate enumeration" - ); - return IntPtr.Zero; - } - - Object obj = self.binder.InvokeRaw(IntPtr.Zero, args, kw); - if (obj == null) { - return IntPtr.Zero; - } - - return CLRObject.GetInstHandle(obj, tp); - } - - - //==================================================================== - // Implementation of [] semantics for reflected types. This exists - // both to implement the Array[int] syntax for creating arrays and - // to support generic name overload resolution using []. - //==================================================================== - - public override IntPtr type_subscript(IntPtr idx) { - - // If this type is the Array type, the [] means we need to - // construct and return an array type of the given element type. - - if ((this.type) == typeof(Array)) { - if (Runtime.PyTuple_Check(idx)) { - return Exceptions.RaiseTypeError("type expected"); - } - ClassBase c = GetManagedObject(idx) as ClassBase; - Type t = (c != null) ? c.type : Converter.GetTypeByAlias(idx); - if (t == null) { - return Exceptions.RaiseTypeError("type expected"); - } - Type a = t.MakeArrayType(); - ClassBase o = ClassManager.GetClass(a); - Runtime.Incref(o.pyHandle); - return o.pyHandle; - } - - // If there are generics in our namespace with the same base name - // as the current type, then [] means the caller wants to - // bind the generic type matching the given type parameters. - - Type[] types = Runtime.PythonArgsToTypeArray(idx); - if (types == null) { - return Exceptions.RaiseTypeError("type(s) expected"); - } - - string gname = this.type.FullName + "`" + types.Length.ToString(); - Type gtype = AssemblyManager.LookupType(gname); - if (gtype != null) { - GenericType g = ClassManager.GetClass(gtype) as GenericType; - return g.type_subscript(idx); - /*Runtime.Incref(g.pyHandle); - return g.pyHandle;*/ - } - return Exceptions.RaiseTypeError("unsubscriptable object"); - } - - - //==================================================================== - // Implements __getitem__ for reflected classes and value types. - //==================================================================== - - public static IntPtr mp_subscript(IntPtr ob, IntPtr idx) { - //ManagedType self = GetManagedObject(ob); - IntPtr tp = Runtime.PyObject_TYPE(ob); - ClassBase cls = (ClassBase)GetManagedObject(tp); - - if (cls.indexer == null || !cls.indexer.CanGet) { - Exceptions.SetError(Exceptions.TypeError, - "unindexable object" - ); - return IntPtr.Zero; - } - - // Arg may be a tuple in the case of an indexer with multiple - // parameters. If so, use it directly, else make a new tuple - // with the index arg (method binders expect arg tuples). - - IntPtr args = idx; - bool free = false; - - if (!Runtime.PyTuple_Check(idx)) { - args = Runtime.PyTuple_New(1); - Runtime.Incref(idx); - Runtime.PyTuple_SetItem(args, 0, idx); - free = true; - } - - IntPtr value = IntPtr.Zero; - - try { - value = cls.indexer.GetItem(ob, args); - } - finally { - if (free) { - Runtime.Decref(args); - } - } - return value; - } - - - //==================================================================== - // Implements __setitem__ for reflected classes and value types. - //==================================================================== - - public static int mp_ass_subscript(IntPtr ob, IntPtr idx, IntPtr v) { - //ManagedType self = GetManagedObject(ob); - IntPtr tp = Runtime.PyObject_TYPE(ob); - ClassBase cls = (ClassBase)GetManagedObject(tp); - - if (cls.indexer == null || !cls.indexer.CanSet) { - Exceptions.SetError(Exceptions.TypeError, - "object doesn't support item assignment" - ); - return -1; - } - - // Arg may be a tuple in the case of an indexer with multiple - // parameters. If so, use it directly, else make a new tuple - // with the index arg (method binders expect arg tuples). - - IntPtr args = idx; - bool free = false; - - if (!Runtime.PyTuple_Check(idx)) { - args = Runtime.PyTuple_New(1); - Runtime.Incref(idx); - Runtime.PyTuple_SetItem(args, 0, idx); - free = true; - } - - int i = Runtime.PyTuple_Size(args); - IntPtr real = Runtime.PyTuple_New(i + 1); - for (int n = 0; n < i; n++) { - IntPtr item = Runtime.PyTuple_GetItem(args, n); - Runtime.Incref(item); - Runtime.PyTuple_SetItem(real, n, item); - } - Runtime.Incref(v); - Runtime.PyTuple_SetItem(real, i, v); - - try { - cls.indexer.SetItem(ob, real); - } - finally { - Runtime.Decref(real); - - if (free) { - Runtime.Decref(args); - } - } - - if (Exceptions.ErrorOccurred()) { - return -1; - } - - return 0; - } - - - //==================================================================== - // This is a hack. Generally, no managed class is considered callable - // from Python - with the exception of System.Delegate. It is useful - // to be able to call a System.Delegate instance directly, especially - // when working with multicast delegates. - //==================================================================== - - public static IntPtr tp_call(IntPtr ob, IntPtr args, IntPtr kw) { - //ManagedType self = GetManagedObject(ob); - IntPtr tp = Runtime.PyObject_TYPE(ob); - ClassBase cb = (ClassBase)GetManagedObject(tp); - - if (cb.type != typeof(System.Delegate)) { - Exceptions.SetError(Exceptions.TypeError, - "object is not callable"); - return IntPtr.Zero; - } - - CLRObject co = (CLRObject)ManagedType.GetManagedObject(ob); - Delegate d = co.inst as Delegate; - BindingFlags flags = BindingFlags.Public | - BindingFlags.NonPublic | - BindingFlags.Instance | - BindingFlags.Static; - - MethodInfo method = d.GetType().GetMethod("Invoke", flags); - MethodBinder binder = new MethodBinder(method); - return binder.Invoke(ob, args, kw); - } - - - } - -} diff --git a/Pythonnet.Runtime/clrmodule.il b/Pythonnet.Runtime/clrmodule.il deleted file mode 100644 index be57f06549..0000000000 --- a/Pythonnet.Runtime/clrmodule.il +++ /dev/null @@ -1,278 +0,0 @@ -// ========================================================================== -// This software is subject to the provisions of the Zope Public License, -// Version 2.0 (ZPL). A copy of the ZPL should accompany this distribution. -// THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED -// WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -// WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS -// FOR A PARTICULAR PURPOSE. -// ========================================================================== - -//============================================================================ -// This file is a hand-maintained stub - it implements clr.dll, which can be -// loaded by a standard CPython interpreter as an extension module. When it -// is loaded, it bootstraps the managed runtime integration layer and defers -// to it to do initialization and put the clr module into sys.modules, etc. - -// The "USE_PYTHON_RUNTIME_*" defines control what extra evidence is used -// to help the CLR find the appropriate Python.Runtime assembly. - -// If defined, the "pythonRuntimeVersionString" variable must be set to -// Python.Runtime's current version. -#define USE_PYTHON_RUNTIME_VERSION - -// If defined, the "PythonRuntimePublicKeyTokenData" data array must be -// set to Python.Runtime's public key token. -//#define USE_PYTHON_RUNTIME_PUBLIC_KEY_TOKEN - -// If DEBUG_PRINT is defined, a few System.Console.WriteLine calls are made -// to indicate what's going on during the load... -//#define DEBUG_PRINT -//============================================================================ - -.assembly extern mscorlib -{ - .publickeytoken = (B7 7A 5C 56 19 34 E0 89 ) - .ver 4:0:0:0 -} - -.assembly clr -{ - .hash algorithm 0x00008004 - .ver 2:4:2:7 -} - -.module clr.dll -.imagebase 0x00400000 -.subsystem 0x00000003 -.file alignment 512 - -// This includes the platform-specific IL. The include search path -// is set depending on whether we're compiling 32 or 64 bit. -// This MUST come before any other .data directives! -// Why, oh why, can't ilasm support command line #defines? :( -#include "clrmodule-platform.il" - -#ifdef USE_PYTHON_RUNTIME_PUBLIC_KEY_TOKEN -.data PythonRuntimePublicKeyTokenData = bytearray (64 e1 4e 84 5a bf 2e 60) -#endif - -.class public auto ansi beforefieldinit clrModule extends [mscorlib]System.Object -{ -#ifdef USE_PYTHON_RUNTIME_PUBLIC_KEY_TOKEN - .field static assembly int64 PythonRuntimePublicKeyToken at PythonRuntimePublicKeyTokenData -#endif - - .method public hidebysig specialname rtspecialname instance void - .ctor() cil managed - { - .maxstack 1 - ldarg.0 - call instance void [mscorlib]System.Object::.ctor() - ret - } - - .method public hidebysig static void modopt([mscorlib]System.Runtime.CompilerServices.CallConvCdecl) - initclr() cil managed - { - .vtentry 1:1 - .export [1] as initclr - - .maxstack 6 - .locals init ( - class [mscorlib]System.Reflection.Assembly pythonRuntime, - class [mscorlib]System.Reflection.Assembly executingAssembly, - class [mscorlib]System.Reflection.AssemblyName pythonRuntimeName, - class [mscorlib]System.Type pythonEngineType, - int8[] publicKeyToken, - string assemblyDirectory, - string pythonRuntimeVersionString, - string pythonRuntimeDllPath) - - // pythonRuntime = null; - ldnull - stloc pythonRuntime - - .try - { -#ifdef DEBUG_PRINT - ldstr "Attempting to load Python.Runtime using standard binding rules... " - call void [mscorlib]System.Console::Write(string) -#endif - - // Attempt to find and load Python.Runtime using standard assembly binding rules. - // This roughly translates into looking in order: - // - GAC - // - ApplicationBase - // - A PrivateBinPath under ApplicationBase - // With an unsigned assembly, the GAC is skipped. - - // System.Reflection.AssemblyName pythonRuntimeName = new System.Reflection.AssemblyName(); - newobj instance void [mscorlib]System.Reflection.AssemblyName::.ctor() - stloc pythonRuntimeName - - // pythonRuntimeName.Name = "Python.Runtime"; - ldloc pythonRuntimeName - ldstr "Python.Runtime" - callvirt instance void [mscorlib]System.Reflection.AssemblyName::set_Name(string) - -#ifdef USE_PYTHON_RUNTIME_VERSION - // pythonRuntimeVersionString = "..."; - ldstr "2.0.0.2" - stloc pythonRuntimeVersionString - - // pythonRuntimeName.Version = new Version(pythonRuntimeVersionString); - ldloc pythonRuntimeName - ldloc pythonRuntimeVersionString - newobj instance void [mscorlib]System.Version::.ctor(string) - callvirt instance void [mscorlib]System.Reflection.AssemblyName::set_Version(class [mscorlib]System.Version) -#endif - -#ifdef USE_PYTHON_RUNTIME_PUBLIC_KEY_TOKEN - // publicKeyToken = new byte[] { ... }; - ldc.i4.8 - newarr [mscorlib]System.Byte - dup - ldtoken field int64 clrModule::PythonRuntimePublicKeyToken - call void [mscorlib]System.Runtime.CompilerServices.RuntimeHelpers::InitializeArray(class [mscorlib]System.Array, valuetype [mscorlib]System.RuntimeFieldHandle) - stloc publicKeyToken - - // pythonRuntimeName.SetPublicKeyToken(publicKeyToken); - ldloc pythonRuntimeName - ldloc publicKeyToken - callvirt instance void [mscorlib]System.Reflection.AssemblyName::SetPublicKeyToken(uint8[]) -#endif - - // pythonRuntimeName.CultureInfo = System.Globalization.CultureInfo.InvariantCulture; - ldloc pythonRuntimeName - call class [mscorlib]System.Globalization.CultureInfo [mscorlib]System.Globalization.CultureInfo::get_InvariantCulture() - callvirt instance void [mscorlib]System.Reflection.AssemblyName::set_CultureInfo(class [mscorlib]System.Globalization.CultureInfo) - - // return System.Reflection.Assembly.Load(pythonRuntimeName); - ldloc pythonRuntimeName - call class [mscorlib]System.Reflection.Assembly [mscorlib]System.Reflection.Assembly::Load(class [mscorlib]System.Reflection.AssemblyName) - stloc pythonRuntime - -#ifdef DEBUG_PRINT - ldstr "Success!" - call void [mscorlib]System.Console::WriteLine(string) -#endif - leave.s LOADED_PYTHON_RUNTIME - } - catch [mscorlib]System.Object - { -#ifdef DEBUG_PRINT - ldstr "Failed." - call void [mscorlib]System.Console::WriteLine(string) -#endif - leave.s EXIT_CLR_LOAD - } - EXIT_CLR_LOAD: nop - - .try - { - // If the above fails for any reason, we fallback to attempting to load "Python.Runtime.dll" - // from the directory this assembly is running in. "This assembly" is probably "clr.pyd", - // sitting somewhere in PYTHONPATH. This is using Assembly.LoadFrom, and inherits all the - // caveats of that call. See MSDN docs for details. - // Suzanne Cook's blog is also an excellent source of info on this: - // http://blogs.msdn.com/suzcook/ - // http://blogs.msdn.com/suzcook/archive/2003/05/29/57143.aspx - // http://blogs.msdn.com/suzcook/archive/2003/06/13/57180.aspx - // executingAssembly = System.Reflection.Assembly.GetExecutingAssembly(); - call class [mscorlib]System.Reflection.Assembly [mscorlib]System.Reflection.Assembly::GetExecutingAssembly() - stloc executingAssembly - - // assemblyDirectory = System.IO.Path.GetDirectoryName(executingAssembly.Location); - ldloc executingAssembly - callvirt instance string [mscorlib]System.Reflection.Assembly::get_Location() - call string [mscorlib]System.IO.Path::GetDirectoryName(string) - stloc assemblyDirectory - - // pythonRuntimeDllPath = System.IO.Path.Combine(assemblyDirectory, "Python.Runtime.dll"); - ldloc assemblyDirectory - ldstr "Python.Runtime.dll" - call string [mscorlib]System.IO.Path::Combine(string, string) - stloc pythonRuntimeDllPath - -#ifdef DEBUG_PRINT - ldstr "Attempting to load Python.Runtime from: '{0}'... " - ldloc pythonRuntimeDllPath - call void [mscorlib]System.Console::Write(string, object) -#endif - - // pythonRuntime = System.Reflection.Assembly.LoadFrom(pythonRuntimeDllPath); - ldloc pythonRuntimeDllPath - call class [mscorlib]System.Reflection.Assembly [mscorlib]System.Reflection.Assembly::LoadFrom(string) - stloc pythonRuntime - -#ifdef DEBUG_PRINT - ldstr "Success!" - call void [mscorlib]System.Console::WriteLine(string) - - ldloc pythonRuntime - callvirt instance string [mscorlib]System.Reflection.Assembly::get_CodeBase() - call void [mscorlib]System.Console::WriteLine(string) -#endif - leave.s LOADED_PYTHON_RUNTIME - } - catch [mscorlib]System.Object - { -#ifdef DEBUG_PRINT - ldstr "Failed." - call void [mscorlib]System.Console::WriteLine(string) -#endif - leave.s EXIT_PYTHONPATH_LOAD - } - EXIT_PYTHONPATH_LOAD: nop - - // If we get here, we haven't loaded Python.Runtime, so bail. -#ifdef DEBUG_PRINT - ldstr "Could not load Python.Runtime, so sad." - call void [mscorlib]System.Console::WriteLine(string) -#endif - ret; - - // Once here, we've successfully loaded SOME version of Python.Runtime - // So now we get the PythonEngine and execute the InitExt method on it. - LOADED_PYTHON_RUNTIME: nop - .try - { -#ifdef DEBUG_PRINT - ldstr "Running Python.Runtime.PythonEngine.InitExt()" - call void [mscorlib]System.Console::WriteLine(string) -#endif - // pythonEngineType = pythonRuntime.GetType("Python.Runtime.PythonEngine"); - ldloc pythonRuntime - ldstr "Python.Runtime.PythonEngine" - callvirt instance class [mscorlib]System.Type [mscorlib]System.Reflection.Assembly::GetType(string) - stloc pythonEngineType - - // pythonEngineType.InvokeMember("InitExt", System.Reflection.BindingFlags.InvokeMethod, null, null, null); - ldloc pythonEngineType - ldstr "InitExt" - ldc.i4 0x100 - ldnull - ldnull - ldnull - callvirt instance object [mscorlib]System.Type::InvokeMember( string, - valuetype [mscorlib]System.Reflection.BindingFlags, - class [mscorlib]System.Reflection.Binder, - object, - object[]) - pop - leave.s EXIT_TRY_INVOKE - } - catch [mscorlib]System.Object - { -#ifdef DEBUG_PRINT - ldstr "Error calling Python.Runtime.PythonEngine.InitExt()." - call void [mscorlib]System.Console::WriteLine(string) -#endif - leave.s EXIT_TRY_INVOKE - } - EXIT_TRY_INVOKE: nop - - ret - } -} - diff --git a/Pythonnet.Runtime/clrmodule.pp.il b/Pythonnet.Runtime/clrmodule.pp.il deleted file mode 100644 index 59b2893793..0000000000 --- a/Pythonnet.Runtime/clrmodule.pp.il +++ /dev/null @@ -1,279 +0,0 @@ -// ========================================================================== -// This software is subject to the provisions of the Zope Public License, -// Version 2.0 (ZPL). A copy of the ZPL should accompany this distribution. -// THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED -// WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -// WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS -// FOR A PARTICULAR PURPOSE. -// ========================================================================== - -//============================================================================ -// This file is a hand-maintained stub - it implements clr.dll, which can be -// loaded by a standard CPython interpreter as an extension module. When it -// is loaded, it bootstraps the managed runtime integration layer and defers -// to it to do initialization and put the clr module into sys.modules, etc. - -// The "USE_PYTHON_RUNTIME_*" defines control what extra evidence is used -// to help the CLR find the appropriate Python.Runtime assembly. - -// If defined, the "pythonRuntimeVersionString" variable must be set to -// Python.Runtime's current version. -#define USE_PYTHON_RUNTIME_VERSION - -// If defined, the "PythonRuntimePublicKeyTokenData" data array must be -// set to Python.Runtime's public key token. -//#define USE_PYTHON_RUNTIME_PUBLIC_KEY_TOKEN - -// If DEBUG_PRINT is defined, a few System.Console.WriteLine calls are made -// to indicate what's going on during the load... -//#define DEBUG_PRINT -//============================================================================ - -.assembly extern mscorlib -{ - .publickeytoken = (B7 7A 5C 56 19 34 E0 89 ) - .ver 2:0:0:0 -} - -.assembly clr -{ - .hash algorithm 0x00008004 - .ver 2:0:0:2 -} - -.module clr.dll -.imagebase 0x00400000 -.subsystem 0x00000003 -.file alignment 512 - -// This includes the platform-specific IL. The include search path -// is set depending on whether we're compiling 32 or 64 bit. -// This MUST come before any other .data directives! -// Why, oh why, can't ilasm support command line #defines? :( - -// Contributed by VIKAS DHIMAN - Handled by /home/barton/Projects/PyDotNet/pythonnet/makefile -// gcc -C -P -x c++ -I $(ARCH) clrmodule.pp.il -o clrmodule.il -// to copy the correct architecture to the clrModule. -// Nice formating, as well - Thanks, Vikas! -#include "clrmodule-platform.il" - -#ifdef USE_PYTHON_RUNTIME_PUBLIC_KEY_TOKEN -.data PythonRuntimePublicKeyTokenData = bytearray (64 e1 4e 84 5a bf 2e 60) -#endif - -.class public auto ansi beforefieldinit clrModule extends [mscorlib]System.Object -{ -#ifdef USE_PYTHON_RUNTIME_PUBLIC_KEY_TOKEN - .field static assembly int64 PythonRuntimePublicKeyToken at PythonRuntimePublicKeyTokenData -#endif - - .method public hidebysig specialname rtspecialname instance void - .ctor() cil managed - { - .maxstack 1 - ldarg.0 - call instance void [mscorlib]System.Object::.ctor() - ret - } - - .method public hidebysig static void modopt([mscorlib]System.Runtime.CompilerServices.CallConvCdecl) - initclr() cil managed - { - .vtentry 1:1 - .export [1] as initclr - - .maxstack 6 - .locals init ( - class [mscorlib]System.Reflection.Assembly pythonRuntime, - class [mscorlib]System.Reflection.Assembly executingAssembly, - class [mscorlib]System.Reflection.AssemblyName pythonRuntimeName, - class [mscorlib]System.Type pythonEngineType, - int8[] publicKeyToken, - string assemblyDirectory, - string pythonRuntimeVersionString, - string pythonRuntimeDllPath) - - // pythonRuntime = null; - ldnull - stloc pythonRuntime - - .try - { -#ifdef DEBUG_PRINT - ldstr "Attempting to load Python.Runtime using standard binding rules... " - call void [mscorlib]System.Console::Write(string) -#endif - - // Attempt to find and load Python.Runtime using standard assembly binding rules. - // This roughly translates into looking in order: - // - GAC - // - ApplicationBase - // - A PrivateBinPath under ApplicationBase - // With an unsigned assembly, the GAC is skipped. - - // System.Reflection.AssemblyName pythonRuntimeName = new System.Reflection.AssemblyName(); - newobj instance void [mscorlib]System.Reflection.AssemblyName::.ctor() - stloc pythonRuntimeName - - // pythonRuntimeName.Name = "Python.Runtime"; - ldloc pythonRuntimeName - ldstr "Python.Runtime" - callvirt instance void [mscorlib]System.Reflection.AssemblyName::set_Name(string) - -#ifdef USE_PYTHON_RUNTIME_VERSION - // pythonRuntimeVersionString = "..."; - ldstr "2.0.0.2" - stloc pythonRuntimeVersionString - - // pythonRuntimeName.Version = new Version(pythonRuntimeVersionString); - ldloc pythonRuntimeName - ldloc pythonRuntimeVersionString - newobj instance void [mscorlib]System.Version::.ctor(string) - callvirt instance void [mscorlib]System.Reflection.AssemblyName::set_Version(class [mscorlib]System.Version) -#endif - -#ifdef USE_PYTHON_RUNTIME_PUBLIC_KEY_TOKEN - // publicKeyToken = new byte[] { ... }; - ldc.i4.8 - newarr [mscorlib]System.Byte - dup - ldtoken field int64 clrModule::PythonRuntimePublicKeyToken - call void [mscorlib]System.Runtime.CompilerServices.RuntimeHelpers::InitializeArray(class [mscorlib]System.Array, valuetype [mscorlib]System.RuntimeFieldHandle) - stloc publicKeyToken - - // pythonRuntimeName.SetPublicKeyToken(publicKeyToken); - ldloc pythonRuntimeName - ldloc publicKeyToken - callvirt instance void [mscorlib]System.Reflection.AssemblyName::SetPublicKeyToken(uint8[]) -#endif - - // pythonRuntimeName.CultureInfo = System.Globalization.CultureInfo.InvariantCulture; - ldloc pythonRuntimeName - call class [mscorlib]System.Globalization.CultureInfo [mscorlib]System.Globalization.CultureInfo::get_InvariantCulture() - callvirt instance void [mscorlib]System.Reflection.AssemblyName::set_CultureInfo(class [mscorlib]System.Globalization.CultureInfo) - - // return System.Reflection.Assembly.Load(pythonRuntimeName); - ldloc pythonRuntimeName - call class [mscorlib]System.Reflection.Assembly [mscorlib]System.Reflection.Assembly::Load(class [mscorlib]System.Reflection.AssemblyName) - stloc pythonRuntime - -#ifdef DEBUG_PRINT - ldstr "Success!" - call void [mscorlib]System.Console::WriteLine(string) -#endif - leave.s LOADED_PYTHON_RUNTIME - } - catch [mscorlib]System.Object - { -#ifdef DEBUG_PRINT - ldstr "Failed." - call void [mscorlib]System.Console::WriteLine(string) -#endif - leave.s EXIT_CLR_LOAD - } - EXIT_CLR_LOAD: nop - - .try - { - // If the above fails for any reason, we fallback to attempting to load "Python.Runtime.dll" - // from the directory this assembly is running in. "This assembly" is probably "clr.pyd", - // sitting somewhere in PYTHONPATH. This is using Assembly.LoadFrom, and inherits all the - // caveats of that call. See MSDN docs for details. - // Suzanne Cook's blog is also an excellent source of info on this: - // http://blogs.msdn.com/suzcook/ - // http://blogs.msdn.com/suzcook/archive/2003/05/29/57143.aspx - // http://blogs.msdn.com/suzcook/archive/2003/06/13/57180.aspx - // executingAssembly = System.Reflection.Assembly.GetExecutingAssembly(); - call class [mscorlib]System.Reflection.Assembly [mscorlib]System.Reflection.Assembly::GetExecutingAssembly() - stloc executingAssembly - - // assemblyDirectory = System.IO.Path.GetDirectoryName(executingAssembly.Location); - ldloc executingAssembly - callvirt instance string [mscorlib]System.Reflection.Assembly::get_Location() - call string [mscorlib]System.IO.Path::GetDirectoryName(string) - stloc assemblyDirectory - - // pythonRuntimeDllPath = System.IO.Path.Combine(assemblyDirectory, "Python.Runtime.dll"); - ldloc assemblyDirectory - ldstr "Python.Runtime.dll" - call string [mscorlib]System.IO.Path::Combine(string, string) - stloc pythonRuntimeDllPath - -#ifdef DEBUG_PRINT - ldstr "Attempting to load Python.Runtime from: '{0}'... " - ldloc pythonRuntimeDllPath - call void [mscorlib]System.Console::Write(string, object) -#endif - - // pythonRuntime = System.Reflection.Assembly.LoadFrom(pythonRuntimeDllPath); - ldloc pythonRuntimeDllPath - call class [mscorlib]System.Reflection.Assembly [mscorlib]System.Reflection.Assembly::LoadFrom(string) - stloc pythonRuntime - -#ifdef DEBUG_PRINT - ldstr "Success!" - call void [mscorlib]System.Console::WriteLine(string) -#endif - leave.s LOADED_PYTHON_RUNTIME - } - catch [mscorlib]System.Object - { -#ifdef DEBUG_PRINT - ldstr "Failed." - call void [mscorlib]System.Console::WriteLine(string) -#endif - leave.s EXIT_PYTHONPATH_LOAD - } - EXIT_PYTHONPATH_LOAD: nop - - // If we get here, we haven't loaded Python.Runtime, so bail. -#ifdef DEBUG_PRINT - ldstr "Could not load Python.Runtime, so sad." - call void [mscorlib]System.Console::WriteLine(string) -#endif - ret - - // Once here, we've successfully loaded SOME version of Python.Runtime - // So now we get the PythonEngine and execute the InitExt method on it. - LOADED_PYTHON_RUNTIME: nop - .try - { -#ifdef DEBUG_PRINT - ldstr "Running Python.Runtime.PythonEngine.InitExt()" - call void [mscorlib]System.Console::WriteLine(string) -#endif - // pythonEngineType = pythonRuntime.GetType("Python.Runtime.PythonEngine"); - ldloc pythonRuntime - ldstr "Python.Runtime.PythonEngine" - callvirt instance class [mscorlib]System.Type [mscorlib]System.Reflection.Assembly::GetType(string) - stloc pythonEngineType - - // pythonEngineType.InvokeMember("InitExt", System.Reflection.BindingFlags.InvokeMethod, null, null, null); - ldloc pythonEngineType - ldstr "InitExt" - ldc.i4 0x100 - ldnull - ldnull - ldnull - callvirt instance object [mscorlib]System.Type::InvokeMember( string, - valuetype [mscorlib]System.Reflection.BindingFlags, - class [mscorlib]System.Reflection.Binder, - object, - object[]) - pop - leave.s EXIT_TRY_INVOKE - } - catch [mscorlib]System.Object - { -#ifdef DEBUG_PRINT - ldstr "Error calling Python.Runtime.PythonEngine.InitExt()." - call void [mscorlib]System.Console::WriteLine(string) -#endif - leave.s EXIT_TRY_INVOKE - } - EXIT_TRY_INVOKE: nop - - ret - } -} - diff --git a/Pythonnet.Runtime/clrobject.cs b/Pythonnet.Runtime/clrobject.cs deleted file mode 100644 index c61f9523db..0000000000 --- a/Pythonnet.Runtime/clrobject.cs +++ /dev/null @@ -1,78 +0,0 @@ -// ========================================================================== -// This software is subject to the provisions of the Zope Public License, -// Version 2.0 (ZPL). A copy of the ZPL should accompany this distribution. -// THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED -// WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -// WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS -// FOR A PARTICULAR PURPOSE. -// ========================================================================== - -using System; -using System.Collections; -using System.Reflection; -using System.Runtime.InteropServices; - -namespace Python.Runtime { - - - internal class CLRObject : ManagedType { - - internal Object inst; - - internal CLRObject(Object ob, IntPtr tp) : base() { - - IntPtr py = Runtime.PyType_GenericAlloc(tp, 0); - - int flags = (int)Marshal.ReadIntPtr(tp, TypeOffset.tp_flags); - if ((flags & TypeFlags.Subclass) != 0) { - IntPtr dict = Marshal.ReadIntPtr(py, ObjectOffset.ob_dict); - if (dict == IntPtr.Zero) { - dict = Runtime.PyDict_New(); - Marshal.WriteIntPtr(py, ObjectOffset.ob_dict, dict); - } - } - - GCHandle gc = GCHandle.Alloc(this); - Marshal.WriteIntPtr(py, ObjectOffset.magic(), (IntPtr)gc); - this.tpHandle = tp; - this.pyHandle = py; - this.gcHandle = gc; - inst = ob; - } - - - internal static CLRObject GetInstance(Object ob, IntPtr pyType) { - return new CLRObject(ob, pyType); - } - - - internal static CLRObject GetInstance(Object ob) { - ClassBase cc = ClassManager.GetClass(ob.GetType()); - return GetInstance(ob, cc.tpHandle); - } - - - internal static IntPtr GetInstHandle(Object ob, IntPtr pyType) { - CLRObject co = GetInstance(ob, pyType); - return co.pyHandle; - } - - - internal static IntPtr GetInstHandle(Object ob, Type type) { - ClassBase cc = ClassManager.GetClass(type); - CLRObject co = GetInstance(ob, cc.tpHandle); - return co.pyHandle; - } - - - internal static IntPtr GetInstHandle(Object ob) { - CLRObject co = GetInstance(ob); - return co.pyHandle; - } - - - } - - -} - diff --git a/Pythonnet.Runtime/codegenerator.cs b/Pythonnet.Runtime/codegenerator.cs deleted file mode 100644 index 4305471e09..0000000000 --- a/Pythonnet.Runtime/codegenerator.cs +++ /dev/null @@ -1,62 +0,0 @@ -// ========================================================================== -// This software is subject to the provisions of the Zope Public License, -// Version 2.0 (ZPL). A copy of the ZPL should accompany this distribution. -// THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED -// WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -// WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS -// FOR A PARTICULAR PURPOSE. -// ========================================================================== - -using System; -using System.Threading; -using System.Runtime.InteropServices; -using System.Runtime.CompilerServices; -using System.Collections; -using System.Reflection; -using System.Reflection.Emit; - -namespace Python.Runtime { - - /// - /// Several places in the runtime generate code on the fly to support - /// dynamic functionality. The CodeGenerator class manages the dynamic - /// assembly used for code generation and provides utility methods for - /// certain repetitive tasks. - /// - - internal class CodeGenerator { - - AssemblyBuilder aBuilder; - ModuleBuilder mBuilder; - - internal CodeGenerator() { - AssemblyName aname = new AssemblyName(); - aname.Name = "__CodeGenerator_Assembly"; - AssemblyBuilderAccess aa = AssemblyBuilderAccess.Run; - - aBuilder = Thread.GetDomain().DefineDynamicAssembly(aname, aa); - mBuilder = aBuilder.DefineDynamicModule("__CodeGenerator_Module"); - } - - //==================================================================== - // DefineType is a shortcut utility to get a new TypeBuilder. - //==================================================================== - - internal TypeBuilder DefineType(string name) { - TypeAttributes attrs = TypeAttributes.Public; - return mBuilder.DefineType(name, attrs); - } - - //==================================================================== - // DefineType is a shortcut utility to get a new TypeBuilder. - //==================================================================== - - internal TypeBuilder DefineType(string name, Type basetype) { - TypeAttributes attrs = TypeAttributes.Public; - return mBuilder.DefineType(name, attrs, basetype); - } - - } - - -} diff --git a/Pythonnet.Runtime/constructorbinder.cs b/Pythonnet.Runtime/constructorbinder.cs deleted file mode 100644 index 4dc1f1457a..0000000000 --- a/Pythonnet.Runtime/constructorbinder.cs +++ /dev/null @@ -1,96 +0,0 @@ -// ========================================================================== -// This software is subject to the provisions of the Zope Public License, -// Version 2.0 (ZPL). A copy of the ZPL should accompany this distribution. -// THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED -// WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -// WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS -// FOR A PARTICULAR PURPOSE. -// ========================================================================== - -using System; -using System.Reflection; - -namespace Python.Runtime { - - //======================================================================== - // A ConstructorBinder encapsulates information about one or more managed - // constructors, and is responsible for selecting the right constructor - // given a set of Python arguments. This is slightly different than the - // standard MethodBinder because of a difference in invoking constructors - // using reflection (which is seems to be a CLR bug). - //======================================================================== - - internal class ConstructorBinder : MethodBinder { - - internal ConstructorBinder () : base() {} - - //==================================================================== - // Constructors get invoked when an instance of a wrapped managed - // class or a subclass of a managed class is created. This differs - // from the MethodBinder implementation in that we return the raw - // result of the constructor rather than wrapping it as a Python - // object - the reason is that only the caller knows the correct - // Python type to use when wrapping the result (may be a subclass). - //==================================================================== - - internal object InvokeRaw(IntPtr inst, IntPtr args, IntPtr kw) { - return this.InvokeRaw(inst, args, kw, null); - } - /// - /// Allows ctor selection to be limited to a single attempt at a - /// match by providing the MethodBase to use instead of searching - /// the entire MethodBinder.list (generic ArrayList) - /// - /// (possibly null) instance - /// PyObject* to the arg tuple - /// PyObject* to the keyword args dict - /// The sole ContructorInfo to use or null - /// The result of the constructor call with converted params - /// - /// 2010-07-24 BC: I added the info parameter to the call to Bind() - /// Binding binding = this.Bind(inst, args, kw, info); - /// to take advantage of Bind()'s ability to use a single MethodBase (CI or MI). - /// - internal object InvokeRaw(IntPtr inst, IntPtr args, IntPtr kw, - MethodBase info) { - Binding binding = this.Bind(inst, args, kw, info); - Object result; - - if (binding == null) { - // It is possible for __new__ to be invoked on construction - // of a Python subclass of a managed class, so args may - // reflect more args than are required to instantiate the - // class. So if we cant find a ctor that matches, we'll see - // if there is a default constructor and, if so, assume that - // any extra args are intended for the subclass' __init__. - - IntPtr eargs = Runtime.PyTuple_New(0); - binding = this.Bind(inst, eargs, kw); - Runtime.Decref(eargs); - - if (binding == null) { - Exceptions.SetError(Exceptions.TypeError, - "no constructor matches given arguments" - ); - return null; - } - } - - // Fire the selected ctor and catch errors... - ConstructorInfo ci = (ConstructorInfo)binding.info; - // Object construction is presumed to be non-blocking and fast - // enough that we shouldn't really need to release the GIL. - try { - result = ci.Invoke(binding.args); - } - catch (Exception e) { - if (e.InnerException != null) { - e = e.InnerException; - } - Exceptions.SetError(e); - return null; - } - return result; - } - } -} diff --git a/Pythonnet.Runtime/constructorbinding.cs b/Pythonnet.Runtime/constructorbinding.cs deleted file mode 100644 index c5f014469f..0000000000 --- a/Pythonnet.Runtime/constructorbinding.cs +++ /dev/null @@ -1,237 +0,0 @@ -// ========================================================================== -// This software is subject to the provisions of the Zope Public License, -// Version 2.0 (ZPL). A copy of the ZPL should accompany this distribution. -// THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED -// WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -// WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS -// FOR A PARTICULAR PURPOSE. -// ========================================================================== - -using System; -using System.Reflection; - -namespace Python.Runtime { - - /// - /// Implements a Python type that wraps a CLR ctor call. Constructor objects - /// support a .Overloads[] syntax to allow explicit ctor overload selection. - /// - /// - /// ClassManager stores a ConstructorBinding instance in the class's __dict__['Overloads'] - /// - /// SomeType.Overloads[Type, ...] works like this: - /// 1) Python retreives the Overloads attribute from this ClassObject's dictionary normally - /// and finds a non-null tp_descr_get slot which is called by the interpreter - /// and returns an IncRef()ed pyHandle to itself. - /// 2) The ConstructorBinding object handles the [] syntax in its mp_subscript by matching - /// the Type object parameters to a contructor overload using Type.GetConstructor() - /// [NOTE: I don't know why method overloads are not searched the same way.] - /// and creating the BoundContructor oject which contains ContructorInfo object. - /// 3) In tp_call, if ctorInfo is not null, ctorBinder.InvokeRaw() is called. - /// - internal class ConstructorBinding : ExtensionType - { - Type type; // The managed Type being wrapped in a ClassObject - IntPtr pyTypeHndl; // The python type tells GetInstHandle which Type to create. - ConstructorBinder ctorBinder; - IntPtr repr; - - public ConstructorBinding(Type type, IntPtr pyTypeHndl, ConstructorBinder ctorBinder) : base() { - this.type = type; - Runtime.Incref(pyTypeHndl); - this.pyTypeHndl = pyTypeHndl; - this.ctorBinder = ctorBinder; - repr = IntPtr.Zero; - } - - /// - /// Descriptor __get__ implementation. - /// Implements a Python type that wraps a CLR ctor call that requires the use - /// of a .Overloads[pyTypeOrType...] syntax to allow explicit ctor overload - /// selection. - /// - /// PyObject* to a Constructors wrapper - /// the instance that the attribute was accessed through, - /// or None when the attribute is accessed through the owner - /// always the owner class - /// a CtorMapper (that borrows a reference to this python type and the - /// ClassObject's ConstructorBinder) wrapper. - /// - /// - /// Python 2.6.5 docs: - /// object.__get__(self, instance, owner) - /// Called to get the attribute of the owner class (class attribute access) - /// or of an instance of that class (instance attribute access). - /// owner is always the owner class, while instance is the instance that - /// the attribute was accessed through, or None when the attribute is accessed through the owner. - /// This method should return the (computed) attribute value or raise an AttributeError exception. - /// - public static IntPtr tp_descr_get(IntPtr op, IntPtr instance, IntPtr owner) - { - ConstructorBinding self = (ConstructorBinding)GetManagedObject(op); - if (self == null) { - return IntPtr.Zero; - } - - // It doesn't seem to matter if it's accessed through an instance (rather than via the type). - /*if (instance != IntPtr.Zero) { - // This is ugly! PyObject_IsInstance() returns 1 for true, 0 for false, -1 for error... - if (Runtime.PyObject_IsInstance(instance, owner) < 1) { - return Exceptions.RaiseTypeError("How in the world could that happen!"); - } - }*/ - Runtime.Incref(self.pyHandle); // Decref'd by the interpreter. - return self.pyHandle; - } - - //==================================================================== - // Implement explicit overload selection using subscript syntax ([]). - //==================================================================== - /// - /// ConstructorBinding.GetItem(PyObject *o, PyObject *key) - /// Return element of o corresponding to the object key or NULL on failure. - /// This is the equivalent of the Python expression o[key]. - /// - /// - /// - /// - public static IntPtr mp_subscript(IntPtr op, IntPtr key) { - ConstructorBinding self = (ConstructorBinding)GetManagedObject(op); - - Type[] types = Runtime.PythonArgsToTypeArray(key); - if (types == null) { - return Exceptions.RaiseTypeError("type(s) expected"); - } - //MethodBase[] methBaseArray = self.ctorBinder.GetMethods(); - //MethodBase ci = MatchSignature(methBaseArray, types); - ConstructorInfo ci = self.type.GetConstructor(types); - if (ci == null) { - string msg = "No match found for constructor signature"; - return Exceptions.RaiseTypeError(msg); - } - BoundContructor boundCtor = new BoundContructor(self.type, self.pyTypeHndl, self.ctorBinder, ci); - - /* Since nothing's chached, do we need the increment??? - Runtime.Incref(boundCtor.pyHandle); // Decref'd by the interpreter??? */ - return boundCtor.pyHandle; - } - - //==================================================================== - // ConstructorBinding __repr__ implementation [borrowed from MethodObject]. - //==================================================================== - - public static IntPtr tp_repr(IntPtr ob) { - ConstructorBinding self = (ConstructorBinding)GetManagedObject(ob); - if (self.repr != IntPtr.Zero) { - Runtime.Incref(self.repr); - return self.repr; - } - MethodBase[] methods = self.ctorBinder.GetMethods(); - string name = self.type.FullName; - string doc = ""; - for (int i = 0; i < methods.Length; i++) { - if (doc.Length > 0) - doc += "\n"; - string str = methods[i].ToString(); - int idx = str.IndexOf("("); - doc += String.Format("{0}{1}", name, str.Substring(idx)); - } - self.repr = Runtime.PyString_FromString(doc); - Runtime.Incref(self.repr); - return self.repr; - } - - //==================================================================== - // ConstructorBinding dealloc implementation. - //==================================================================== - - public static new void tp_dealloc(IntPtr ob) { - ConstructorBinding self = (ConstructorBinding)GetManagedObject(ob); - Runtime.Decref(self.repr); - Runtime.Decref(self.pyTypeHndl); - ExtensionType.FinalizeObject(self); - } - } - - /// - /// Implements a Python type that constucts the given Type given a particular ContructorInfo. - /// - /// - /// Here mostly because I wanted a new __repr__ function for the selected constructor. - /// An earlier implementation hung the __call__ on the ContructorBinding class and - /// returned an Incref()ed self.pyHandle from the __get__ function. - /// - internal class BoundContructor : ExtensionType { - Type type; // The managed Type being wrapped in a ClassObject - IntPtr pyTypeHndl; // The python type tells GetInstHandle which Type to create. - ConstructorBinder ctorBinder; - ConstructorInfo ctorInfo; - IntPtr repr; - - public BoundContructor(Type type, IntPtr pyTypeHndl, ConstructorBinder ctorBinder, ConstructorInfo ci) - : base() { - this.type = type; - Runtime.Incref(pyTypeHndl); - this.pyTypeHndl = pyTypeHndl; - this.ctorBinder = ctorBinder; - ctorInfo = ci; - repr = IntPtr.Zero; - } - - /// - /// BoundContructor.__call__(PyObject *callable_object, PyObject *args, PyObject *kw) - /// - /// PyObject *callable_object - /// PyObject *args - /// PyObject *kw - /// A reference to a new instance of the class by invoking the selected ctor(). - public static IntPtr tp_call(IntPtr op, IntPtr args, IntPtr kw) { - BoundContructor self = (BoundContructor)GetManagedObject(op); - // Even though a call with null ctorInfo just produces the old behavior - /*if (self.ctorInfo == null) { - string msg = "Usage: Class.Overloads[CLR_or_python_Type, ...]"; - return Exceptions.RaiseTypeError(msg); - }*/ - // Bind using ConstructorBinder.Bind and invoke the ctor providing a null instancePtr - // which will fire self.ctorInfo using ConstructorInfo.Invoke(). - Object obj = self.ctorBinder.InvokeRaw(IntPtr.Zero, args, kw, self.ctorInfo); - if (obj == null) { - // XXX set an error - return IntPtr.Zero; - } - // Instantiate the python object that wraps the result of the method call - // and return the PyObject* to it. - return CLRObject.GetInstHandle(obj, self.pyTypeHndl); - } - - //==================================================================== - // BoundContructor __repr__ implementation [borrowed from MethodObject]. - //==================================================================== - - public static IntPtr tp_repr(IntPtr ob) { - BoundContructor self = (BoundContructor)GetManagedObject(ob); - if (self.repr != IntPtr.Zero) { - Runtime.Incref(self.repr); - return self.repr; - } - string name = self.type.FullName; - string str = self.ctorInfo.ToString(); - int idx = str.IndexOf("("); - str = String.Format("returns a new {0}{1}", name, str.Substring(idx)); - self.repr = Runtime.PyString_FromString(str); - Runtime.Incref(self.repr); - return self.repr; - } - - //==================================================================== - // ConstructorBinding dealloc implementation. - //==================================================================== - - public static new void tp_dealloc(IntPtr ob) { - BoundContructor self = (BoundContructor)GetManagedObject(ob); - Runtime.Decref(self.repr); - Runtime.Decref(self.pyTypeHndl); - ExtensionType.FinalizeObject(self); - } - } -} diff --git a/Pythonnet.Runtime/converter.cs b/Pythonnet.Runtime/converter.cs deleted file mode 100644 index af7acd972a..0000000000 --- a/Pythonnet.Runtime/converter.cs +++ /dev/null @@ -1,714 +0,0 @@ -// ========================================================================== -// This software is subject to the provisions of the Zope Public License, -// Version 2.0 (ZPL). A copy of the ZPL should accompany this distribution. -// THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED -// WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -// WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS -// FOR A PARTICULAR PURPOSE. -// ========================================================================== - -using System; -using System.Reflection; -using System.Runtime.InteropServices; -using System.Globalization; -using System.Security; - -namespace Python.Runtime { - - //======================================================================== - // Performs data conversions between managed types and Python types. - //======================================================================== - - [SuppressUnmanagedCodeSecurityAttribute()] - - internal class Converter { - - private Converter() {} - - static NumberFormatInfo nfi; - static Type objectType; - static Type stringType; - static Type doubleType; - static Type int32Type; - static Type int64Type; - static Type flagsType; - static Type boolType; - //static Type typeType; - - static Converter () { - nfi = NumberFormatInfo.InvariantInfo; - objectType = typeof(Object); - stringType = typeof(String); - int32Type = typeof(Int32); - int64Type = typeof(Int64); - doubleType = typeof(Double); - flagsType = typeof(FlagsAttribute); - boolType = typeof(Boolean); - //typeType = typeof(Type); - } - - - //==================================================================== - // Given a builtin Python type, return the corresponding CLR type. - //==================================================================== - - internal static Type GetTypeByAlias(IntPtr op) { - if ((op == Runtime.PyStringType) || - (op == Runtime.PyUnicodeType)) { - return stringType; - } - else if (op == Runtime.PyIntType) { - return int32Type; - } - else if (op == Runtime.PyLongType) { - return int64Type; - } - else if (op == Runtime.PyFloatType) { - return doubleType; - } - else if (op == Runtime.PyBoolType) { - return boolType; - } - return null; - } - - - //==================================================================== - // Return a Python object for the given native object, converting - // basic types (string, int, etc.) into equivalent Python objects. - // This always returns a new reference. Note that the System.Decimal - // type has no Python equivalent and converts to a managed instance. - //==================================================================== - - internal static IntPtr ToPython(Object value, Type type) { - IntPtr result = IntPtr.Zero; - - // Null always converts to None in Python. - - if (value == null) { - result = Runtime.PyNone; - Runtime.Incref(result); - return result; - } - - // hmm - from Python, we almost never care what the declared - // type is. we'd rather have the object bound to the actual - // implementing class. - - type = value.GetType(); - - TypeCode tc = Type.GetTypeCode(type); - - switch(tc) { - - case TypeCode.Object: - result = CLRObject.GetInstHandle(value, type); - - // XXX - hack to make sure we convert new-style class based - // managed exception instances to wrappers ;( - if (Runtime.wrap_exceptions) { - Exception e = value as Exception; - if (e != null) { - return Exceptions.GetExceptionInstanceWrapper(result); - } - } - - return result; - - case TypeCode.String: - return Runtime.PyUnicode_FromString((string)value); - - case TypeCode.Int32: - return Runtime.PyInt_FromInt32((int)value); - - case TypeCode.Boolean: - if ((bool)value) { - Runtime.Incref(Runtime.PyTrue); - return Runtime.PyTrue; - } - Runtime.Incref(Runtime.PyFalse); - return Runtime.PyFalse; - - case TypeCode.Byte: - return Runtime.PyInt_FromInt32((int)((byte)value)); - - case TypeCode.Char: - return Runtime.PyUnicode_FromOrdinal((int)((char)value)); - - case TypeCode.Int16: - return Runtime.PyInt_FromInt32((int)((short)value)); - - case TypeCode.Int64: - return Runtime.PyLong_FromLongLong((long)value); - - case TypeCode.Single: - // return Runtime.PyFloat_FromDouble((double)((float)value)); - string ss = ((float)value).ToString(nfi); - IntPtr ps = Runtime.PyString_FromString(ss); - IntPtr op = Runtime.PyFloat_FromString(ps, IntPtr.Zero); - Runtime.Decref(ps); - return op; - - case TypeCode.Double: - return Runtime.PyFloat_FromDouble((double)value); - - case TypeCode.SByte: - return Runtime.PyInt_FromInt32((int)((sbyte)value)); - - case TypeCode.UInt16: - return Runtime.PyInt_FromInt32((int)((ushort)value)); - - case TypeCode.UInt32: - return Runtime.PyLong_FromUnsignedLong((uint)value); - - case TypeCode.UInt64: - return Runtime.PyLong_FromUnsignedLongLong((ulong)value); - - default: - result = CLRObject.GetInstHandle(value, type); - return result; - } - - } - - - //==================================================================== - // In a few situations, we don't have any advisory type information - // when we want to convert an object to Python. - //==================================================================== - - internal static IntPtr ToPythonImplicit(Object value) { - if (value == null) { - IntPtr result = Runtime.PyNone; - Runtime.Incref(result); - return result; - } - - return ToPython(value, objectType); - } - - - //==================================================================== - // Return a managed object for the given Python object, taking funny - // byref types into account. - //==================================================================== - - internal static bool ToManaged(IntPtr value, Type type, - out object result, bool setError) { - if (type.IsByRef) { - type = type.GetElementType(); - } - return Converter.ToManagedValue(value, type, out result, setError); - } - - - internal static bool ToManagedValue(IntPtr value, Type obType, - out Object result, bool setError) { - // Common case: if the Python value is a wrapped managed object - // instance, just return the wrapped object. - ManagedType mt = ManagedType.GetManagedObject(value); - result = null; - - // XXX - hack to support objects wrapped in old-style classes - // (such as exception objects). - if (Runtime.wrap_exceptions) { - if (mt == null) { - if (Runtime.PyObject_IsInstance( - value, Exceptions.Exception - ) > 0) { - IntPtr p = Runtime.PyObject_GetAttrString(value, "_inner"); - if (p != IntPtr.Zero) { - // This is safe because we know that the __dict__ of - // value holds a reference to _inner. - value = p; - Runtime.Decref(p); - mt = ManagedType.GetManagedObject(value); - } - } - IntPtr c = Exceptions.UnwrapExceptionClass(value); - if ((c != IntPtr.Zero) && (c != value)) { - value = c; - Runtime.Decref(c); - mt = ManagedType.GetManagedObject(value); - } - } - } - - if (mt != null) { - if (mt is CLRObject) { - object tmp = ((CLRObject)mt).inst; - if (obType.IsInstanceOfType(tmp)) { - result = tmp; - return true; - } - string err = "value cannot be converted to {0}"; - err = String.Format(err, obType); - Exceptions.SetError(Exceptions.TypeError, err); - return false; - } - if (mt is ClassBase) { - result = ((ClassBase)mt).type; - return true; - } - // shouldnt happen - return false; - } - - if (value == Runtime.PyNone && !obType.IsValueType) { - result = null; - return true; - } - - if (obType.IsArray) { - return ToArray(value, obType, out result, setError); - } - - if (obType.IsEnum) { - return ToEnum(value, obType, out result, setError); - } - - // Conversion to 'Object' is done based on some reasonable - // default conversions (Python string -> managed string, - // Python int -> Int32 etc.). - - if (obType == objectType) { - if (Runtime.IsStringType(value)) { - return ToPrimitive(value, stringType, out result, - setError); - } - - else if (Runtime.PyBool_Check(value)) { - return ToPrimitive(value, boolType, out result, setError); - } - - else if (Runtime.PyInt_Check(value)) { - return ToPrimitive(value, int32Type, out result, setError); - } - - else if (Runtime.PyLong_Check(value)) { - return ToPrimitive(value, int64Type, out result, setError); - } - - else if (Runtime.PyFloat_Check(value)) { - return ToPrimitive(value, doubleType, out result, setError); - } - - else if (Runtime.PySequence_Check(value)) { - return ToArray(value, typeof(object[]), out result, - setError); - } - - if (setError) { - Exceptions.SetError(Exceptions.TypeError, - "value cannot be converted to Object" - ); - } - - return false; - } - - return ToPrimitive(value, obType, out result, setError); - - } - - //==================================================================== - // Convert a Python value to an instance of a primitive managed type. - //==================================================================== - - static bool ToPrimitive(IntPtr value, Type obType, out Object result, - bool setError) { - - IntPtr overflow = Exceptions.OverflowError; - TypeCode tc = Type.GetTypeCode(obType); - result = null; - IntPtr op; - int ival; - - switch(tc) { - - case TypeCode.String: - string st = Runtime.GetManagedString(value); - if (st == null) { - goto type_error; - } - result = st; - return true; - - case TypeCode.Int32: - // Trickery to support 64-bit platforms. - if (IntPtr.Size == 4) { - op = Runtime.PyNumber_Int(value); - - // As of Python 2.3, large ints magically convert :( - if (Runtime.PyLong_Check(op) ) { - Runtime.Decref(op); - goto overflow; - } - - if (op == IntPtr.Zero) { - if (Exceptions.ExceptionMatches(overflow)) { - goto overflow; - } - goto type_error; - } - ival = (int)Runtime.PyInt_AsLong(op); - Runtime.Decref(op); - result = ival; - return true; - } - else { - op = Runtime.PyNumber_Long(value); - if (op == IntPtr.Zero) { - if (Exceptions.ExceptionMatches(overflow)) { - goto overflow; - } - goto type_error; - } - long ll = (long)Runtime.PyLong_AsLongLong(op); - Runtime.Decref(op); - if ((ll == -1) && Exceptions.ErrorOccurred()) { - goto overflow; - } - if (ll > Int32.MaxValue || ll < Int32.MinValue) { - goto overflow; - } - result = (int)ll; - return true; - } - - case TypeCode.Boolean: - result = (Runtime.PyObject_IsTrue(value) != 0); - return true; - - case TypeCode.Byte: - if (Runtime.PyObject_TypeCheck(value, Runtime.PyStringType)) { - if (Runtime.PyString_Size(value) == 1) { - op = Runtime.PyString_AS_STRING(value); - result = (byte)Marshal.ReadByte(op); - return true; - } - goto type_error; - } - - op = Runtime.PyNumber_Int(value); - if (op == IntPtr.Zero) { - if (Exceptions.ExceptionMatches(overflow)) { - goto overflow; - } - goto type_error; - } - ival = (int) Runtime.PyInt_AsLong(op); - Runtime.Decref(op); - - if (ival > Byte.MaxValue || ival < Byte.MinValue) { - goto overflow; - } - byte b = (byte) ival; - result = b; - return true; - - case TypeCode.SByte: - if (Runtime.PyObject_TypeCheck(value, Runtime.PyStringType)) { - if (Runtime.PyString_Size(value) == 1) { - op = Runtime.PyString_AS_STRING(value); - result = (sbyte)Marshal.ReadByte(op); - return true; - } - goto type_error; - } - - op = Runtime.PyNumber_Int(value); - if (op == IntPtr.Zero) { - if (Exceptions.ExceptionMatches(overflow)) { - goto overflow; - } - goto type_error; - } - ival = (int) Runtime.PyInt_AsLong(op); - Runtime.Decref(op); - - if (ival > SByte.MaxValue || ival < SByte.MinValue) { - goto overflow; - } - sbyte sb = (sbyte) ival; - result = sb; - return true; - - case TypeCode.Char: - - if (Runtime.PyObject_TypeCheck(value, Runtime.PyStringType)) { - if (Runtime.PyString_Size(value) == 1) { - op = Runtime.PyString_AS_STRING(value); - result = (char)Marshal.ReadByte(op); - return true; - } - goto type_error; - } - - else if (Runtime.PyObject_TypeCheck(value, - Runtime.PyUnicodeType)) { - if (Runtime.PyUnicode_GetSize(value) == 1) { - op = Runtime.PyUnicode_AS_UNICODE(value); -#if (!UCS4) - // 2011-01-02: Marshal as character array because the cast - // result = (char)Marshal.ReadInt16(op); throws an OverflowException - // on negative numbers with Check Overflow option set on the project - Char[] buff = new Char[1]; - Marshal.Copy(op, buff, 0, 1); - result = buff[0]; -#else - // XXX this is probably NOT correct? - result = (char)Marshal.ReadInt32(op); -#endif - return true; - } - goto type_error; - } - - op = Runtime.PyNumber_Int(value); - if (op == IntPtr.Zero) { - goto type_error; - } - ival = Runtime.PyInt_AsLong(op); - if (ival > Char.MaxValue || ival < Char.MinValue) { - goto overflow; - } - Runtime.Decref(op); - result = (char)ival; - return true; - - case TypeCode.Int16: - op = Runtime.PyNumber_Int(value); - if (op == IntPtr.Zero) { - if (Exceptions.ExceptionMatches(overflow)) { - goto overflow; - } - goto type_error; - } - ival = (int) Runtime.PyInt_AsLong(op); - Runtime.Decref(op); - if (ival > Int16.MaxValue || ival < Int16.MinValue) { - goto overflow; - } - short s = (short) ival; - result = s; - return true; - - case TypeCode.Int64: - op = Runtime.PyNumber_Long(value); - if (op == IntPtr.Zero) { - if (Exceptions.ExceptionMatches(overflow)) { - goto overflow; - } - goto type_error; - } - long l = (long)Runtime.PyLong_AsLongLong(op); - Runtime.Decref(op); - if ((l == -1) && Exceptions.ErrorOccurred()) { - goto overflow; - } - result = l; - return true; - - case TypeCode.UInt16: - op = Runtime.PyNumber_Int(value); - if (op == IntPtr.Zero) { - if (Exceptions.ExceptionMatches(overflow)) { - goto overflow; - } - goto type_error; - } - ival = (int) Runtime.PyInt_AsLong(op); - Runtime.Decref(op); - if (ival > UInt16.MaxValue || ival < UInt16.MinValue) { - goto overflow; - } - ushort us = (ushort) ival; - result = us; - return true; - - case TypeCode.UInt32: - op = Runtime.PyNumber_Long(value); - if (op == IntPtr.Zero) { - if (Exceptions.ExceptionMatches(overflow)) { - goto overflow; - } - goto type_error; - } - uint ui = (uint)Runtime.PyLong_AsUnsignedLong(op); - Runtime.Decref(op); - if (Exceptions.ErrorOccurred()) { - goto overflow; - } - result = ui; - return true; - - case TypeCode.UInt64: - op = Runtime.PyNumber_Long(value); - if (op == IntPtr.Zero) { - if (Exceptions.ExceptionMatches(overflow)) { - goto overflow; - } - goto type_error; - } - ulong ul = (ulong)Runtime.PyLong_AsUnsignedLongLong(op); - Runtime.Decref(op); - if (Exceptions.ErrorOccurred()) { - goto overflow; - } - result = ul; - return true; - - - case TypeCode.Single: - op = Runtime.PyNumber_Float(value); - if (op == IntPtr.Zero) { - if (Exceptions.ExceptionMatches(overflow)) { - goto overflow; - } - goto type_error; - } - double dd = Runtime.PyFloat_AsDouble(value); - if (dd > Single.MaxValue || dd < Single.MinValue) { - goto overflow; - } - result = (float)dd; - return true; - - case TypeCode.Double: - op = Runtime.PyNumber_Float(value); - if (op == IntPtr.Zero) { - goto type_error; - } - double d = Runtime.PyFloat_AsDouble(op); - Runtime.Decref(op); - if (d > Double.MaxValue || d < Double.MinValue) { - goto overflow; - } - result = d; - return true; - - } - - - type_error: - - if (setError) { - string format = "'{0}' value cannot be converted to {1}"; - string tpName = Runtime.PyObject_GetTypeName(value); - string error = String.Format(format, tpName, obType); - Exceptions.SetError(Exceptions.TypeError, error); - } - - return false; - - overflow: - - if (setError) { - string error = "value too large to convert"; - Exceptions.SetError(Exceptions.OverflowError, error); - } - - return false; - - } - - - static void SetConversionError(IntPtr value, Type target) { - IntPtr ob = Runtime.PyObject_Repr(value); - string src = Runtime.GetManagedString(ob); - Runtime.Decref(ob); - string error = String.Format( - "Cannot convert {0} to {1}", src, target - ); - Exceptions.SetError(Exceptions.TypeError, error); - } - - - //==================================================================== - // Convert a Python value to a correctly typed managed array instance. - // The Python value must support the Python sequence protocol and the - // items in the sequence must be convertible to the target array type. - //==================================================================== - - static bool ToArray(IntPtr value, Type obType, out Object result, - bool setError) { - - Type elementType = obType.GetElementType(); - int size = Runtime.PySequence_Size(value); - result = null; - - if (size < 0) { - if (setError) { - SetConversionError(value, obType); - } - return false; - } - - Array items = Array.CreateInstance(elementType, size); - - // XXX - is there a better way to unwrap this if it is a real - // array? - for (int i = 0; i < size; i++) { - Object obj = null; - IntPtr item = Runtime.PySequence_GetItem(value, i); - if (item == IntPtr.Zero) { - if (setError) { - SetConversionError(value, obType); - return false; - } - } - - if (!Converter.ToManaged(item, elementType, out obj, true)) { - Runtime.Decref(item); - return false; - } - - items.SetValue(obj, i); - Runtime.Decref(item); - } - - result = items; - return true; - } - - - //==================================================================== - // Convert a Python value to a correctly typed managed enum instance. - //==================================================================== - - static bool ToEnum(IntPtr value, Type obType, out Object result, - bool setError) { - - Type etype = Enum.GetUnderlyingType(obType); - result = null; - - if (!ToPrimitive(value, etype, out result, setError)) { - return false; - } - - if (Enum.IsDefined(obType, result)) { - result = Enum.ToObject(obType, result); - return true; - } - - if (obType.GetCustomAttributes(flagsType, true).Length > 0) { - result = Enum.ToObject(obType, result); - return true; - } - - if (setError) { - string error = "invalid enumeration value"; - Exceptions.SetError(Exceptions.ValueError, error); - } - - return false; - - } - - - - } - - -} diff --git a/Pythonnet.Runtime/debughelper.cs b/Pythonnet.Runtime/debughelper.cs deleted file mode 100644 index 2c7c6a054f..0000000000 --- a/Pythonnet.Runtime/debughelper.cs +++ /dev/null @@ -1,128 +0,0 @@ -// ========================================================================== -// This software is subject to the provisions of the Zope Public License, -// Version 2.0 (ZPL). A copy of the ZPL should accompany this distribution. -// THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED -// WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -// WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS -// FOR A PARTICULAR PURPOSE. -// ========================================================================== - -using System; -using System.Collections; -using System.Reflection; -using System.Runtime.InteropServices; -using System.Diagnostics; -using System.Threading; - -namespace Python.Runtime { - - /// - /// Debugging helper utilities. - /// The methods are only executed when the DEBUG flag is set. Otherwise - /// they are automagically hidden by the compiler and silently surpressed. - /// - - internal class DebugUtil { - - [Conditional("DEBUG")] - public static void Print(string msg, params IntPtr[] args) { - string result = msg; - result += " "; - - for (int i = 0; i < args.Length; i++) { - if (args[i] == IntPtr.Zero) { - Console.WriteLine("null arg to print"); - } - IntPtr ob = Runtime.PyObject_Repr(args[i]); - result += Runtime.GetManagedString(ob); - Runtime.Decref(ob); - result += " "; - } - Console.WriteLine(result); - return; - } - - [Conditional("DEBUG")] - public static void Print(string msg) { - Console.WriteLine(msg); - } - - [Conditional("DEBUG")] - internal static void DumpType(IntPtr type) { - IntPtr op = Marshal.ReadIntPtr(type, TypeOffset.tp_name); - string name = Marshal.PtrToStringAnsi(op); - - Console.WriteLine("Dump type: {0}", name); - - op = Marshal.ReadIntPtr(type, TypeOffset.ob_type); - DebugUtil.Print(" type: ", op); - - op = Marshal.ReadIntPtr(type, TypeOffset.tp_base); - DebugUtil.Print(" base: ", op); - - op = Marshal.ReadIntPtr(type, TypeOffset.tp_bases); - DebugUtil.Print(" bases: ", op); - - //op = Marshal.ReadIntPtr(type, TypeOffset.tp_mro); - //DebugUtil.Print(" mro: ", op); - - - FieldInfo[] slots = typeof(TypeOffset).GetFields(); - int size = IntPtr.Size; - - for (int i = 0; i < slots.Length; i++) { - int offset = i * size; - name = slots[i].Name; - op = Marshal.ReadIntPtr(type, offset); - Console.WriteLine(" {0}: {1}", name, op); - } - - Console.WriteLine(""); - Console.WriteLine(""); - - op = Marshal.ReadIntPtr(type, TypeOffset.tp_dict); - if (op == IntPtr.Zero) { - Console.WriteLine(" dict: null"); - } - else { - DebugUtil.Print(" dict: ", op); - } - - } - - [Conditional("DEBUG")] - internal static void DumpInst(IntPtr ob) { - IntPtr tp = Runtime.PyObject_TYPE(ob); - int sz = (int)Marshal.ReadIntPtr(tp, TypeOffset.tp_basicsize); - - for (int i = 0; i < sz; i += IntPtr.Size) { - IntPtr pp = new IntPtr(ob.ToInt64() + i); - IntPtr v = Marshal.ReadIntPtr(pp); - Console.WriteLine("offset {0}: {1}", i, v); - } - - Console.WriteLine(""); - Console.WriteLine(""); - } - - [Conditional("DEBUG")] - internal static void debug(string msg) { - StackTrace st = new StackTrace(1, true); - StackFrame sf = st.GetFrame(0); - MethodBase mb = sf.GetMethod(); - Type mt = mb.DeclaringType; - string caller = mt.Name + "." + sf.GetMethod().Name; - Thread t = Thread.CurrentThread; - string tid = t.GetHashCode().ToString(); - Console.WriteLine("thread {0} : {1}", tid, caller); - Console.WriteLine(" {0}", msg); - return; - } - - - } - - -} - - diff --git a/Pythonnet.Runtime/delegatemanager.cs b/Pythonnet.Runtime/delegatemanager.cs deleted file mode 100644 index ddbabf8724..0000000000 --- a/Pythonnet.Runtime/delegatemanager.cs +++ /dev/null @@ -1,289 +0,0 @@ -// ========================================================================== -// This software is subject to the provisions of the Zope Public License, -// Version 2.0 (ZPL). A copy of the ZPL should accompany this distribution. -// THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED -// WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -// WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS -// FOR A PARTICULAR PURPOSE. -// ========================================================================== - -using System; -using System.Threading; -using System.Runtime.InteropServices; -using System.Runtime.CompilerServices; -using System.Collections; -using System.Reflection; -using System.Reflection.Emit; - -namespace Python.Runtime { - - /// - /// The DelegateManager class manages the creation of true managed - /// delegate instances that dispatch calls to Python methods. - /// - - internal class DelegateManager { - - Hashtable cache; - Type basetype; - Type listtype; - Type voidtype; - Type typetype; - Type ptrtype; - CodeGenerator codeGenerator; - - public DelegateManager() { - basetype = typeof(Dispatcher); - listtype = typeof(ArrayList); - voidtype = typeof(void); - typetype = typeof(Type); - ptrtype = typeof(IntPtr); - cache = new Hashtable(); - codeGenerator = new CodeGenerator(); - } - - //==================================================================== - // Given a true delegate instance, return the PyObject handle of the - // Python object implementing the delegate (or IntPtr.Zero if the - // delegate is not implemented in Python code. - //==================================================================== - - public IntPtr GetPythonHandle(Delegate d) { - if ((d != null) && (d.Target is Dispatcher)) { - Dispatcher disp = d.Target as Dispatcher; - return disp.target; - } - return IntPtr.Zero; - } - - //==================================================================== - // GetDispatcher is responsible for creating a class that provides - // an appropriate managed callback method for a given delegate type. - //==================================================================== - - private Type GetDispatcher(Type dtype) { - - // If a dispatcher type for the given delegate type has already - // been generated, get it from the cache. The cache maps delegate - // types to generated dispatcher types. A possible optimization - // for the future would be to generate dispatcher types based on - // unique signatures rather than delegate types, since multiple - // delegate types with the same sig could use the same dispatcher. - - Object item = cache[dtype]; - if (item != null) { - return (Type)item; - } - - string name = "__" + dtype.FullName + "Dispatcher"; - name = name.Replace('.', '_'); - name = name.Replace('+', '_'); - TypeBuilder tb = codeGenerator.DefineType(name, basetype); - - // Generate a constructor for the generated type that calls the - // appropriate constructor of the Dispatcher base type. - - MethodAttributes ma = MethodAttributes.Public | - MethodAttributes.HideBySig | - MethodAttributes.SpecialName | - MethodAttributes.RTSpecialName; - CallingConventions cc = CallingConventions.Standard; - Type[] args = {ptrtype, typetype}; - ConstructorBuilder cb = tb.DefineConstructor(ma, cc, args); - ConstructorInfo ci = basetype.GetConstructor(args); - ILGenerator il = cb.GetILGenerator(); - il.Emit(OpCodes.Ldarg_0); - il.Emit(OpCodes.Ldarg_1); - il.Emit(OpCodes.Ldarg_2); - il.Emit(OpCodes.Call, ci); - il.Emit(OpCodes.Ret); - - // Method generation: we generate a method named "Invoke" on the - // dispatcher type, whose signature matches the delegate type for - // which it is generated. The method body simply packages the - // arguments and hands them to the Dispatch() method, which deals - // with converting the arguments, calling the Python method and - // converting the result of the call. - - MethodInfo method = dtype.GetMethod("Invoke"); - ParameterInfo[] pi = method.GetParameters(); - - Type[] signature = new Type[pi.Length]; - for (int i = 0; i < pi.Length; i++) { - signature[i] = pi[i].ParameterType; - } - - MethodBuilder mb = tb.DefineMethod( - "Invoke", - MethodAttributes.Public, - method.ReturnType, - signature - ); - - ConstructorInfo ctor = listtype.GetConstructor(Type.EmptyTypes); - MethodInfo dispatch = basetype.GetMethod("Dispatch"); - MethodInfo add = listtype.GetMethod("Add"); - - il = mb.GetILGenerator(); - il.DeclareLocal(listtype); - il.Emit(OpCodes.Newobj, ctor); - il.Emit(OpCodes.Stloc_0); - - for (int c = 0; c < signature.Length; c++) { - Type t = signature[c]; - il.Emit(OpCodes.Ldloc_0); - il.Emit(OpCodes.Ldarg_S, (byte)(c + 1)); - - if (t.IsValueType) { - il.Emit(OpCodes.Box, t); - } - - il.Emit(OpCodes.Callvirt, add); - il.Emit(OpCodes.Pop); - } - - il.Emit(OpCodes.Ldarg_0); - il.Emit(OpCodes.Ldloc_0); - il.Emit(OpCodes.Call, dispatch); - - if (method.ReturnType == voidtype) { - il.Emit(OpCodes.Pop); - } - else if (method.ReturnType.IsValueType) { - il.Emit(OpCodes.Unbox_Any, method.ReturnType); - } - - il.Emit(OpCodes.Ret); - - Type disp = tb.CreateType(); - cache[dtype] = disp; - return disp; - } - - //==================================================================== - // Given a delegate type and a callable Python object, GetDelegate - // returns an instance of the delegate type. The delegate instance - // returned will dispatch calls to the given Python object. - //==================================================================== - - internal Delegate GetDelegate(Type dtype, IntPtr callable) { - Type dispatcher = GetDispatcher(dtype); - object[] args = {callable, dtype}; - object o = Activator.CreateInstance(dispatcher, args); - return Delegate.CreateDelegate(dtype, o, "Invoke"); - } - - - - } - - - /* When a delegate instance is created that has a Python implementation, - the delegate manager generates a custom subclass of Dispatcher and - instantiates it, passing the IntPtr of the Python callable. - - The "real" delegate is created using CreateDelegate, passing the - instance of the generated type and the name of the (generated) - implementing method (Invoke). - - The true delegate instance holds the only reference to the dispatcher - instance, which ensures that when the delegate dies, the finalizer - of the referenced instance will be able to decref the Python - callable. - - A possible alternate strategy would be to create custom subclasses - of the required delegate type, storing the IntPtr in it directly. - This would be slightly cleaner, but I'm not sure if delegates are - too "special" for this to work. It would be more work, so for now - the 80/20 rule applies :) - - */ - - public class Dispatcher { - - public IntPtr target; - public Type dtype; - - public Dispatcher(IntPtr target, Type dtype) { - Runtime.Incref(target); - this.target = target; - this.dtype = dtype; - } - - ~Dispatcher() { - // Note: the managed GC thread can run and try to free one of - // these *after* the Python runtime has been finalized! - if (Runtime.Py_IsInitialized() > 0) { - IntPtr gs = PythonEngine.AcquireLock(); - Runtime.Decref(target); - PythonEngine.ReleaseLock(gs); - } - } - - public object Dispatch(ArrayList args) { - IntPtr gs = PythonEngine.AcquireLock(); - object ob = null; - - try { - ob = TrueDispatch(args); - } - catch (Exception e) { - PythonEngine.ReleaseLock(gs); - throw e; - } - - PythonEngine.ReleaseLock(gs); - return ob; - } - - public object TrueDispatch(ArrayList args) { - MethodInfo method = dtype.GetMethod("Invoke"); - ParameterInfo[] pi = method.GetParameters(); - IntPtr pyargs = Runtime.PyTuple_New(pi.Length); - Type rtype = method.ReturnType; - - for (int i = 0; i < pi.Length; i++) { - // Here we own the reference to the Python value, and we - // give the ownership to the arg tuple. - IntPtr arg = Converter.ToPython(args[i], pi[i].ParameterType); - Runtime.PyTuple_SetItem(pyargs, i, arg); - } - - IntPtr op = Runtime.PyObject_Call(target, pyargs, IntPtr.Zero); - Runtime.Decref(pyargs); - - if (op == IntPtr.Zero) { - PythonException e = new PythonException(); - throw e; - } - - if (rtype == typeof(void)) { - return null; - } - - Object result = null; - if (!Converter.ToManaged(op, rtype, out result, false)) { - string s = "could not convert Python result to " + - rtype.ToString(); - Runtime.Decref(op); - throw new ConversionException(s); - } - - Runtime.Decref(op); - return result; - } - - - } - - - public class ConversionException : System.Exception { - - public ConversionException() : base() {} - - public ConversionException(string msg) : base(msg) {} - - } - - -} diff --git a/Pythonnet.Runtime/delegateobject.cs b/Pythonnet.Runtime/delegateobject.cs deleted file mode 100644 index 467b9d0644..0000000000 --- a/Pythonnet.Runtime/delegateobject.cs +++ /dev/null @@ -1,119 +0,0 @@ -// ========================================================================== -// This software is subject to the provisions of the Zope Public License, -// Version 2.0 (ZPL). A copy of the ZPL should accompany this distribution. -// THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED -// WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -// WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS -// FOR A PARTICULAR PURPOSE. -// ========================================================================== - -using System; -using System.Reflection; -using System.Runtime.InteropServices; - -namespace Python.Runtime { - - /// - /// Managed class that provides the implementation for reflected delegate - /// types. Delegates are represented in Python by generated type objects. - /// Each of those type objects is associated an instance of this class, - /// which provides its implementation. - /// - - internal class DelegateObject : ClassBase { - - MethodBinder binder; - - internal DelegateObject(Type tp) : base(tp) { - binder = new MethodBinder(tp.GetMethod("Invoke")); - } - - - //==================================================================== - // Given a PyObject pointer to an instance of a delegate type, return - // the true managed delegate the Python object represents (or null). - //==================================================================== - - private static Delegate GetTrueDelegate(IntPtr op) { - CLRObject o = GetManagedObject(op) as CLRObject; - if (o != null) { - Delegate d = o.inst as Delegate; - return d; - } - return null; - } - - - internal override bool CanSubclass() { - return false; - } - - - //==================================================================== - // DelegateObject __new__ implementation. The result of this is a new - // PyObject whose type is DelegateObject and whose ob_data is a handle - // to an actual delegate instance. The method wrapped by the actual - // delegate instance belongs to an object generated to relay the call - // to the Python callable passed in. - //==================================================================== - - public static IntPtr tp_new(IntPtr tp, IntPtr args, IntPtr kw) { - DelegateObject self = (DelegateObject)GetManagedObject(tp); - - if (Runtime.PyTuple_Size(args) != 1) { - string message = "class takes exactly one argument"; - return Exceptions.RaiseTypeError(message); - } - - IntPtr method = Runtime.PyTuple_GetItem(args, 0); - - if (Runtime.PyCallable_Check(method) != 1) { - return Exceptions.RaiseTypeError("argument must be callable"); - } - - Delegate d = PythonEngine.DelegateManager.GetDelegate(self.type, method); - return CLRObject.GetInstHandle(d, self.pyHandle); - } - - - - //==================================================================== - // Implements __call__ for reflected delegate types. - //==================================================================== - - public static IntPtr tp_call(IntPtr ob, IntPtr args, IntPtr kw) { - IntPtr pytype = Runtime.PyObject_TYPE(ob); - DelegateObject self = (DelegateObject)GetManagedObject(pytype); - CLRObject o = GetManagedObject(ob) as CLRObject; - - if (o == null) { - return Exceptions.RaiseTypeError("invalid argument"); - } - - Delegate d = o.inst as Delegate; - - if (d == null) { - return Exceptions.RaiseTypeError("invalid argument"); - } - return self.binder.Invoke(ob, args, kw); - } - - - //==================================================================== - // Implements __cmp__ for reflected delegate types. - //==================================================================== - - public static new int tp_compare(IntPtr ob, IntPtr other) { - Delegate d1 = GetTrueDelegate(ob); - Delegate d2 = GetTrueDelegate(other); - if (d1 == d2) { - return 0; - } - return -1; - } - - - } - - -} diff --git a/Pythonnet.Runtime/eventbinding.cs b/Pythonnet.Runtime/eventbinding.cs deleted file mode 100644 index 6135c1d68e..0000000000 --- a/Pythonnet.Runtime/eventbinding.cs +++ /dev/null @@ -1,132 +0,0 @@ -// ========================================================================== -// This software is subject to the provisions of the Zope Public License, -// Version 2.0 (ZPL). A copy of the ZPL should accompany this distribution. -// THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED -// WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -// WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS -// FOR A PARTICULAR PURPOSE. -// ========================================================================== - -using System; - -namespace Python.Runtime { - - //======================================================================== - // Implements a Python event binding type, similar to a method binding. - //======================================================================== - - internal class EventBinding : ExtensionType { - - EventObject e; - IntPtr target; - - public EventBinding(EventObject e, IntPtr target) : base() { - Runtime.Incref(target); - this.target = target; - this.e = e; - } - - - //==================================================================== - // EventBinding += operator implementation. - //==================================================================== - - public static IntPtr nb_inplace_add(IntPtr ob, IntPtr arg) { - EventBinding self = (EventBinding)GetManagedObject(ob); - - if (Runtime.PyCallable_Check(arg) < 1) { - Exceptions.SetError(Exceptions.TypeError, - "event handlers must be callable" - ); - return IntPtr.Zero; - } - - if(!self.e.AddEventHandler(self.target, arg)) { - return IntPtr.Zero; - } - - Runtime.Incref(self.pyHandle); - return self.pyHandle; - } - - - //==================================================================== - // EventBinding -= operator implementation. - //==================================================================== - - public static IntPtr nb_inplace_subtract(IntPtr ob, IntPtr arg) { - EventBinding self = (EventBinding)GetManagedObject(ob); - - if (Runtime.PyCallable_Check(arg) < 1) { - Exceptions.SetError(Exceptions.TypeError, - "invalid event handler" - ); - return IntPtr.Zero; - } - - if (!self.e.RemoveEventHandler(self.target, arg)) { - return IntPtr.Zero; - } - - Runtime.Incref(self.pyHandle); - return self.pyHandle; - } - - - //==================================================================== - // EventBinding __hash__ implementation. - //==================================================================== - - public static IntPtr tp_hash(IntPtr ob) { - EventBinding self = (EventBinding)GetManagedObject(ob); - long x = 0; - long y = 0; - - if (self.target != IntPtr.Zero) { - x = Runtime.PyObject_Hash(self.target).ToInt64(); - if (x == -1) { - return new IntPtr(-1); - } - } - - y = Runtime.PyObject_Hash(self.e.pyHandle).ToInt64(); - if (y == -1) { - return new IntPtr(-1); - } - - x ^= y; - - if (x == -1) { - x = -1; - } - - return new IntPtr(x); - } - - - //==================================================================== - // EventBinding __repr__ implementation. - //==================================================================== - - public static IntPtr tp_repr(IntPtr ob) { - EventBinding self = (EventBinding)GetManagedObject(ob); - string type = (self.target == IntPtr.Zero) ? "unbound" : "bound"; - string s = String.Format("<{0} event '{1}'>", type, self.e.name); - return Runtime.PyString_FromString(s); - } - - - //==================================================================== - // EventBinding dealloc implementation. - //==================================================================== - - public static new void tp_dealloc(IntPtr ob) { - EventBinding self = (EventBinding)GetManagedObject(ob); - Runtime.Decref(self.target); - ExtensionType.FinalizeObject(self); - } - - } - - -} diff --git a/Pythonnet.Runtime/eventobject.cs b/Pythonnet.Runtime/eventobject.cs deleted file mode 100644 index 0e9122f492..0000000000 --- a/Pythonnet.Runtime/eventobject.cs +++ /dev/null @@ -1,230 +0,0 @@ -// ========================================================================== -// This software is subject to the provisions of the Zope Public License, -// Version 2.0 (ZPL). A copy of the ZPL should accompany this distribution. -// THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED -// WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -// WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS -// FOR A PARTICULAR PURPOSE. -// ========================================================================== - -using System; -using System.Collections; -using System.Reflection; - -namespace Python.Runtime { - - //======================================================================== - // Implements a Python descriptor type that provides access to CLR events. - //======================================================================== - - internal class EventObject : ExtensionType { - - internal string name; - internal EventBinding unbound; - internal EventInfo info; - internal Hashtable reg; - - public EventObject(EventInfo info) : base() { - this.name = info.Name; - this.info = info; - } - - - //==================================================================== - // Register a new Python object event handler with the event. - //==================================================================== - - internal bool AddEventHandler(IntPtr target, IntPtr handler) { - Object obj = null; - if (target != IntPtr.Zero) { - CLRObject co = (CLRObject)ManagedType.GetManagedObject(target); - obj = co.inst; - } - - // Create a true delegate instance of the appropriate type to - // wrap the Python handler. Note that wrapper delegate creation - // always succeeds, though calling the wrapper may fail. - - Type type = this.info.EventHandlerType; - Delegate d = PythonEngine.DelegateManager.GetDelegate(type, handler); - - // Now register the handler in a mapping from instance to pairs - // of (handler hash, delegate) so we can lookup to remove later. - // All this is done lazily to avoid overhead until an event is - // actually subscribed to by a Python event handler. - - if (reg == null) { - reg = new Hashtable(); - } - object key = (obj != null) ? obj : this.info.ReflectedType; - ArrayList list = reg[key] as ArrayList; - if (list == null) { - list = new ArrayList(); - reg[key] = list; - } - list.Add(new Handler(Runtime.PyObject_Hash(handler), d)); - - // Note that AddEventHandler helper only works for public events, - // so we have to get the underlying add method explicitly. - - object[] args = { d }; - MethodInfo mi = this.info.GetAddMethod(true); - mi.Invoke(obj, BindingFlags.Default, null, args, null); - - return true; - } - - - //==================================================================== - // Remove the given Python object event handler. - //==================================================================== - - internal bool RemoveEventHandler(IntPtr target, IntPtr handler) { - Object obj = null; - if (target != IntPtr.Zero) { - CLRObject co = (CLRObject)ManagedType.GetManagedObject(target); - obj = co.inst; - } - - IntPtr hash = Runtime.PyObject_Hash(handler); - if (Exceptions.ErrorOccurred() || (reg == null)) { - Exceptions.SetError(Exceptions.ValueError, - "unknown event handler" - ); - return false; - } - - object key = (obj != null) ? obj : this.info.ReflectedType; - ArrayList list = reg[key] as ArrayList; - - if (list == null) { - Exceptions.SetError(Exceptions.ValueError, - "unknown event handler" - ); - return false; - } - - object[] args = { null }; - MethodInfo mi = this.info.GetRemoveMethod(true); - - for (int i = 0; i < list.Count; i++) { - Handler item = (Handler)list[i]; - if (item.hash != hash) { - continue; - } - args[0] = item.del; - try { - mi.Invoke(obj, BindingFlags.Default, null, args, null); - } - catch { - continue; - } - list.RemoveAt(i); - return true; - } - - Exceptions.SetError(Exceptions.ValueError, - "unknown event handler" - ); - return false; - } - - - //==================================================================== - // Descriptor __get__ implementation. A getattr on an event returns - // a "bound" event that keeps a reference to the object instance. - //==================================================================== - - public static IntPtr tp_descr_get(IntPtr ds, IntPtr ob, IntPtr tp) { - EventObject self = GetManagedObject(ds) as EventObject; - EventBinding binding; - - if (self == null) { - return Exceptions.RaiseTypeError("invalid argument"); - } - - // If the event is accessed through its type (rather than via - // an instance) we return an 'unbound' EventBinding that will - // be cached for future accesses through the type. - - if (ob == IntPtr.Zero) { - if (self.unbound == null) { - self.unbound = new EventBinding(self, IntPtr.Zero); - } - binding = self.unbound; - Runtime.Incref(binding.pyHandle); - return binding.pyHandle; - } - - if (Runtime.PyObject_IsInstance(ob, tp) < 1) { - return Exceptions.RaiseTypeError("invalid argument"); - } - - binding = new EventBinding(self, ob); - return binding.pyHandle; - } - - - //==================================================================== - // Descriptor __set__ implementation. This actually never allows you - // to set anything; it exists solely to support the '+=' spelling of - // event handler registration. The reason is that given code like: - // 'ob.SomeEvent += method', Python will attempt to set the attribute - // SomeEvent on ob to the result of the '+=' operation. - //==================================================================== - - public static new int tp_descr_set(IntPtr ds, IntPtr ob, IntPtr val) { - EventBinding e = GetManagedObject(val) as EventBinding; - - if (e != null) { - return 0; - } - - string message = "cannot set event attributes"; - Exceptions.RaiseTypeError(message); - return -1; - } - - - //==================================================================== - // Descriptor __repr__ implementation. - //==================================================================== - - public static IntPtr tp_repr(IntPtr ob) { - EventObject self = (EventObject)GetManagedObject(ob); - string s = String.Format("", self.name); - return Runtime.PyString_FromString(s); - } - - - //==================================================================== - // Descriptor dealloc implementation. - //==================================================================== - - public static new void tp_dealloc(IntPtr ob) { - EventObject self = (EventObject)GetManagedObject(ob); - if (self.unbound != null) { - Runtime.Decref(self.unbound.pyHandle); - } - ExtensionType.FinalizeObject(self); - } - - - } - - - - internal class Handler { - - public IntPtr hash; - public Delegate del; - - public Handler(IntPtr hash, Delegate d) { - this.hash = hash; - this.del = d; - } - - } - - -} diff --git a/Pythonnet.Runtime/exceptions.cs b/Pythonnet.Runtime/exceptions.cs deleted file mode 100644 index 2c70c38c19..0000000000 --- a/Pythonnet.Runtime/exceptions.cs +++ /dev/null @@ -1,638 +0,0 @@ -// ========================================================================== -// This software is subject to the provisions of the Zope Public License, -// Version 2.0 (ZPL). A copy of the ZPL should accompany this distribution. -// THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED -// WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -// WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS -// FOR A PARTICULAR PURPOSE. -// ========================================================================== - -using System; -using System.Reflection; -using System.Collections; -using System.Runtime.InteropServices; - - -namespace Python.Runtime { - - /// - /// Base class for Python types that reflect managed exceptions based on - /// System.Exception - /// - /// - /// The Python wrapper for managed exceptions LIES about its inheritance - /// tree. Although the real System.Exception is a subclass of - /// System.Object the Python type for System.Exception does NOT claim that - /// it subclasses System.Object. Instead TypeManager.CreateType() uses - /// Python's exception.Exception class as base class for System.Exception. - /// - internal class ExceptionClassObject : ClassObject { - - internal ExceptionClassObject(Type tp) : base(tp) { - } - -#if (PYTHON25 || PYTHON26 || PYTHON27) - internal static Exception ToException(IntPtr ob) { - CLRObject co = GetManagedObject(ob) as CLRObject; - if (co == null) { - return null; - } - Exception e = co.inst as Exception; - if (e == null) { - return null; - } - return e; - } - - //==================================================================== - // Exception __str__ implementation - //==================================================================== - - public new static IntPtr tp_str(IntPtr ob) { - Exception e = ToException(ob); - if (e == null) { - return Exceptions.RaiseTypeError("invalid object"); - } - - string message = String.Empty; - if (e.Message != String.Empty) { - message = e.Message; - } - if ((e.StackTrace != null) && (e.StackTrace != String.Empty)) { - message = message + "\n" + e.StackTrace; - } - return Runtime.PyUnicode_FromString(message); - } - - //==================================================================== - // Exception __repr__ implementation. - //==================================================================== - - public static IntPtr tp_repr(IntPtr ob) { - Exception e = ToException(ob); - if (e == null) { - return Exceptions.RaiseTypeError("invalid object"); - } - string name = e.GetType().Name; - string message; - if (e.Message != String.Empty) { - message = String.Format("{0}('{1}',)", name, e.Message); - } else { - message = String.Format("{0}()", name); - } - return Runtime.PyUnicode_FromString(message); - } - //==================================================================== - // Exceptions __getattribute__ implementation. - // handles Python's args and message attributes - //==================================================================== - - public static IntPtr tp_getattro(IntPtr ob, IntPtr key) - { - if (!Runtime.PyString_Check(key)) { - Exceptions.SetError(Exceptions.TypeError, "string expected"); - return IntPtr.Zero; - } - - string name = Runtime.GetManagedString(key); - if (name == "args") { - Exception e = ToException(ob); - IntPtr args; - if (e.Message != String.Empty) { - args = Runtime.PyTuple_New(1); - IntPtr msg = Runtime.PyUnicode_FromString(e.Message); - Runtime.PyTuple_SetItem(args, 0, msg); - } else { - args = Runtime.PyTuple_New(0); - } - return args; - } - - if (name == "message") { - return ExceptionClassObject.tp_str(ob); - } - - return Runtime.PyObject_GenericGetAttr(ob, key); - } -#endif // (PYTHON25 || PYTHON26 || PYTHON27) - } - - /// - /// Encapsulates the Python exception APIs. - /// - /// - /// Readability of the Exceptions class improvements as we look toward version 2.7 ... - /// - - public class Exceptions { - - internal static IntPtr warnings_module; - internal static IntPtr exceptions_module; - - private Exceptions() {} - - //=================================================================== - // Initialization performed on startup of the Python runtime. - //=================================================================== - - internal static void Initialize() { - exceptions_module = Runtime.PyImport_ImportModule("exceptions"); - Exceptions.ErrorCheck(exceptions_module); - warnings_module = Runtime.PyImport_ImportModule("warnings"); - Exceptions.ErrorCheck(warnings_module); - Type type = typeof(Exceptions); - foreach (FieldInfo fi in type.GetFields(BindingFlags.Public | - BindingFlags.Static)) { - IntPtr op = Runtime.PyObject_GetAttrString(exceptions_module, fi.Name); - if (op != IntPtr.Zero) { - fi.SetValue(type, op); - } - else { - fi.SetValue(type, IntPtr.Zero); - DebugUtil.Print("Unknown exception: " + fi.Name); - } - } - Runtime.PyErr_Clear(); - if (Runtime.wrap_exceptions) { - SetupExceptionHack(); - } - } - - - //=================================================================== - // Cleanup resources upon shutdown of the Python runtime. - //=================================================================== - - internal static void Shutdown() { - Type type = typeof(Exceptions); - foreach (FieldInfo fi in type.GetFields(BindingFlags.Public | - BindingFlags.Static)) { - IntPtr op = (IntPtr)fi.GetValue(type); - if (op != IntPtr.Zero) { - Runtime.Decref(op); - } - } - Runtime.Decref(exceptions_module); - Runtime.Decref(warnings_module); - } - - /// - /// Shortcut for (pointer == NULL) -> throw PythonException - /// - /// Pointer to a Python object - internal unsafe static void ErrorCheck(IntPtr pointer) { - if (pointer == IntPtr.Zero) { - throw new PythonException(); - } - } - - /// - /// Shortcut for (pointer == NULL or ErrorOccurred()) -> throw PythonException - /// - /// Shortcut for (pointer == NULL) -> throw PythonException - internal unsafe static void ErrorOccurredCheck(IntPtr pointer) { - if ((pointer == IntPtr.Zero) || Exceptions.ErrorOccurred()) { - throw new PythonException(); - } - } - - // Versions of CPython up to 2.4 do not allow exceptions to be - // new-style classes. To get around that restriction and provide - // a consistent user experience for programmers, we wrap managed - // exceptions in an old-style class that (through some dont-try- - // this-at-home hackery) delegates to the managed exception and - // obeys the conventions of both Python and managed exceptions. - - /// - /// Conditionally initialized variables! - /// - static IntPtr ns_exc; // new-style class for System.Exception - static IntPtr os_exc; // old-style class for System.Exception - static Hashtable cache; - - /// - /// the lines - /// // XXX - hack to raise a compatible old-style exception ;( - /// if (Runtime.wrap_exceptions) { - /// CallOneOfTheseMethods(); - /// - /// - internal static void SetupExceptionHack() { - ns_exc = ClassManager.GetClass(typeof(Exception)).pyHandle; - cache = new Hashtable(); - - string code = - "import exceptions\n" + - "class Exception(exceptions.Exception):\n" + - " _class = None\n" + - " _inner = None\n" + - " \n" + - " #@property\n" + - " def message(self):\n" + - " return self.Message\n" + - " message = property(message)\n" + - " \n" + - " def __init__(self, *args, **kw):\n" + - " inst = self.__class__._class(*args, **kw)\n" + - " self.__dict__['_inner'] = inst\n" + - " exceptions.Exception.__init__(self, *args, **kw)\n" + - "\n" + - " def __getattr__(self, name, _marker=[]):\n" + - " inner = self.__dict__['_inner']\n" + - " v = getattr(inner, name, _marker)\n" + - " if v is not _marker:\n" + - " return v\n" + - " v = self.__dict__.get(name, _marker)\n" + - " if v is not _marker:\n" + - " return v\n" + - " raise AttributeError(name)\n" + - "\n" + - " def __setattr__(self, name, value):\n" + - " inner = self.__dict__['_inner']\n" + - " setattr(inner, name, value)\n" + - "\n" + - " def __str__(self):\n" + - " inner = self.__dict__.get('_inner')\n" + - " msg = getattr(inner, 'Message', '')\n" + - " st = getattr(inner, 'StackTrace', '')\n" + - " st = st and '\\n' + st or ''\n" + - " return msg + st\n" + - " \n" + - " def __repr__(self):\n" + - " inner = self.__dict__.get('_inner')\n" + - " msg = getattr(inner, 'Message', '')\n" + - " name = self.__class__.__name__\n" + - " return '%s(\\'%s\\',)' % (name, msg) \n" + - "\n"; - - IntPtr dict = Runtime.PyDict_New(); - - IntPtr builtins = Runtime.PyEval_GetBuiltins(); - Runtime.PyDict_SetItemString(dict, "__builtins__", builtins); - - IntPtr namestr = Runtime.PyString_FromString("System"); - Runtime.PyDict_SetItemString(dict, "__name__", namestr); - Runtime.Decref(namestr); - - Runtime.PyDict_SetItemString(dict, "__file__", Runtime.PyNone); - Runtime.PyDict_SetItemString(dict, "__doc__", Runtime.PyNone); - - IntPtr flag = Runtime.Py_file_input; - IntPtr result = Runtime.PyRun_String(code, flag, dict, dict); - Exceptions.ErrorCheck(result); - Runtime.Decref(result); - - os_exc = Runtime.PyDict_GetItemString(dict, "Exception"); - Runtime.PyObject_SetAttrString(os_exc, "_class", ns_exc); - Runtime.PyErr_Clear(); - } - - - internal static IntPtr GenerateExceptionClass(IntPtr real) { - if (real == ns_exc) { - return os_exc; - } - - IntPtr nbases = Runtime.PyObject_GetAttrString(real, "__bases__"); - if (Runtime.PyTuple_Size(nbases) != 1) { - throw new SystemException("Invalid __bases__"); - } - IntPtr nsbase = Runtime.PyTuple_GetItem(nbases, 0); - Runtime.Decref(nbases); - - IntPtr osbase = GetExceptionClassWrapper(nsbase); - IntPtr baselist = Runtime.PyTuple_New(1); - Runtime.Incref(osbase); - Runtime.PyTuple_SetItem(baselist, 0, osbase); - IntPtr name = Runtime.PyObject_GetAttrString(real, "__name__"); - - IntPtr dict = Runtime.PyDict_New(); - IntPtr mod = Runtime.PyObject_GetAttrString(real, "__module__"); - Runtime.PyDict_SetItemString(dict, "__module__", mod); - Runtime.Decref(mod); - - IntPtr subc = Runtime.PyClass_New(baselist, dict, name); - Runtime.Decref(baselist); - Runtime.Decref(dict); - Runtime.Decref(name); - - Runtime.PyObject_SetAttrString(subc, "_class", real); - return subc; - } - - internal static IntPtr GetExceptionClassWrapper(IntPtr real) { - // Given the pointer to a new-style class representing a managed - // exception, return an appropriate old-style class wrapper that - // maintains all of the expectations and delegates to the wrapped - // class. - object ob = cache[real]; - if (ob == null) { - IntPtr op = GenerateExceptionClass(real); - cache[real] = op; - return op; - } - return (IntPtr)ob; - } - - internal static IntPtr GetExceptionInstanceWrapper(IntPtr real) { - // Given the pointer to a new-style class instance representing a - // managed exception, return an appropriate old-style class - // wrapper instance that delegates to the wrapped instance. - IntPtr tp = Runtime.PyObject_TYPE(real); - if (Runtime.PyObject_TYPE(tp) == Runtime.PyInstanceType) { - return real; - } - // Get / generate a class wrapper, instantiate it and set its - // _inner attribute to the real new-style exception instance. - IntPtr ct = GetExceptionClassWrapper(tp); - Exceptions.ErrorCheck(ct); - IntPtr op = Runtime.PyInstance_NewRaw(ct, IntPtr.Zero); - Exceptions.ErrorCheck(op); - IntPtr d = Runtime.PyObject_GetAttrString(op, "__dict__"); - Exceptions.ErrorCheck(d); - Runtime.PyDict_SetItemString(d, "_inner", real); - Runtime.Decref(d); - return op; - } - - internal static IntPtr UnwrapExceptionClass(IntPtr op) { - // In some cases its necessary to recognize an exception *class*, - // and obtain the inner (wrapped) exception class. This method - // returns the inner class if found, or a null pointer. - - IntPtr d = Runtime.PyObject_GetAttrString(op, "__dict__"); - if (d == IntPtr.Zero) { - Exceptions.Clear(); - return IntPtr.Zero; - } - IntPtr c = Runtime.PyDict_GetItemString(d, "_class"); - Runtime.Decref(d); - if (c == IntPtr.Zero) { - Exceptions.Clear(); - } - return c; - } - - /// - /// GetException Method - /// - /// - /// - /// Retrieve Python exception information as a PythonException - /// instance. The properties of the PythonException may be used - /// to access the exception type, value and traceback info. - /// - - public static PythonException GetException() { - return null; - } - - /// - /// ExceptionMatches Method - /// - /// - /// - /// Returns true if the current Python exception matches the given - /// Python object. This is a wrapper for PyErr_ExceptionMatches. - /// - - public static bool ExceptionMatches(IntPtr ob) { - return Runtime.PyErr_ExceptionMatches(ob) != 0; - } - - /// - /// ExceptionMatches Method - /// - /// - /// - /// Returns true if the given Python exception matches the given - /// Python object. This is a wrapper for PyErr_GivenExceptionMatches. - /// - - public static bool ExceptionMatches(IntPtr exc, IntPtr ob) { - int i = Runtime.PyErr_GivenExceptionMatches(exc, ob); - return (i != 0); - } - - /// - /// SetError Method - /// - /// - /// - /// Sets the current Python exception given a native string. - /// This is a wrapper for the Python PyErr_SetString call. - /// - - public static void SetError(IntPtr ob, string value) { - Runtime.PyErr_SetString(ob, value); - } - - /// - /// SetError Method - /// - /// - /// - /// Sets the current Python exception given a Python object. - /// This is a wrapper for the Python PyErr_SetObject call. - /// - - public static void SetError(IntPtr ob, IntPtr value) { - Runtime.PyErr_SetObject(ob, value); - } - - /// - /// SetError Method - /// - /// - /// - /// Sets the current Python exception given a CLR exception - /// object. The CLR exception instance is wrapped as a Python - /// object, allowing it to be handled naturally from Python. - /// - - public static void SetError(Exception e) { - - // Because delegates allow arbitrary nestings of Python calling - // managed calling Python calling... etc. it is possible that we - // might get a managed exception raised that is a wrapper for a - // Python exception. In that case we'd rather have the real thing. - - PythonException pe = e as PythonException; - if (pe != null) { - Runtime.PyErr_SetObject(pe.PyType, pe.PyValue); - return; - } - - IntPtr op = CLRObject.GetInstHandle(e); - - // XXX - hack to raise a compatible old-style exception ;( - if (Runtime.wrap_exceptions) { - op = GetExceptionInstanceWrapper(op); - } - IntPtr etype = Runtime.PyObject_GetAttrString(op, "__class__"); - Runtime.PyErr_SetObject(etype, op); - Runtime.Decref(etype); - Runtime.Decref(op); - } - - /// - /// ErrorOccurred Method - /// - /// - /// - /// Returns true if an exception occurred in the Python runtime. - /// This is a wrapper for the Python PyErr_Occurred call. - /// - - public static bool ErrorOccurred() { - return Runtime.PyErr_Occurred() != 0; - } - - /// - /// Clear Method - /// - /// - /// - /// Clear any exception that has been set in the Python runtime. - /// - - public static void Clear() { - Runtime.PyErr_Clear(); - } - - //==================================================================== - // helper methods for raising warnings - //==================================================================== - - /// - /// Alias for Python's warnings.warn() function. - /// - public static void warn(string message, IntPtr exception, int stacklevel) - { - if ((exception == IntPtr.Zero) || - (Runtime.PyObject_IsSubclass(exception, Exceptions.Warning) != 1)) { - Exceptions.RaiseTypeError("Invalid exception"); - } - - Runtime.Incref(warnings_module); - IntPtr warn = Runtime.PyObject_GetAttrString(warnings_module, "warn"); - Runtime.Decref(warnings_module); - Exceptions.ErrorCheck(warn); - - IntPtr args = Runtime.PyTuple_New(3); - IntPtr msg = Runtime.PyString_FromString(message); - Runtime.Incref(exception); // PyTuple_SetItem steals a reference - IntPtr level = Runtime.PyInt_FromInt32(stacklevel); - Runtime.PyTuple_SetItem(args, 0, msg); - Runtime.PyTuple_SetItem(args, 1, exception); - Runtime.PyTuple_SetItem(args, 2, level); - - IntPtr result = Runtime.PyObject_CallObject(warn, args); - Exceptions.ErrorCheck(result); - - Runtime.Decref(warn); - Runtime.Decref(result); - Runtime.Decref(args); - } - - public static void warn(string message, IntPtr exception) - { - warn(message, exception, 1); - } - - public static void deprecation(string message, int stacklevel) - { - warn(message, Exceptions.DeprecationWarning, stacklevel); - } - - public static void deprecation(string message) - { - deprecation(message, 1); - } - - //==================================================================== - // Internal helper methods for common error handling scenarios. - //==================================================================== - - internal static IntPtr RaiseTypeError(string message) { - Exceptions.SetError(Exceptions.TypeError, message); - return IntPtr.Zero; - } - - // 2010-11-16: Arranged in python (2.6 & 2.7) source header file order - /* Predefined exceptions are - puplic static variables on the Exceptions class filled in from - the python class using reflection in Initialize() looked up by - name, not posistion. */ -#if (PYTHON25 || PYTHON26 || PYTHON27) - public static IntPtr BaseException; -#endif - public static IntPtr Exception; - public static IntPtr StopIteration; -#if (PYTHON25 || PYTHON26 || PYTHON27) - public static IntPtr GeneratorExit; -#endif - public static IntPtr StandardError; - public static IntPtr ArithmeticError; - public static IntPtr LookupError; - - public static IntPtr AssertionError; - public static IntPtr AttributeError; - public static IntPtr EOFError; - public static IntPtr FloatingPointError; - public static IntPtr EnvironmentError; - public static IntPtr IOError; - public static IntPtr OSError; - public static IntPtr ImportError; - public static IntPtr IndexError; - public static IntPtr KeyError; - public static IntPtr KeyboardInterrupt; - public static IntPtr MemoryError; - public static IntPtr NameError; - public static IntPtr OverflowError; - public static IntPtr RuntimeError; - public static IntPtr NotImplementedError; - public static IntPtr SyntaxError; - public static IntPtr IndentationError; - public static IntPtr TabError; - public static IntPtr ReferenceError; - public static IntPtr SystemError; - public static IntPtr SystemExit; - public static IntPtr TypeError; - public static IntPtr UnboundLocalError; - public static IntPtr UnicodeError; - public static IntPtr UnicodeEncodeError; - public static IntPtr UnicodeDecodeError; - public static IntPtr UnicodeTranslateError; - public static IntPtr ValueError; - public static IntPtr ZeroDivisionError; -//#ifdef MS_WINDOWS - //public static IntPtr WindowsError; -//#endif -//#ifdef __VMS - //public static IntPtr VMSError; -//#endif - - //PyAPI_DATA(PyObject *) PyExc_BufferError; - - //PyAPI_DATA(PyObject *) PyExc_MemoryErrorInst; - //PyAPI_DATA(PyObject *) PyExc_RecursionErrorInst; - - - /* Predefined warning categories */ - public static IntPtr Warning; - public static IntPtr UserWarning; - public static IntPtr DeprecationWarning; - public static IntPtr PendingDeprecationWarning; - public static IntPtr SyntaxWarning; - public static IntPtr RuntimeWarning; - public static IntPtr FutureWarning; -#if (PYTHON25 || PYTHON26 || PYTHON27) - public static IntPtr ImportWarning; - public static IntPtr UnicodeWarning; - //PyAPI_DATA(PyObject *) PyExc_BytesWarning; -#endif - } - - -} diff --git a/Pythonnet.Runtime/extensiontype.cs b/Pythonnet.Runtime/extensiontype.cs deleted file mode 100644 index b0499bb0ae..0000000000 --- a/Pythonnet.Runtime/extensiontype.cs +++ /dev/null @@ -1,129 +0,0 @@ -// ========================================================================== -// This software is subject to the provisions of the Zope Public License, -// Version 2.0 (ZPL). A copy of the ZPL should accompany this distribution. -// THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED -// WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -// WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS -// FOR A PARTICULAR PURPOSE. -// ========================================================================== - -using System; -using System.Runtime.InteropServices; -using System.Collections; -using System.Reflection; - -namespace Python.Runtime { - - /// - /// Base class for extensions whose instances *share* a single Python - /// type object, such as the types that represent CLR methods, fields, - /// etc. Instances implemented by this class do not support subtyping. - /// - - internal abstract class ExtensionType : ManagedType { - - public ExtensionType() : base() { - - // Create a new PyObject whose type is a generated type that is - // implemented by the particuar concrete ExtensionType subclass. - // The Python instance object is related to an instance of a - // particular concrete subclass with a hidden CLR gchandle. - - IntPtr tp = TypeManager.GetTypeHandle(this.GetType()); - -// int rc = (int)Marshal.ReadIntPtr(tp, TypeOffset.ob_refcnt); -// if (rc > 1050) { -// DebugUtil.Print("tp is: ", tp); -// DebugUtil.DumpType(tp); -// } - - IntPtr py = Runtime.PyType_GenericAlloc(tp, 0); - - GCHandle gc = GCHandle.Alloc(this); - Marshal.WriteIntPtr(py, ObjectOffset.magic(), (IntPtr)gc); - - // We have to support gc because the type machinery makes it very - // hard not to - but we really don't have a need for it in most - // concrete extension types, so untrack the object to save calls - // from Python into the managed runtime that are pure overhead. - - Runtime.PyObject_GC_UnTrack(py); - - this.tpHandle = tp; - this.pyHandle = py; - this.gcHandle = gc; - } - - - //==================================================================== - // Common finalization code to support custom tp_deallocs. - //==================================================================== - - public static void FinalizeObject(ManagedType self) { - Runtime.PyObject_GC_Del(self.pyHandle); - Runtime.Decref(self.tpHandle); - self.gcHandle.Free(); - } - - - //==================================================================== - // Type __setattr__ implementation. - //==================================================================== - - public static int tp_setattro(IntPtr ob, IntPtr key, IntPtr val) { - string message = "type does not support setting attributes"; - if (val == IntPtr.Zero) { - message = "readonly attribute"; - } - Exceptions.SetError(Exceptions.TypeError, message); - return -1; - } - - - //==================================================================== - // Default __set__ implementation - this prevents descriptor instances - // being silently replaced in a type __dict__ by default __setattr__. - //==================================================================== - - public static int tp_descr_set(IntPtr ds, IntPtr ob, IntPtr val) { - string message = "attribute is read-only"; - Exceptions.SetError(Exceptions.AttributeError, message); - return -1; - } - - - //==================================================================== - // Required Python GC support. - //==================================================================== - - public static int tp_traverse(IntPtr ob, IntPtr func, IntPtr args) { - return 0; - } - - - public static int tp_clear(IntPtr ob) { - return 0; - } - - - public static int tp_is_gc(IntPtr type) { - return 1; - } - - - //==================================================================== - // Default dealloc implementation. - //==================================================================== - - public static void tp_dealloc(IntPtr ob) { - // Clean up a Python instance of this extension type. This - // frees the allocated Python object and decrefs the type. - ManagedType self = GetManagedObject(ob); - FinalizeObject(self); - } - - - } - - -} diff --git a/Pythonnet.Runtime/fieldobject.cs b/Pythonnet.Runtime/fieldobject.cs deleted file mode 100644 index ee9d3392a5..0000000000 --- a/Pythonnet.Runtime/fieldobject.cs +++ /dev/null @@ -1,150 +0,0 @@ -// ========================================================================== -// This software is subject to the provisions of the Zope Public License, -// Version 2.0 (ZPL). A copy of the ZPL should accompany this distribution. -// THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED -// WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -// WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS -// FOR A PARTICULAR PURPOSE. -// ========================================================================== - -using System; -using System.Collections; -using System.Reflection; -using System.Runtime.InteropServices; - -namespace Python.Runtime { - - //======================================================================== - // Implements a Python descriptor type that provides access to CLR fields. - //======================================================================== - - internal class FieldObject : ExtensionType { - - FieldInfo info; - - public FieldObject(FieldInfo info) : base() { - this.info = info; - } - - //==================================================================== - // Descriptor __get__ implementation. This method returns the - // value of the field on the given object. The returned value - // is converted to an appropriately typed Python object. - //==================================================================== - - public static IntPtr tp_descr_get(IntPtr ds, IntPtr ob, IntPtr tp) { - FieldObject self = (FieldObject)GetManagedObject(ds); - Object result; - - if (self == null) { - return IntPtr.Zero; - } - - FieldInfo info = self.info; - - if ((ob == IntPtr.Zero) || (ob == Runtime.PyNone)) { - if (!info.IsStatic) { - Exceptions.SetError(Exceptions.TypeError, - "instance attribute must be accessed " + - "through a class instance" - ); - return IntPtr.Zero; - } - try { - result = info.GetValue(null); - return Converter.ToPython(result, info.FieldType); - } - catch(Exception e) { - Exceptions.SetError(Exceptions.TypeError, e.Message); - return IntPtr.Zero; - } - } - - try { - CLRObject co = (CLRObject)GetManagedObject(ob); - result = info.GetValue(co.inst); - return Converter.ToPython(result, info.FieldType); - } - catch(Exception e) { - Exceptions.SetError(Exceptions.TypeError, e.Message); - return IntPtr.Zero; - } - } - - //==================================================================== - // Descriptor __set__ implementation. This method sets the value of - // a field based on the given Python value. The Python value must be - // convertible to the type of the field. - //==================================================================== - - public static new int tp_descr_set(IntPtr ds, IntPtr ob, IntPtr val) { - FieldObject self = (FieldObject)GetManagedObject(ds); - Object newval; - - if (self == null) { - return -1; - } - - if (val == IntPtr.Zero) { - Exceptions.SetError(Exceptions.TypeError, - "cannot delete field" - ); - return -1; - } - - FieldInfo info = self.info; - - if (info.IsLiteral || info.IsInitOnly) { - Exceptions.SetError(Exceptions.TypeError, - "field is read-only" - ); - return -1; - } - - bool is_static = info.IsStatic; - - if ((ob == IntPtr.Zero) || (ob == Runtime.PyNone)) { - if (!is_static) { - Exceptions.SetError(Exceptions.TypeError, - "instance attribute must be set " + - "through a class instance" - ); - return -1; - } - } - - if (!Converter.ToManaged(val, info.FieldType, out newval, - true)) { - return -1; - } - - try { - if (!is_static) { - CLRObject co = (CLRObject)GetManagedObject(ob); - info.SetValue(co.inst, newval); - } - else { - info.SetValue(null, newval); - } - return 0; - } - catch(Exception e) { - Exceptions.SetError(Exceptions.TypeError, e.Message); - return -1; - } - } - - //==================================================================== - // Descriptor __repr__ implementation. - //==================================================================== - - public static IntPtr tp_repr(IntPtr ob) { - FieldObject self = (FieldObject)GetManagedObject(ob); - string s = String.Format("", self.info.Name); - return Runtime.PyString_FromStringAndSize(s, s.Length); - } - - } - - -} diff --git a/Pythonnet.Runtime/generictype.cs b/Pythonnet.Runtime/generictype.cs deleted file mode 100644 index 082bc768ce..0000000000 --- a/Pythonnet.Runtime/generictype.cs +++ /dev/null @@ -1,100 +0,0 @@ -// ========================================================================== -// This software is subject to the provisions of the Zope Public License, -// Version 2.0 (ZPL). A copy of the ZPL should accompany this distribution. -// THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED -// WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -// WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS -// FOR A PARTICULAR PURPOSE. -// ========================================================================== - -using System; -using System.Reflection; - -namespace Python.Runtime { - - /// - /// Implements reflected generic types. Note that the Python behavior - /// is the same for both generic type definitions and constructed open - /// generic types. Both are essentially factories for creating closed - /// types based on the required generic type parameters. - /// - - internal class GenericType : ClassBase { - - internal GenericType(Type tp) : base(tp) {} - - //==================================================================== - // Implements __new__ for reflected generic types. - //==================================================================== - - public static IntPtr tp_new(IntPtr tp, IntPtr args, IntPtr kw) { - Exceptions.SetError(Exceptions.TypeError, - "cannot instantiate an open generic type" - ); - return IntPtr.Zero; - } - - - //==================================================================== - // Implements __call__ for reflected generic types. - //==================================================================== - - public static IntPtr tp_call(IntPtr ob, IntPtr args, IntPtr kw) { - Exceptions.SetError(Exceptions.TypeError, - "object is not callable"); - return IntPtr.Zero; - } - - //==================================================================== - // Implements subscript syntax for reflected generic types. A closed - // type is created by binding the generic type via subscript syntax: - // inst = List[str]() - //==================================================================== - - public override IntPtr type_subscript(IntPtr idx) { - Type[] types = Runtime.PythonArgsToTypeArray(idx); - if (types == null) { - return Exceptions.RaiseTypeError("type(s) expected"); - } - if (!this.type.IsGenericTypeDefinition) { - return Exceptions.RaiseTypeError( - "type is not a generic type definition" - ); - } - - // This is a little tricky, because an instance of GenericType - // may represent either a specific generic type, or act as an - // alias for one or more generic types with the same base name. - - if (this.type.ContainsGenericParameters) { - Type[] args = this.type.GetGenericArguments(); - Type target = null; - - if (args.Length == types.Length) { - target = this.type; - } - else { - foreach (Type t in - GenericUtil.GenericsForType(this.type)) { - if (t.GetGenericArguments().Length == types.Length) { - target = t; - break; - } - } - } - - if (target != null) { - Type t = target.MakeGenericType(types); - ManagedType c = (ManagedType)ClassManager.GetClass(t); - Runtime.Incref(c.pyHandle); - return c.pyHandle; - } - return Exceptions.RaiseTypeError("no type matches params"); - } - - return Exceptions.RaiseTypeError("unsubscriptable object"); - } - - } - -} diff --git a/Pythonnet.Runtime/genericutil.cs b/Pythonnet.Runtime/genericutil.cs deleted file mode 100644 index 92751add76..0000000000 --- a/Pythonnet.Runtime/genericutil.cs +++ /dev/null @@ -1,141 +0,0 @@ -// ========================================================================== -// This software is subject to the provisions of the Zope Public License, -// Version 2.0 (ZPL). A copy of the ZPL should accompany this distribution. -// THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED -// WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -// WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS -// FOR A PARTICULAR PURPOSE. -// ========================================================================== - -using System; -using System.Runtime.InteropServices; -using System.Collections.Generic; -using System.Collections; -using System.Reflection; -using System.Security; - -namespace Python.Runtime { - - /// - /// This class is responsible for efficiently maintaining the bits - /// of information we need to support aliases with 'nice names'. - /// - - internal class GenericUtil { - - static Dictionary>> mapping; - - private GenericUtil() {} - - static GenericUtil() { - mapping = new - Dictionary>>(); - } - - //==================================================================== - // Register a generic type that appears in a given namespace. - //==================================================================== - - internal static void Register(Type t) { - Dictionary> nsmap = null; - //for Anonymous type, there is no namespace - if (t.Namespace == null) return; - - mapping.TryGetValue(t.Namespace, out nsmap); - if (nsmap == null) { - nsmap = new Dictionary>(); - mapping[t.Namespace] = nsmap; - } - string basename = t.Name; - int tick = basename.IndexOf("`"); - if (tick > -1) { - basename = basename.Substring(0, tick); - } - List gnames = null; - nsmap.TryGetValue(basename, out gnames); - if (gnames == null) { - gnames = new List(); - nsmap[basename] = gnames; - } - gnames.Add(t.Name); - } - - //==================================================================== - // xxx - //==================================================================== - - public static List GetGenericBaseNames(string ns) { - Dictionary> nsmap = null; - mapping.TryGetValue(ns, out nsmap); - if (nsmap == null) { - return null; - } - List names = new List(); - foreach (string key in nsmap.Keys) { - names.Add(key); - } - return names; - } - - //==================================================================== - // xxx - //==================================================================== - - public static List GenericsForType(Type t) { - Dictionary> nsmap = null; - mapping.TryGetValue(t.Namespace, out nsmap); - if (nsmap == null) { - return null; - } - - string basename = t.Name; - int tick = basename.IndexOf("`"); - if (tick > -1) { - basename = basename.Substring(0, tick); - } - - List names = null; - nsmap.TryGetValue(basename, out names); - if (names == null) { - return null; - } - - List result = new List(); - foreach (string name in names) { - string qname = t.Namespace + "." + name; - Type o = AssemblyManager.LookupType(qname); - if (o != null) { - result.Add(o); - } - } - - return result; - } - - //==================================================================== - // xxx - //==================================================================== - - public static string GenericNameForBaseName(string ns, string name) { - Dictionary> nsmap = null; - mapping.TryGetValue(ns, out nsmap); - if (nsmap == null) { - return null; - } - List gnames = null; - nsmap.TryGetValue(name, out gnames); - if (gnames == null) { - return null; - } - if (gnames.Count > 0) { - return gnames[0]; - } - return null; - } - - - } - - - -} diff --git a/Pythonnet.Runtime/importhook.cs b/Pythonnet.Runtime/importhook.cs deleted file mode 100644 index 9d618b60dd..0000000000 --- a/Pythonnet.Runtime/importhook.cs +++ /dev/null @@ -1,243 +0,0 @@ -// ========================================================================== -// This software is subject to the provisions of the Zope Public License, -// Version 2.0 (ZPL). A copy of the ZPL should accompany this distribution. -// THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED -// WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -// WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS -// FOR A PARTICULAR PURPOSE. -// ========================================================================== - -using System; -using System.Collections; -using System.Runtime.InteropServices; - -namespace Python.Runtime { - - //======================================================================== - // Implements the "import hook" used to integrate Python with the CLR. - //======================================================================== - - internal class ImportHook { - - static IntPtr py_import; - static CLRModule root; - static MethodWrapper hook; - - //=================================================================== - // Initialization performed on startup of the Python runtime. - //=================================================================== - - internal static void Initialize() { - - // Initialize the Python <--> CLR module hook. We replace the - // built-in Python __import__ with our own. This isn't ideal, - // but it provides the most "Pythonic" way of dealing with CLR - // modules (Python doesn't provide a way to emulate packages). - - IntPtr dict = Runtime.PyImport_GetModuleDict(); - IntPtr mod = Runtime.PyDict_GetItemString(dict, "__builtin__"); - py_import = Runtime.PyObject_GetAttrString(mod, "__import__"); - - hook = new MethodWrapper(typeof(ImportHook), "__import__"); - Runtime.PyObject_SetAttrString(mod, "__import__", hook.ptr); - Runtime.Decref(hook.ptr); - - root = new CLRModule(); - Runtime.Incref(root.pyHandle); // we are using the module two times - Runtime.PyDict_SetItemString(dict, "CLR", root.pyHandle); - Runtime.PyDict_SetItemString(dict, "clr", root.pyHandle); - } - - - //=================================================================== - // Cleanup resources upon shutdown of the Python runtime. - //=================================================================== - - internal static void Shutdown() { - Runtime.Decref(root.pyHandle); - Runtime.Decref(root.pyHandle); - Runtime.Decref(py_import); - } - - - //=================================================================== - // The actual import hook that ties Python to the managed world. - //=================================================================== - - public static IntPtr __import__(IntPtr self, IntPtr args, IntPtr kw) { - - // Replacement for the builtin __import__. The original import - // hook is saved as this.py_import. This version handles CLR - // import and defers to the normal builtin for everything else. - - int num_args = Runtime.PyTuple_Size(args); - if (num_args < 1) { - return Exceptions.RaiseTypeError( - "__import__() takes at least 1 argument (0 given)" - ); - } - - // borrowed reference - IntPtr py_mod_name = Runtime.PyTuple_GetItem(args, 0); - if ((py_mod_name == IntPtr.Zero) || - (!Runtime.IsStringType(py_mod_name))) { - return Exceptions.RaiseTypeError("string expected"); - } - - // Check whether the import is of the form 'from x import y'. - // This determines whether we return the head or tail module. - - IntPtr fromList = IntPtr.Zero; - bool fromlist = false; - if (num_args >= 4) { - fromList = Runtime.PyTuple_GetItem(args, 3); - if ((fromList != IntPtr.Zero) && - (Runtime.PyObject_IsTrue(fromList) == 1)) { - fromlist = true; - } - } - - string mod_name = Runtime.GetManagedString(py_mod_name); - // Check these BEFORE the built-in import runs; may as well - // do the Incref()ed return here, since we've already found - // the module. - if (mod_name == "clr") { - root.InitializePreload(); - Runtime.Incref(root.pyHandle); - return root.pyHandle; - } - if (mod_name == "CLR") { - Exceptions.deprecation("The CLR module is deprecated. " + - "Please use 'clr'."); - root.InitializePreload(); - Runtime.Incref(root.pyHandle); - return root.pyHandle; - } - string realname = mod_name; - if (mod_name.StartsWith("CLR.")) { - realname = mod_name.Substring(4); - string msg = String.Format("Importing from the CLR.* namespace "+ - "is deprecated. Please import '{0}' directly.", realname); - Exceptions.deprecation(msg); - } - else { - // 2010-08-15: Always seemed smart to let python try first... - // This shaves off a few tenths of a second on test_module.py - // and works around a quirk where 'sys' is found by the - // LoadImplicit() deprecation logic. - // Turns out that the AssemblyManager.ResolveHandler() checks to see if any - // Assembly's FullName.ToLower().StartsWith(name.ToLower()), which makes very - // little sense to me. - IntPtr res = Runtime.PyObject_Call(py_import, args, kw); - if (res != IntPtr.Zero) { - // There was no error. - return res; - } - // There was an error - if (!Exceptions.ExceptionMatches(Exceptions.ImportError)) { - // and it was NOT an ImportError; bail out here. - return IntPtr.Zero; - } - // Otherwise, just clear the it. - Exceptions.Clear(); - } - - string[] names = realname.Split('.'); - - // Now we need to decide if the name refers to a CLR module, - // and may have to do an implicit load (for b/w compatibility) - // using the AssemblyManager. The assembly manager tries - // really hard not to use Python objects or APIs, because - // parts of it can run recursively and on strange threads. - // - // It does need an opportunity from time to time to check to - // see if sys.path has changed, in a context that is safe. Here - // we know we have the GIL, so we'll let it update if needed. - - AssemblyManager.UpdatePath(); - if (!AssemblyManager.IsValidNamespace(realname)) { - bool fromFile = false; - if (AssemblyManager.LoadImplicit(realname, out fromFile)) { - if (true == fromFile) { - string deprWarning = String.Format("\nThe module was found, but not in a referenced namespace.\n" + - "Implicit loading is deprecated. Please use clr.AddReference(\"{0}\").", realname); - Exceptions.deprecation(deprWarning); - } - } - else - { - // May be called when a module being imported imports a module. - // In particular, I've seen decimal import copy import org.python.core - return Runtime.PyObject_Call(py_import, args, kw); - } - } - - // See if sys.modules for this interpreter already has the - // requested module. If so, just return the exising module. - - IntPtr modules = Runtime.PyImport_GetModuleDict(); - IntPtr module = Runtime.PyDict_GetItem(modules, py_mod_name); - - if (module != IntPtr.Zero) { - if (fromlist) { - Runtime.Incref(module); - return module; - } - module = Runtime.PyDict_GetItemString(modules, names[0]); - Runtime.Incref(module); - return module; - } - Exceptions.Clear(); - - // Traverse the qualified module name to get the named module - // and place references in sys.modules as we go. Note that if - // we are running in interactive mode we pre-load the names in - // each module, which is often useful for introspection. If we - // are not interactive, we stick to just-in-time creation of - // objects at lookup time, which is much more efficient. - // NEW: The clr got a new module variable preload. You can - // enable preloading in a non-interactive python processing by - // setting clr.preload = True - - ModuleObject head = (mod_name == realname) ? null : root; - ModuleObject tail = root; - root.InitializePreload(); - - for (int i = 0; i < names.Length; i++) { - string name = names[i]; - ManagedType mt = tail.GetAttribute(name, true); - if (!(mt is ModuleObject)) { - string error = String.Format("No module named {0}", name); - Exceptions.SetError(Exceptions.ImportError, error); - return IntPtr.Zero; - } - if (head == null) { - head = (ModuleObject)mt; - } - tail = (ModuleObject) mt; - if (CLRModule.preload) { - tail.LoadNames(); - } - Runtime.PyDict_SetItemString(modules, tail.moduleName, - tail.pyHandle - ); - } - - ModuleObject mod = fromlist ? tail : head; - - if (fromlist && Runtime.PySequence_Size(fromList) == 1) { - IntPtr fp = Runtime.PySequence_GetItem(fromList, 0); - if ((!CLRModule.preload) && Runtime.GetManagedString(fp) == "*") { - mod.LoadNames(); - } - Runtime.Decref(fp); - } - - Runtime.Incref(mod.pyHandle); - return mod.pyHandle; - } - - } - - -} diff --git a/Pythonnet.Runtime/indexer.cs b/Pythonnet.Runtime/indexer.cs deleted file mode 100644 index 8118dc339b..0000000000 --- a/Pythonnet.Runtime/indexer.cs +++ /dev/null @@ -1,68 +0,0 @@ -// ========================================================================== -// This software is subject to the provisions of the Zope Public License, -// Version 2.0 (ZPL). A copy of the ZPL should accompany this distribution. -// THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED -// WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -// WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS -// FOR A PARTICULAR PURPOSE. -// ========================================================================== - -using System; -using System.Collections; -using System.Reflection; -using System.Security.Permissions; - -namespace Python.Runtime { - - //======================================================================== - // Bundles the information required to support an indexer property. - //======================================================================== - - internal class Indexer { - - public MethodBinder GetterBinder; - public MethodBinder SetterBinder; - - public Indexer() { - GetterBinder = new MethodBinder(); - SetterBinder = new MethodBinder(); - } - - - public bool CanGet { - get { - return GetterBinder.Count > 0; - } - } - - public bool CanSet { - get { - return SetterBinder.Count > 0; - } - } - - - public void AddProperty(PropertyInfo pi) { - MethodInfo getter = pi.GetGetMethod(true); - MethodInfo setter = pi.GetSetMethod(true); - if (getter != null) { - GetterBinder.AddMethod(getter); - } - if (setter != null) { - SetterBinder.AddMethod(setter); - } - } - - internal IntPtr GetItem(IntPtr inst, IntPtr args) { - return GetterBinder.Invoke(inst, args, IntPtr.Zero); - } - - - internal void SetItem(IntPtr inst, IntPtr args) { - SetterBinder.Invoke(inst, args, IntPtr.Zero); - } - - } - - -} diff --git a/Pythonnet.Runtime/interfaceobject.cs b/Pythonnet.Runtime/interfaceobject.cs deleted file mode 100644 index 7c2aead1fe..0000000000 --- a/Pythonnet.Runtime/interfaceobject.cs +++ /dev/null @@ -1,89 +0,0 @@ -// ========================================================================== -// This software is subject to the provisions of the Zope Public License, -// Version 2.0 (ZPL). A copy of the ZPL should accompany this distribution. -// THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED -// WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -// WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS -// FOR A PARTICULAR PURPOSE. -// ========================================================================== - -using System; -using System.Reflection; -using System.Runtime.InteropServices; - -namespace Python.Runtime { - - /// - /// Provides the implementation for reflected interface types. Managed - /// interfaces are represented in Python by actual Python type objects. - /// Each of those type objects is associated with an instance of this - /// class, which provides the implementation for the Python type. - /// - - internal class InterfaceObject : ClassBase { - - internal ConstructorInfo ctor; - - internal InterfaceObject(Type tp) : base(tp) { - CoClassAttribute coclass = (CoClassAttribute) - Attribute.GetCustomAttribute(tp, cc_attr); - if (coclass != null) { - ctor = coclass.CoClass.GetConstructor(Type.EmptyTypes); - } - } - - static Type cc_attr; - - static InterfaceObject() { - cc_attr = typeof(CoClassAttribute); - } - - //==================================================================== - // Implements __new__ for reflected interface types. - //==================================================================== - - public static IntPtr tp_new(IntPtr tp, IntPtr args, IntPtr kw) { - InterfaceObject self = (InterfaceObject)GetManagedObject(tp); - int nargs = Runtime.PyTuple_Size(args); - Type type = self.type; - Object obj; - - if (nargs == 1) { - IntPtr inst = Runtime.PyTuple_GetItem(args, 0); - CLRObject co = GetManagedObject(inst) as CLRObject; - - if ((co == null) || (!type.IsInstanceOfType(co.inst))) { - string msg = "object does not implement " + type.Name; - Exceptions.SetError(Exceptions.TypeError, msg); - return IntPtr.Zero; - } - - obj = co.inst; - } - - else if ((nargs == 0) && (self.ctor != null)) { - obj = self.ctor.Invoke(null); - - if (obj == null || !type.IsInstanceOfType(obj)) { - Exceptions.SetError(Exceptions.TypeError, - "CoClass default constructor failed" - ); - return IntPtr.Zero; - } - } - - else { - Exceptions.SetError(Exceptions.TypeError, - "interface takes exactly one argument" - ); - return IntPtr.Zero; - } - - return CLRObject.GetInstHandle(obj, self.pyHandle); - } - - - } - - -} diff --git a/Pythonnet.Runtime/interfaces.cs b/Pythonnet.Runtime/interfaces.cs deleted file mode 100644 index 484a9ad5d2..0000000000 --- a/Pythonnet.Runtime/interfaces.cs +++ /dev/null @@ -1,40 +0,0 @@ -// ========================================================================== -// This software is subject to the provisions of the Zope Public License, -// Version 2.0 (ZPL). A copy of the ZPL should accompany this distribution. -// THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED -// WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -// WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS -// FOR A PARTICULAR PURPOSE. -// ========================================================================== - -using System; -using System.Reflection; -using System.Runtime.InteropServices; - -namespace Python.Runtime { - - /// - /// xxx - /// - - internal interface IReflectedType { - string PythonTypeName(); - Type GetReflectedType(); - } - - internal interface IReflectedClass : IReflectedType { - bool IsException(); - } - - internal interface IReflectedInterface : IReflectedType { - - } - - internal interface IReflectedArray : IReflectedType { - } - - internal interface IReflectedGenericClass : IReflectedClass { - } - - -} diff --git a/Pythonnet.Runtime/interop.cs b/Pythonnet.Runtime/interop.cs deleted file mode 100644 index b88a3f5049..0000000000 --- a/Pythonnet.Runtime/interop.cs +++ /dev/null @@ -1,544 +0,0 @@ -// ========================================================================== -// This software is subject to the provisions of the Zope Public License, -// Version 2.0 (ZPL). A copy of the ZPL should accompany this distribution. -// THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED -// WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -// WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS -// FOR A PARTICULAR PURPOSE. -// ========================================================================== - -using System; -using System.Collections; -using System.Collections.Specialized; -using System.Runtime.InteropServices; -using System.Reflection; - -namespace Python.Runtime { - - //======================================================================= - // This file defines objects to support binary interop with the Python - // runtime. Generally, the definitions here need to be kept up to date - // when moving to new Python versions. - //======================================================================= - - [Serializable()] - [AttributeUsage(AttributeTargets.All)] - public class DocStringAttribute : Attribute { - public DocStringAttribute(string docStr) { - DocString = docStr; - } - public string DocString { - get { return docStr; } - set { docStr = value; } - } - private string docStr; - } - - [Serializable()] - [AttributeUsage(AttributeTargets.Method | AttributeTargets.Delegate)] - internal class PythonMethodAttribute : Attribute { - public PythonMethodAttribute() {} - } - - [Serializable()] - [AttributeUsage(AttributeTargets.Method | AttributeTargets.Delegate)] - internal class ModuleFunctionAttribute : Attribute { - public ModuleFunctionAttribute() {} - } - - [Serializable()] - [AttributeUsage(AttributeTargets.Method | AttributeTargets.Delegate)] - internal class ForbidPythonThreadsAttribute : Attribute { - public ForbidPythonThreadsAttribute() { } - } - - - [Serializable()] - [AttributeUsage(AttributeTargets.Property)] - internal class ModulePropertyAttribute : Attribute { - public ModulePropertyAttribute() {} - } - - - [StructLayout(LayoutKind.Sequential, CharSet=CharSet.Ansi)] - internal class ObjectOffset { - - static ObjectOffset() { - int size = IntPtr.Size; - int n = 0; // Py_TRACE_REFS add two pointers to PyObject_HEAD -#if (Py_DEBUG) - _ob_next = 0; - _ob_prev = 1 * size; - n = 2; -#endif - ob_refcnt = (n+0) * size; - ob_type = (n+1) * size; - ob_dict = (n+2) * size; - ob_data = (n+3) * size; - } - - public static int magic() { - return ob_data; - } - - public static int Size() { -#if (Py_DEBUG) - return 6 * IntPtr.Size; -#else - return 4 * IntPtr.Size; -#endif - } - -#if (Py_DEBUG) - public static int _ob_next; - public static int _ob_prev; -#endif - public static int ob_refcnt; - public static int ob_type; - public static int ob_dict; - public static int ob_data; - } - - - [StructLayout(LayoutKind.Sequential, CharSet=CharSet.Ansi)] - internal class TypeOffset { - - static TypeOffset() { - Type type = typeof(TypeOffset); - FieldInfo[] fi = type.GetFields(); - int size = IntPtr.Size; - for (int i = 0; i < fi.Length; i++) { - fi[i].SetValue(null, i * size); - } - } - - public static int magic() { - return ob_size; - } - -/* The *real* layout of a type object when allocated on the heap */ -//typedef struct _heaptypeobject { -#if (Py_DEBUG) // #ifdef Py_TRACE_REFS -/* _PyObject_HEAD_EXTRA defines pointers to support a doubly-linked list of all live heap objects. */ - public static int _ob_next = 0; - public static int _ob_prev = 0; -#endif -// PyObject_VAR_HEAD { -// PyObject_HEAD { - public static int ob_refcnt = 0; - public static int ob_type = 0; - // } - public static int ob_size = 0; /* Number of items in _VAR_iable part */ -// } - public static int tp_name = 0; /* For printing, in format "." */ - public static int tp_basicsize = 0; /* For allocation */ - public static int tp_itemsize = 0; - - /* Methods to implement standard operations */ - public static int tp_dealloc = 0; - public static int tp_print = 0; - public static int tp_getattr = 0; - public static int tp_setattr = 0; - public static int tp_compare = 0; - public static int tp_repr = 0; - - /* Method suites for standard classes */ - public static int tp_as_number = 0; - public static int tp_as_sequence = 0; - public static int tp_as_mapping = 0; - - /* More standard operations (here for binary compatibility) */ - public static int tp_hash = 0; - public static int tp_call = 0; - public static int tp_str = 0; - public static int tp_getattro = 0; - public static int tp_setattro = 0; - - /* Functions to access object as input/output buffer */ - public static int tp_as_buffer = 0; - - /* Flags to define presence of optional/expanded features */ - public static int tp_flags = 0; - - public static int tp_doc = 0; /* Documentation string */ - - /* Assigned meaning in release 2.0 */ - /* call function for all accessible objects */ - public static int tp_traverse = 0; - /* delete references to contained objects */ - public static int tp_clear = 0; - - /* Assigned meaning in release 2.1 */ - /* rich comparisons */ - public static int tp_richcompare = 0; - /* weak reference enabler */ - public static int tp_weaklistoffset = 0; - - /* Added in release 2.2 */ - /* Iterators */ - public static int tp_iter = 0; - public static int tp_iternext = 0; - /* Attribute descriptor and subclassing stuff */ - public static int tp_methods = 0; - public static int tp_members = 0; - public static int tp_getset = 0; - public static int tp_base = 0; - public static int tp_dict = 0; - public static int tp_descr_get = 0; - public static int tp_descr_set = 0; - public static int tp_dictoffset = 0; - public static int tp_init = 0; - public static int tp_alloc = 0; - public static int tp_new = 0; - public static int tp_free = 0; /* Low-level free-memory routine */ - public static int tp_is_gc = 0; /* For PyObject_IS_GC */ - public static int tp_bases = 0; - public static int tp_mro = 0; /* method resolution order */ - public static int tp_cache = 0; - public static int tp_subclasses = 0; - public static int tp_weaklist = 0; - public static int tp_del = 0; -#if (PYTHON26 || PYTHON27) - /* Type attribute cache version tag. Added in version 2.6 */ - public static int tp_version_tag; -#endif - // COUNT_ALLOCS adds some more stuff to PyTypeObject -#if (Py_COUNT_ALLOCS) - /* these must be last and never explicitly initialized */ - public static int tp_allocs = 0; - public static int tp_frees = 0; - public static int tp_maxalloc = 0; - public static int tp_prev = 0; - public static int tp_next = 0; -#endif -//} PyTypeObject; -//typedef struct { - public static int nb_add = 0; - public static int nb_subtract = 0; - public static int nb_multiply = 0; - public static int nb_divide = 0; - public static int nb_remainder = 0; - public static int nb_divmod = 0; - public static int nb_power = 0; - public static int nb_negative = 0; - public static int nb_positive = 0; - public static int nb_absolute = 0; - public static int nb_nonzero = 0; - public static int nb_invert = 0; - public static int nb_lshift = 0; - public static int nb_rshift = 0; - public static int nb_and = 0; - public static int nb_xor = 0; - public static int nb_or = 0; - public static int nb_coerce = 0; - public static int nb_int = 0; - public static int nb_long = 0; - public static int nb_float = 0; - public static int nb_oct = 0; - public static int nb_hex = 0; - /* Added in release 2.0 */ - public static int nb_inplace_add = 0; - public static int nb_inplace_subtract = 0; - public static int nb_inplace_multiply = 0; - public static int nb_inplace_divide = 0; - public static int nb_inplace_remainder = 0; - public static int nb_inplace_power = 0; - public static int nb_inplace_lshift = 0; - public static int nb_inplace_rshift = 0; - public static int nb_inplace_and = 0; - public static int nb_inplace_xor = 0; - public static int nb_inplace_or = 0; - /* Added in release 2.2 */ - /* The following require the Py_TPFLAGS_HAVE_CLASS flag */ - public static int nb_floor_divide = 0; - public static int nb_true_divide = 0; - public static int nb_inplace_floor_divide = 0; - public static int nb_inplace_true_divide = 0; -#if (PYTHON25 || PYTHON26 || PYTHON27) - /* Added in release 2.5 */ - public static int nb_index = 0; -#endif - //} PyNumberMethods; -//typedef struct { - public static int mp_length = 0; - public static int mp_subscript = 0; - public static int mp_ass_subscript = 0; -//} PyMappingMethods; -//typedef struct { - public static int sq_length = 0; - public static int sq_concat = 0; - public static int sq_repeat = 0; - public static int sq_item = 0; - public static int sq_slice = 0; - public static int sq_ass_item = 0; - public static int sq_ass_slice = 0; - public static int sq_contains = 0; - /* Added in release 2.0 */ - public static int sq_inplace_concat = 0; - public static int sq_inplace_repeat = 0; -//} PySequenceMethods; -//typedef struct { - public static int bf_getreadbuffer = 0; - public static int bf_getwritebuffer = 0; - public static int bf_getsegcount = 0; - public static int bf_getcharbuffer = 0; -#if (PYTHON26 || PYTHON27) - // This addition is not actually noted in the 2.6.5 object.h - public static int bf_getbuffer = 0; - public static int bf_releasebuffer = 0; -//} PyBufferProcs; -#endif - //PyObject *ht_name, *ht_slots; - public static int name = 0; - public static int slots = 0; - /* here are optional user slots, followed by the members. */ - public static int members = 0; - } - - /// - /// TypeFlags(): The actual bit values for the Type Flags stored - /// in a class. - /// Note that the two values reserved for stackless have been put - /// to good use as PythonNet specific flags (Managed and Subclass) - /// - internal class TypeFlags { - public static int HaveGetCharBuffer = (1 << 0); - public static int HaveSequenceIn = (1 << 1); - public static int GC = 0; - public static int HaveInPlaceOps = (1 << 3); - public static int CheckTypes = (1 << 4); - public static int HaveRichCompare = (1 << 5); - public static int HaveWeakRefs = (1 << 6); - public static int HaveIter = (1 << 7); - public static int HaveClass = (1 << 8); - public static int HeapType = (1 << 9); - public static int BaseType = (1 << 10); - public static int Ready = (1 << 12); - public static int Readying = (1 << 13); - public static int HaveGC = (1 << 14); - // 15 and 16 are reserved for stackless - public static int HaveStacklessExtension = 0; - /* XXX Reusing reserved constants */ - public static int Managed = (1 << 15); // PythonNet specific - public static int Subclass = (1 << 16); // PythonNet specific -#if (PYTHON25 || PYTHON26 || PYTHON27) - public static int HaveIndex = (1 << 17); -#endif -#if (PYTHON26 || PYTHON27) - /* Objects support nb_index in PyNumberMethods */ - public static int HaveVersionTag = (1 << 18); - public static int ValidVersionTag = (1 << 19); - public static int IsAbstract = (1 << 20); - public static int HaveNewBuffer = (1 << 21); - public static int IntSubclass = (1 << 23); - public static int LongSubclass = (1 << 24); - public static int ListSubclass = (1 << 25); - public static int TupleSubclass = (1 << 26); - public static int StringSubclass = (1 << 27); - public static int UnicodeSubclass = (1 << 28); - public static int DictSubclass = (1 << 29); - public static int BaseExceptionSubclass = (1 << 30); - public static int TypeSubclass = (1 << 31); -#endif - public static int Default = (HaveGetCharBuffer | - HaveSequenceIn | - HaveInPlaceOps | - HaveRichCompare | - HaveWeakRefs | - HaveIter | - HaveClass | - HaveStacklessExtension | -#if (PYTHON25 || PYTHON26 || PYTHON27) - HaveIndex | -#endif - 0); - } - - - // This class defines the function prototypes (delegates) used for low - // level integration with the CPython runtime. It also provides name - // based lookup of the correct prototype for a particular Python type - // slot and utilities for generating method thunks for managed methods. - - internal class Interop { - - static ArrayList keepAlive; - static Hashtable pmap; - - static Interop() { - - // Here we build a mapping of PyTypeObject slot names to the - // appropriate prototype (delegate) type to use for the slot. - - Type[] items = typeof(Interop).GetNestedTypes(); - Hashtable p = new Hashtable(); - - for (int i = 0; i < items.Length; i++) { - Type item = items[i]; - p[item.Name] = item; - } - - keepAlive = new ArrayList(); - Marshal.AllocHGlobal(IntPtr.Size); - pmap = new Hashtable(); - - pmap["tp_dealloc"] = p["DestructorFunc"]; - pmap["tp_print"] = p["PrintFunc"]; - pmap["tp_getattr"] = p["BinaryFunc"]; - pmap["tp_setattr"] = p["ObjObjArgFunc"]; - pmap["tp_compare"] = p["ObjObjFunc"]; - pmap["tp_repr"] = p["UnaryFunc"]; - pmap["tp_hash"] = p["UnaryFunc"]; - pmap["tp_call"] = p["TernaryFunc"]; - pmap["tp_str"] = p["UnaryFunc"]; - pmap["tp_getattro"] = p["BinaryFunc"]; - pmap["tp_setattro"] = p["ObjObjArgFunc"]; - pmap["tp_traverse"] = p["ObjObjArgFunc"]; - pmap["tp_clear"] = p["InquiryFunc"]; - pmap["tp_richcompare"] = p["RichCmpFunc"]; - pmap["tp_iter"] = p["UnaryFunc"]; - pmap["tp_iternext"] = p["UnaryFunc"]; - pmap["tp_descr_get"] = p["TernaryFunc"]; - pmap["tp_descr_set"] = p["ObjObjArgFunc"]; - pmap["tp_init"] = p["ObjObjArgFunc"]; - pmap["tp_alloc"] = p["IntArgFunc"]; - pmap["tp_new"] = p["TernaryFunc"]; - pmap["tp_free"] = p["DestructorFunc"]; - pmap["tp_is_gc"] = p["InquiryFunc"]; - - pmap["nb_add"] = p["BinaryFunc"]; - pmap["nb_subtract"] = p["BinaryFunc"]; - pmap["nb_multiply"] = p["BinaryFunc"]; - pmap["nb_divide"] = p["BinaryFunc"]; - pmap["nb_remainder"] = p["BinaryFunc"]; - pmap["nb_divmod"] = p["BinaryFunc"]; - pmap["nb_power"] = p["TernaryFunc"]; - pmap["nb_negative"] = p["UnaryFunc"]; - pmap["nb_positive"] = p["UnaryFunc"]; - pmap["nb_absolute"] = p["UnaryFunc"]; - pmap["nb_nonzero"] = p["InquiryFunc"]; - pmap["nb_invert"] = p["UnaryFunc"]; - pmap["nb_lshift"] = p["BinaryFunc"]; - pmap["nb_rshift"] = p["BinaryFunc"]; - pmap["nb_and"] = p["BinaryFunc"]; - pmap["nb_xor"] = p["BinaryFunc"]; - pmap["nb_or"] = p["BinaryFunc"]; - pmap["nb_coerce"] = p["ObjObjFunc"]; - pmap["nb_int"] = p["UnaryFunc"]; - pmap["nb_long"] = p["UnaryFunc"]; - pmap["nb_float"] = p["UnaryFunc"]; - pmap["nb_oct"] = p["UnaryFunc"]; - pmap["nb_hex"] = p["UnaryFunc"]; - pmap["nb_inplace_add"] = p["BinaryFunc"]; - pmap["nb_inplace_subtract"] = p["BinaryFunc"]; - pmap["nb_inplace_multiply"] = p["BinaryFunc"]; - pmap["nb_inplace_divide"] = p["BinaryFunc"]; - pmap["nb_inplace_remainder"] = p["BinaryFunc"]; - pmap["nb_inplace_power"] = p["TernaryFunc"]; - pmap["nb_inplace_lshift"] = p["BinaryFunc"]; - pmap["nb_inplace_rshift"] = p["BinaryFunc"]; - pmap["nb_inplace_and"] = p["BinaryFunc"]; - pmap["nb_inplace_xor"] = p["BinaryFunc"]; - pmap["nb_inplace_or"] = p["BinaryFunc"]; - pmap["nb_floor_divide"] = p["BinaryFunc"]; - pmap["nb_true_divide"] = p["BinaryFunc"]; - pmap["nb_inplace_floor_divide"] = p["BinaryFunc"]; - pmap["nb_inplace_true_divide"] = p["BinaryFunc"]; -#if (PYTHON25 || PYTHON26 || PYTHON27) - pmap["nb_index"] = p["UnaryFunc"]; -#endif - - pmap["sq_length"] = p["InquiryFunc"]; - pmap["sq_concat"] = p["BinaryFunc"]; - pmap["sq_repeat"] = p["IntArgFunc"]; - pmap["sq_item"] = p["IntArgFunc"]; - pmap["sq_slice"] = p["IntIntArgFunc"]; - pmap["sq_ass_item"] = p["IntObjArgFunc"]; - pmap["sq_ass_slice"] = p["IntIntObjArgFunc"]; - pmap["sq_contains"] = p["ObjObjFunc"]; - pmap["sq_inplace_concat"] = p["BinaryFunc"]; - pmap["sq_inplace_repeat"] = p["IntArgFunc"]; - - pmap["mp_length"] = p["InquiryFunc"]; - pmap["mp_subscript"] = p["BinaryFunc"]; - pmap["mp_ass_subscript"] = p["ObjObjArgFunc"]; - - pmap["bf_getreadbuffer"] = p["IntObjArgFunc"]; - pmap["bf_getwritebuffer"] = p["IntObjArgFunc"]; - pmap["bf_getsegcount"] = p["ObjObjFunc"]; - pmap["bf_getcharbuffer"] = p["IntObjArgFunc"]; - - pmap["__import__"] = p["TernaryFunc"]; - } - - internal static Type GetPrototype(string name) { - return pmap[name] as Type; - } - - internal static IntPtr GetThunk(MethodInfo method) { - Type dt = Interop.GetPrototype(method.Name); - if (dt != null) { - IntPtr tmp = Marshal.AllocHGlobal(IntPtr.Size); - Delegate d = Delegate.CreateDelegate(dt, method); - Thunk cb = new Thunk(d); - Marshal.StructureToPtr(cb, tmp, false); - IntPtr fp = Marshal.ReadIntPtr(tmp, 0); - Marshal.FreeHGlobal(tmp); - keepAlive.Add(d); - return fp; - } - return IntPtr.Zero; - } - - [UnmanagedFunctionPointer(CallingConvention.Cdecl)] - public delegate IntPtr UnaryFunc(IntPtr ob); - - [UnmanagedFunctionPointer(CallingConvention.Cdecl)] - public delegate IntPtr BinaryFunc(IntPtr ob, IntPtr arg); - - [UnmanagedFunctionPointer(CallingConvention.Cdecl)] - public delegate IntPtr TernaryFunc(IntPtr ob, IntPtr a1, IntPtr a2); - - [UnmanagedFunctionPointer(CallingConvention.Cdecl)] - public delegate int InquiryFunc(IntPtr ob); - - [UnmanagedFunctionPointer(CallingConvention.Cdecl)] - public delegate IntPtr IntArgFunc(IntPtr ob, int arg); - - [UnmanagedFunctionPointer(CallingConvention.Cdecl)] - public delegate IntPtr IntIntArgFunc(IntPtr ob, int a1, int a2); - - [UnmanagedFunctionPointer(CallingConvention.Cdecl)] - public delegate int IntObjArgFunc(IntPtr ob, int a1, IntPtr a2); - - [UnmanagedFunctionPointer(CallingConvention.Cdecl)] - public delegate int IntIntObjArgFunc(IntPtr o, int a, int b, IntPtr c); - - [UnmanagedFunctionPointer(CallingConvention.Cdecl)] - public delegate int ObjObjArgFunc(IntPtr o, IntPtr a, IntPtr b); - - [UnmanagedFunctionPointer(CallingConvention.Cdecl)] - public delegate int ObjObjFunc(IntPtr ob, IntPtr arg); - - [UnmanagedFunctionPointer(CallingConvention.Cdecl)] - public delegate void DestructorFunc(IntPtr ob); - - [UnmanagedFunctionPointer(CallingConvention.Cdecl)] - public delegate int PrintFunc(IntPtr ob, IntPtr a, int b); - - [UnmanagedFunctionPointer(CallingConvention.Cdecl)] - public delegate IntPtr RichCmpFunc(IntPtr ob, IntPtr a, int b); - - } - - - [StructLayout(LayoutKind.Sequential, CharSet=CharSet.Ansi)] - internal struct Thunk { - public Delegate fn; - - public Thunk(Delegate d) { - fn = d; - } - } - -} diff --git a/Pythonnet.Runtime/iterator.cs b/Pythonnet.Runtime/iterator.cs deleted file mode 100644 index 3d34760c39..0000000000 --- a/Pythonnet.Runtime/iterator.cs +++ /dev/null @@ -1,52 +0,0 @@ -// ========================================================================== -// This software is subject to the provisions of the Zope Public License, -// Version 2.0 (ZPL). A copy of the ZPL should accompany this distribution. -// THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED -// WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -// WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS -// FOR A PARTICULAR PURPOSE. -// ========================================================================== - -using System; -using System.Collections; -using System.Reflection; - -namespace Python.Runtime { - - //======================================================================== - // Implements a generic Python iterator for IEnumerable objects and - // managed array objects. This supports 'for i in object:' in Python. - //======================================================================== - - internal class Iterator : ExtensionType { - - IEnumerator iter; - - public Iterator(IEnumerator e) : base() { - this.iter = e; - } - - - //==================================================================== - // Implements support for the Python iteration protocol. - //==================================================================== - - public static IntPtr tp_iternext(IntPtr ob) { - Iterator self = GetManagedObject(ob) as Iterator; - if (!self.iter.MoveNext()) { - Exceptions.SetError(Exceptions.StopIteration, Runtime.PyNone); - return IntPtr.Zero; - } - object item = self.iter.Current; - return Converter.ToPythonImplicit(item); - } - - public static IntPtr tp_iter(IntPtr ob) { - Runtime.Incref(ob); - return ob; - } - - } - - -} diff --git a/Pythonnet.Runtime/managedtype.cs b/Pythonnet.Runtime/managedtype.cs deleted file mode 100644 index 670bcd2b36..0000000000 --- a/Pythonnet.Runtime/managedtype.cs +++ /dev/null @@ -1,97 +0,0 @@ -// ========================================================================== -// This software is subject to the provisions of the Zope Public License, -// Version 2.0 (ZPL). A copy of the ZPL should accompany this distribution. -// THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED -// WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -// WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS -// FOR A PARTICULAR PURPOSE. -// ========================================================================== - -using System; -using System.Runtime.InteropServices; -using System.Collections; -using System.Reflection; - -namespace Python.Runtime { - - //======================================================================== - // Common base class for all objects that are implemented in managed - // code. It defines the common fields that associate CLR and Python - // objects and common utilities to convert between those identities. - //======================================================================== - - internal abstract class ManagedType { - - internal GCHandle gcHandle; // Native handle - internal IntPtr pyHandle; // PyObject * - internal IntPtr tpHandle; // PyType * - - - //==================================================================== - // Given a Python object, return the associated managed object or null. - //==================================================================== - - internal static ManagedType GetManagedObject(IntPtr ob) { - if (ob != IntPtr.Zero) { - IntPtr tp = Runtime.PyObject_TYPE(ob); - if (tp == Runtime.PyTypeType || tp == Runtime.PyCLRMetaType) { - tp = ob; - } - - int flags = (int)Marshal.ReadIntPtr(tp, TypeOffset.tp_flags); - if ((flags & TypeFlags.Managed) != 0) { - IntPtr op = (tp == ob) ? - Marshal.ReadIntPtr(tp, TypeOffset.magic()) : - Marshal.ReadIntPtr(ob, ObjectOffset.magic()); - GCHandle gc = (GCHandle)op; - return (ManagedType)gc.Target; - } - - // In certain situations, we need to recognize a wrapped - // exception class and be willing to unwrap the class :( - - if (Runtime.wrap_exceptions) { - IntPtr e = Exceptions.UnwrapExceptionClass(ob); - if ((e != IntPtr.Zero) && (e != ob)) { - ManagedType m = GetManagedObject(e); - Runtime.Decref(e); - return m; - } - } - } - return null; - } - - - internal static ManagedType GetManagedObjectErr(IntPtr ob) { - ManagedType result = GetManagedObject(ob); - if (result == null) { - Exceptions.SetError(Exceptions.TypeError, - "invalid argument, expected CLR type" - ); - } - return result; - } - - - internal static bool IsManagedType(IntPtr ob) { - if (ob != IntPtr.Zero) { - IntPtr tp = Runtime.PyObject_TYPE(ob); - if (tp == Runtime.PyTypeType || tp == Runtime.PyCLRMetaType) { - tp = ob; - } - - int flags = (int)Marshal.ReadIntPtr(tp, TypeOffset.tp_flags); - if ((flags & TypeFlags.Managed) != 0) { - return true; - } - } - return false; - } - - - } - - -} - diff --git a/Pythonnet.Runtime/metatype.cs b/Pythonnet.Runtime/metatype.cs deleted file mode 100644 index cb14ac99e7..0000000000 --- a/Pythonnet.Runtime/metatype.cs +++ /dev/null @@ -1,264 +0,0 @@ -// ========================================================================== -// This software is subject to the provisions of the Zope Public License, -// Version 2.0 (ZPL). A copy of the ZPL should accompany this distribution. -// THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED -// WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -// WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS -// FOR A PARTICULAR PURPOSE. -// ========================================================================== - -using System; -using System.Runtime.InteropServices; -using System.Collections; -using System.Reflection; - -namespace Python.Runtime { - - //======================================================================== - // The managed metatype. This object implements the type of all reflected - // types. It also provides support for single-inheritance from reflected - // managed types. - //======================================================================== - - internal class MetaType : ManagedType { - - static IntPtr PyCLRMetaType; - - - //==================================================================== - // Metatype initialization. This bootstraps the CLR metatype to life. - //==================================================================== - - public static IntPtr Initialize() { - PyCLRMetaType = TypeManager.CreateMetaType(typeof(MetaType)); - return PyCLRMetaType; - } - - - //==================================================================== - // Metatype __new__ implementation. This is called to create a new - // class / type when a reflected class is subclassed. - //==================================================================== - - public static IntPtr tp_new(IntPtr tp, IntPtr args, IntPtr kw) { - int len = Runtime.PyTuple_Size(args); - if (len < 3) { - return Exceptions.RaiseTypeError("invalid argument list"); - } - - //IntPtr name = Runtime.PyTuple_GetItem(args, 0); - IntPtr bases = Runtime.PyTuple_GetItem(args, 1); - IntPtr dict = Runtime.PyTuple_GetItem(args, 2); - - // We do not support multiple inheritance, so the bases argument - // should be a 1-item tuple containing the type we are subtyping. - // That type must itself have a managed implementation. We check - // that by making sure its metatype is the CLR metatype. - - if (Runtime.PyTuple_Size(bases) != 1) { - return Exceptions.RaiseTypeError( - "cannot use multiple inheritance with managed classes" - ); - - } - - IntPtr base_type = Runtime.PyTuple_GetItem(bases, 0); - IntPtr mt = Runtime.PyObject_TYPE(base_type); - - if (!((mt == PyCLRMetaType) || (mt == Runtime.PyTypeType))) { - return Exceptions.RaiseTypeError("invalid metatype"); - } - - // Ensure that the reflected type is appropriate for subclassing, - // disallowing subclassing of delegates, enums and array types. - - ClassBase cb = GetManagedObject(base_type) as ClassBase; - if (cb != null) { - if (! cb.CanSubclass() ) { - return Exceptions.RaiseTypeError( - "delegates, enums and array types cannot be subclassed" - ); - } - } - - IntPtr slots = Runtime.PyDict_GetItemString(dict, "__slots__"); - if (slots != IntPtr.Zero) { - return Exceptions.RaiseTypeError( - "subclasses of managed classes do not support __slots__" - ); - } - - //return TypeManager.CreateSubType(args); - - - // right way - - IntPtr func = Marshal.ReadIntPtr(Runtime.PyTypeType, - TypeOffset.tp_new); - IntPtr type = NativeCall.Call_3(func, tp, args, kw); - if (type == IntPtr.Zero) { - return IntPtr.Zero; - } - - int flags = TypeFlags.Default; - flags |= TypeFlags.Managed; - flags |= TypeFlags.HeapType; - flags |= TypeFlags.BaseType; - flags |= TypeFlags.Subclass; - flags |= TypeFlags.HaveGC; - Marshal.WriteIntPtr(type, TypeOffset.tp_flags, (IntPtr)flags); - - TypeManager.CopySlot(base_type, type, TypeOffset.tp_dealloc); - - // Hmm - the standard subtype_traverse, clear look at ob_size to - // do things, so to allow gc to work correctly we need to move - // our hidden handle out of ob_size. Then, in theory we can - // comment this out and still not crash. - TypeManager.CopySlot(base_type, type, TypeOffset.tp_traverse); - TypeManager.CopySlot(base_type, type, TypeOffset.tp_clear); - - - // for now, move up hidden handle... - IntPtr gc = Marshal.ReadIntPtr(base_type, TypeOffset.magic()); - Marshal.WriteIntPtr(type, TypeOffset.magic(), gc); - - //DebugUtil.DumpType(base_type); - //DebugUtil.DumpType(type); - - return type; - } - - - public static IntPtr tp_alloc(IntPtr mt, int n) { - IntPtr type = Runtime.PyType_GenericAlloc(mt, n); - return type; - } - - - public static void tp_free(IntPtr tp) { - Runtime.PyObject_GC_Del(tp); - } - - - //==================================================================== - // Metatype __call__ implementation. This is needed to ensure correct - // initialization (__init__ support), because the tp_call we inherit - // from PyType_Type won't call __init__ for metatypes it doesnt know. - //==================================================================== - - public static IntPtr tp_call(IntPtr tp, IntPtr args, IntPtr kw) { - IntPtr func = Marshal.ReadIntPtr(tp, TypeOffset.tp_new); - if (func == IntPtr.Zero) { - return Exceptions.RaiseTypeError("invalid object"); - } - - IntPtr obj = NativeCall.Call_3(func, tp, args, kw); - if (obj == IntPtr.Zero) { - return IntPtr.Zero; - } - - IntPtr py__init__ = Runtime.PyString_FromString("__init__"); - IntPtr type = Runtime.PyObject_TYPE(obj); - IntPtr init = Runtime._PyType_Lookup(type, py__init__); - Runtime.Decref(py__init__); - Runtime.PyErr_Clear(); - - if (init != IntPtr.Zero) { - IntPtr bound = Runtime.GetBoundArgTuple(obj, args); - if (bound == IntPtr.Zero) { - Runtime.Decref(obj); - return IntPtr.Zero; - } - - IntPtr result = Runtime.PyObject_Call(init, bound, kw); - Runtime.Decref(bound); - - if (result == IntPtr.Zero) { - Runtime.Decref(obj); - return IntPtr.Zero; - } - - Runtime.Decref(result); - } - - return obj; - } - - - //==================================================================== - // Type __setattr__ implementation for reflected types. Note that this - // is slightly different than the standard setattr implementation for - // the normal Python metatype (PyTypeType). We need to look first in - // the type object of a reflected type for a descriptor in order to - // support the right setattr behavior for static fields and properties. - //==================================================================== - - public static int tp_setattro(IntPtr tp, IntPtr name, IntPtr value) { - IntPtr descr = Runtime._PyType_Lookup(tp, name); - - if (descr != IntPtr.Zero) { - IntPtr dt = Runtime.PyObject_TYPE(descr); - IntPtr fp = Marshal.ReadIntPtr(dt, TypeOffset.tp_descr_set); - if (fp != IntPtr.Zero) { - return NativeCall.Impl.Int_Call_3(fp, descr, name, value); - } - Exceptions.SetError(Exceptions.AttributeError, - "attribute is read-only"); - return -1; - } - - if (Runtime.PyObject_GenericSetAttr(tp, name, value) < 0) { - return -1; - } - - return 0; - } - - //==================================================================== - // The metatype has to implement [] semantics for generic types, so - // here we just delegate to the generic type def implementation. Its - // own mp_subscript - //==================================================================== - public static IntPtr mp_subscript(IntPtr tp, IntPtr idx) { - ClassBase cb = GetManagedObject(tp) as ClassBase; - if (cb != null) { - return cb.type_subscript(idx); - } - return Exceptions.RaiseTypeError("unsubscriptable object"); - } - - //==================================================================== - // Dealloc implementation. This is called when a Python type generated - // by this metatype is no longer referenced from the Python runtime. - //==================================================================== - - public static void tp_dealloc(IntPtr tp) { - // Fix this when we dont cheat on the handle for subclasses! - - int flags = (int)Marshal.ReadIntPtr(tp, TypeOffset.tp_flags); - if ((flags & TypeFlags.Subclass) == 0) { - IntPtr gc = Marshal.ReadIntPtr(tp, TypeOffset.magic()); - ((GCHandle)gc).Free(); - } - - IntPtr op = Marshal.ReadIntPtr(tp, TypeOffset.ob_type); - Runtime.Decref(op); - - // Delegate the rest of finalization the Python metatype. Note - // that the PyType_Type implementation of tp_dealloc will call - // tp_free on the type of the type being deallocated - in this - // case our CLR metatype. That is why we implement tp_free. - - op = Marshal.ReadIntPtr(Runtime.PyTypeType, TypeOffset.tp_dealloc); - NativeCall.Void_Call_1(op, tp); - - return; - } - - - - - } - - -} diff --git a/Pythonnet.Runtime/methodbinder.cs b/Pythonnet.Runtime/methodbinder.cs deleted file mode 100644 index 80d3968fd4..0000000000 --- a/Pythonnet.Runtime/methodbinder.cs +++ /dev/null @@ -1,465 +0,0 @@ -// ========================================================================== -// This software is subject to the provisions of the Zope Public License, -// Version 2.0 (ZPL). A copy of the ZPL should accompany this distribution. -// THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED -// WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -// WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS -// FOR A PARTICULAR PURPOSE. -// ========================================================================== - -using System; -using System.Collections; -using System.Reflection; - -namespace Python.Runtime { - - //======================================================================== - // A MethodBinder encapsulates information about a (possibly overloaded) - // managed method, and is responsible for selecting the right method given - // a set of Python arguments. This is also used as a base class for the - // ConstructorBinder, a minor variation used to invoke constructors. - //======================================================================== - - internal class MethodBinder { - - public ArrayList list; - public MethodBase[] methods; - public bool init = false; - public bool allow_threads = true; - - internal MethodBinder () { - this.list = new ArrayList(); - } - - internal MethodBinder(MethodInfo mi) : base () { - this.list = new ArrayList(); - this.list.Add(mi); - } - - public int Count { - get { return this.list.Count; } - } - - internal void AddMethod(MethodBase m) { - this.list.Add(m); - } - - //==================================================================== - // Given a sequence of MethodInfo and a sequence of types, return the - // MethodInfo that matches the signature represented by those types. - //==================================================================== - - internal static MethodInfo MatchSignature(MethodInfo[] mi, Type[] tp) { - int count = tp.Length; - for (int i = 0; i < mi.Length; i++) { - ParameterInfo[] pi = mi[i].GetParameters(); - if (pi.Length != count) { - continue; - } - for (int n = 0; n < pi.Length; n++) { - if (tp[n]!= pi[n].ParameterType) { - break; - } - if (n == (pi.Length - 1)) { - return mi[i]; - } - } - } - return null; - } - - //==================================================================== - // Given a sequence of MethodInfo and a sequence of type parameters, - // return the MethodInfo that represents the matching closed generic. - //==================================================================== - - internal static MethodInfo MatchParameters(MethodInfo[] mi,Type[] tp) { - int count = tp.Length; - for (int i = 0; i < mi.Length; i++) { - if (!mi[i].IsGenericMethodDefinition) { - continue; - } - Type[] args = mi[i].GetGenericArguments(); - if (args.Length != count) { - continue; - } - return mi[i].MakeGenericMethod(tp); - } - return null; - } - - - //==================================================================== - // Given a sequence of MethodInfo and two sequences of type parameters, - // return the MethodInfo that matches the signature and the closed generic. - //==================================================================== - - internal static MethodInfo MatchSignatureAndParameters(MethodInfo[] mi, Type[] genericTp, Type[] sigTp) - { - int genericCount = genericTp.Length; - int signatureCount = sigTp.Length; - for (int i = 0; i < mi.Length; i++) - { - if (!mi[i].IsGenericMethodDefinition) - { - continue; - } - Type[] genericArgs = mi[i].GetGenericArguments(); - if (genericArgs.Length != genericCount) - { - continue; - } - ParameterInfo[] pi = mi[i].GetParameters(); - if (pi.Length != signatureCount) - { - continue; - } - for (int n = 0; n < pi.Length; n++) - { - if (sigTp[n] != pi[n].ParameterType) - { - break; - } - if (n == (pi.Length - 1)) - { - MethodInfo match = mi[i]; - if (match.IsGenericMethodDefinition) - { - Type[] typeArgs = match.GetGenericArguments(); - return match.MakeGenericMethod(genericTp); - } - return match; - } - } - } - return null; - } - - - //==================================================================== - // Return the array of MethodInfo for this method. The result array - // is arranged in order of precendence (done lazily to avoid doing it - // at all for methods that are never called). - //==================================================================== - - internal MethodBase[] GetMethods() { - if (!init) { - // I'm sure this could be made more efficient. - list.Sort(new MethodSorter()); - methods = (MethodBase[])list.ToArray(typeof(MethodBase)); - init = true; - } - return methods; - } - - //==================================================================== - // Precedence algorithm largely lifted from jython - the concerns are - // generally the same so we'll start w/this and tweak as necessary. - //==================================================================== - - internal static int GetPrecedence(MethodBase mi) { - ParameterInfo[] pi = mi.GetParameters(); - int val = mi.IsStatic ? 3000 : 0; - int num = pi.Length; - - val += (mi.IsGenericMethod ? 1 : 0); - for (int i = 0; i < num; i++) { - val += ArgPrecedence(pi[i].ParameterType); - } - - return val; - } - - //==================================================================== - // Return a precedence value for a particular Type object. - //==================================================================== - - internal static int ArgPrecedence(Type t) { - Type objectType = typeof(Object); - if (t == objectType) return 3000; - - TypeCode tc = Type.GetTypeCode(t); - if (tc == TypeCode.Object) return 1; - if (tc == TypeCode.UInt64) return 10; - if (tc == TypeCode.UInt32) return 11; - if (tc == TypeCode.UInt16) return 12; - if (tc == TypeCode.Int64) return 13; - if (tc == TypeCode.Int32) return 14; - if (tc == TypeCode.Int16) return 15; - if (tc == TypeCode.Char) return 16; - if (tc == TypeCode.SByte) return 17; - if (tc == TypeCode.Byte) return 18; - if (tc == TypeCode.Single) return 20; - if (tc == TypeCode.Double) return 21; - if (tc == TypeCode.String) return 30; - if (tc == TypeCode.Boolean) return 40; - - if (t.IsArray) { - Type e = t.GetElementType(); - if (e == objectType) - return 2500; - return 100 + ArgPrecedence(e); - } - - return 2000; - } - - //==================================================================== - // Bind the given Python instance and arguments to a particular method - // overload and return a structure that contains the converted Python - // instance, converted arguments and the correct method to call. - //==================================================================== - - internal Binding Bind(IntPtr inst, IntPtr args, IntPtr kw) { - return this.Bind(inst, args, kw, null, null); - } - - internal Binding Bind(IntPtr inst, IntPtr args, IntPtr kw, - MethodBase info) { - return this.Bind(inst, args, kw, info, null); - } - - internal Binding Bind(IntPtr inst, IntPtr args, IntPtr kw, - MethodBase info, MethodInfo[] methodinfo) { - // loop to find match, return invoker w/ or /wo error - MethodBase[] _methods = null; - int pynargs = Runtime.PyTuple_Size(args); - object arg; - bool isGeneric = false; - - if (info != null) { - _methods = (MethodBase[])Array.CreateInstance( - typeof(MethodBase), 1 - ); - _methods.SetValue(info, 0); - } - else { - _methods = GetMethods(); - } - - for (int i = 0; i < _methods.Length; i++) { - MethodBase mi = _methods[i]; - if (mi.IsGenericMethod) { isGeneric = true; } - ParameterInfo[] pi = mi.GetParameters(); - int clrnargs = pi.Length; - bool match = false; - int arrayStart = -1; - int outs = 0; - - if (pynargs == clrnargs) { - match = true; - } else if ((pynargs > clrnargs) && (clrnargs > 0) && - (pi[clrnargs-1].ParameterType.IsArray)) { - // The last argument of the mananged functions seems to - // accept multiple arguments as a array. Hopefully it's a - // spam(params object[] egg) style method - match = true; - arrayStart = clrnargs - 1; - } - - if (match) { - Object[] margs = new Object[clrnargs]; - - for (int n = 0; n < clrnargs; n++) { - IntPtr op; - if (arrayStart == n) { - // map remaining Python arguments to a tuple since - // the managed function accepts it - hopefully :] - op = Runtime.PyTuple_GetSlice(args, arrayStart, pynargs); - } - else { - op = Runtime.PyTuple_GetItem(args, n); - } - Type type = pi[n].ParameterType; - if (pi[n].IsOut || type.IsByRef) { - outs++; - } - - if (!Converter.ToManaged(op, type, out arg, false)) { - Exceptions.Clear(); - margs = null; - break; - } - if (arrayStart == n) { - // GetSlice() creates a new reference but GetItem() - // returns only a borrow reference. - Runtime.Decref(op); - } - margs[n] = arg; - } - - if (margs == null) { - continue; - } - - Object target = null; - if ((!mi.IsStatic) && (inst != IntPtr.Zero)) { - //CLRObject co = (CLRObject)ManagedType.GetManagedObject(inst); - // InvalidCastException: Unable to cast object of type - // 'Python.Runtime.ClassObject' to type 'Python.Runtime.CLRObject' - CLRObject co = ManagedType.GetManagedObject(inst) as CLRObject; - - // Sanity check: this ensures a graceful exit if someone does - // something intentionally wrong like call a non-static method - // on the class rather than on an instance of the class. - // XXX maybe better to do this before all the other rigmarole. - if (co == null) { - return null; - } - target = co.inst; - } - - return new Binding(mi, target, margs, outs); - } - } - // We weren't able to find a matching method but at least one - // is a generic method and info is null. That happens when a generic - // method was not called using the [] syntax. Let's introspect the - // type of the arguments and use it to construct the correct method. - if (isGeneric && (info == null) && (methodinfo != null)) - { - Type[] types = Runtime.PythonArgsToTypeArray(args, true); - MethodInfo mi = MethodBinder.MatchParameters(methodinfo, types); - return Bind(inst, args, kw, mi, null); - } - return null; - } - - internal virtual IntPtr Invoke(IntPtr inst, IntPtr args, IntPtr kw) { - return this.Invoke(inst, args, kw, null, null); - - } - - internal virtual IntPtr Invoke(IntPtr inst, IntPtr args, IntPtr kw, - MethodBase info) { - return this.Invoke(inst, args, kw, info, null); - } - - internal virtual IntPtr Invoke(IntPtr inst, IntPtr args, IntPtr kw, - MethodBase info, MethodInfo[] methodinfo) { - Binding binding = this.Bind(inst, args, kw, info, methodinfo); - Object result; - IntPtr ts = IntPtr.Zero; - - if (binding == null) { - Exceptions.SetError(Exceptions.TypeError, - "No method matches given arguments" - ); - return IntPtr.Zero; - } - - if (allow_threads) { - ts = PythonEngine.BeginAllowThreads(); - } - - try { - result = binding.info.Invoke(binding.inst, - BindingFlags.Default, - null, - binding.args, - null); - } - catch (Exception e) { - if (e.InnerException != null) { - e = e.InnerException; - } - if (allow_threads) { - PythonEngine.EndAllowThreads(ts); - } - Exceptions.SetError(e); - return IntPtr.Zero; - } - - if (allow_threads) { - PythonEngine.EndAllowThreads(ts); - } - - // If there are out parameters, we return a tuple containing - // the result followed by the out parameters. If there is only - // one out parameter and the return type of the method is void, - // we return the out parameter as the result to Python (for - // code compatibility with ironpython). - - MethodInfo mi = (MethodInfo)binding.info; - - if ((binding.outs == 1) && (mi.ReturnType == typeof(void))) { - - } - - if (binding.outs > 0) { - ParameterInfo[] pi = mi.GetParameters(); - int c = pi.Length; - int n = 0; - - IntPtr t = Runtime.PyTuple_New(binding.outs + 1); - IntPtr v = Converter.ToPython(result, mi.ReturnType); - Runtime.PyTuple_SetItem(t, n, v); - n++; - - for (int i=0; i < c; i++) { - Type pt = pi[i].ParameterType; - if (pi[i].IsOut || pt.IsByRef) { - v = Converter.ToPython(binding.args[i], pt); - Runtime.PyTuple_SetItem(t, n, v); - n++; - } - } - - if ((binding.outs == 1) && (mi.ReturnType == typeof(void))) { - v = Runtime.PyTuple_GetItem(t, 1); - Runtime.Incref(v); - Runtime.Decref(t); - return v; - } - - return t; - } - - return Converter.ToPython(result, mi.ReturnType); - } - - } - - - - //======================================================================== - // Utility class to sort method info by parameter type precedence. - //======================================================================== - - internal class MethodSorter : IComparer { - - int IComparer.Compare(Object m1, Object m2) { - int p1 = MethodBinder.GetPrecedence((MethodBase)m1); - int p2 = MethodBinder.GetPrecedence((MethodBase)m2); - if (p1 < p2) return -1; - if (p1 > p2) return 1; - return 0; - } - - } - - - //======================================================================== - // A Binding is a utility instance that bundles together a MethodInfo - // representing a method to call, a (possibly null) target instance for - // the call, and the arguments for the call (all as managed values). - //======================================================================== - - internal class Binding { - - public MethodBase info; - public Object[] args; - public Object inst; - public int outs; - - internal Binding(MethodBase info, Object inst, Object[] args, - int outs) { - this.info = info; - this.inst = inst; - this.args = args; - this.outs = outs; - } - - } - -} diff --git a/Pythonnet.Runtime/methodbinding.cs b/Pythonnet.Runtime/methodbinding.cs deleted file mode 100644 index 0459d36b29..0000000000 --- a/Pythonnet.Runtime/methodbinding.cs +++ /dev/null @@ -1,193 +0,0 @@ -// ========================================================================== -// This software is subject to the provisions of the Zope Public License, -// Version 2.0 (ZPL). A copy of the ZPL should accompany this distribution. -// THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED -// WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -// WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS -// FOR A PARTICULAR PURPOSE. -// ========================================================================== - -using System; -using System.Reflection; - -namespace Python.Runtime { - - //======================================================================== - // Implements a Python binding type for CLR methods. These work much like - // standard Python method bindings, but the same type is used to bind - // both static and instance methods. - //======================================================================== - - internal class MethodBinding : ExtensionType { - - internal MethodInfo info; - internal MethodObject m; - internal IntPtr target; - - public MethodBinding(MethodObject m, IntPtr target) : base() { - Runtime.Incref(target); - this.target = target; - this.info = null; - this.m = m; - } - - //==================================================================== - // Implement binding of generic methods using the subscript syntax []. - //==================================================================== - - public static IntPtr mp_subscript(IntPtr tp, IntPtr idx) { - MethodBinding self = (MethodBinding)GetManagedObject(tp); - - Type[] types = Runtime.PythonArgsToTypeArray(idx); - if (types == null) { - return Exceptions.RaiseTypeError("type(s) expected"); - } - - MethodInfo mi = MethodBinder.MatchParameters(self.m.info, types); - if (mi == null) { - string e = "No match found for given type params"; - return Exceptions.RaiseTypeError(e); - } - - MethodBinding mb = new MethodBinding(self.m, self.target); - mb.info = mi; - Runtime.Incref(mb.pyHandle); - return mb.pyHandle; - } - - - //==================================================================== - // MethodBinding __getattribute__ implementation. - //==================================================================== - - public static IntPtr tp_getattro(IntPtr ob, IntPtr key) { - MethodBinding self = (MethodBinding)GetManagedObject(ob); - - if (!Runtime.PyString_Check(key)) { - Exceptions.SetError(Exceptions.TypeError, "string expected"); - return IntPtr.Zero; - } - - string name = Runtime.GetManagedString(key); - if (name == "__doc__") { - IntPtr doc = self.m.GetDocString(); - Runtime.Incref(doc); - return doc; - } - - // XXX deprecate __overloads__ soon... - if (name == "__overloads__" || name == "Overloads") { - OverloadMapper om = new OverloadMapper(self.m, self.target); - Runtime.Incref(om.pyHandle); - return om.pyHandle; - } - - return Runtime.PyObject_GenericGetAttr(ob, key); - } - - - //==================================================================== - // MethodBinding __call__ implementation. - //==================================================================== - - public static IntPtr tp_call(IntPtr ob, IntPtr args, IntPtr kw) { - MethodBinding self = (MethodBinding)GetManagedObject(ob); - - // This works around a situation where the wrong generic method is picked, - // for example this method in the tests: string Overloaded(int arg1, int arg2, string arg3) - if (self.info != null) - { - if (self.info.IsGenericMethod) - { - int len = Runtime.PyTuple_Size(args); - Type[] sigTp = Runtime.PythonArgsToTypeArray(args, true); - if (sigTp != null) - { - Type[] genericTp = self.info.GetGenericArguments(); - MethodInfo betterMatch = MethodBinder.MatchSignatureAndParameters(self.m.info, genericTp, sigTp); - if (betterMatch != null) self.info = betterMatch; - } - } - } - - // This supports calling a method 'unbound', passing the instance - // as the first argument. Note that this is not supported if any - // of the overloads are static since we can't know if the intent - // was to call the static method or the unbound instance method. - - if ((self.target == IntPtr.Zero) && (!self.m.IsStatic())) - { - int len = Runtime.PyTuple_Size(args); - if (len < 1) - { - Exceptions.SetError(Exceptions.TypeError, "not enough arguments"); - return IntPtr.Zero; - } - IntPtr uargs = Runtime.PyTuple_GetSlice(args, 1, len); - IntPtr inst = Runtime.PyTuple_GetItem(args, 0); - Runtime.Incref(inst); - IntPtr r = self.m.Invoke(inst, uargs, kw, self.info); - Runtime.Decref(inst); - Runtime.Decref(uargs); - return r; - } - - return self.m.Invoke(self.target, args, kw, self.info); - } - - - //==================================================================== - // MethodBinding __hash__ implementation. - //==================================================================== - - public static IntPtr tp_hash(IntPtr ob) { - MethodBinding self = (MethodBinding)GetManagedObject(ob); - long x = 0; - long y = 0; - - if (self.target != IntPtr.Zero) { - x = Runtime.PyObject_Hash(self.target).ToInt64(); - if (x == -1) { - return new IntPtr(-1); - } - } - - y = Runtime.PyObject_Hash(self.m.pyHandle).ToInt64(); - if (y == -1) { - return new IntPtr(-1); - } - - x ^= y; - - if (x == -1) { - x = -1; - } - - return new IntPtr(x); - } - - //==================================================================== - // MethodBinding __repr__ implementation. - //==================================================================== - - public static IntPtr tp_repr(IntPtr ob) { - MethodBinding self = (MethodBinding)GetManagedObject(ob); - string type = (self.target == IntPtr.Zero) ? "unbound" : "bound"; - string s = String.Format("<{0} method '{1}'>", type, self.m.name); - return Runtime.PyString_FromStringAndSize(s, s.Length); - } - - //==================================================================== - // MethodBinding dealloc implementation. - //==================================================================== - - public static new void tp_dealloc(IntPtr ob) { - MethodBinding self = (MethodBinding)GetManagedObject(ob); - Runtime.Decref(self.target); - ExtensionType.FinalizeObject(self); - } - - } - - -} diff --git a/Pythonnet.Runtime/methodobject.cs b/Pythonnet.Runtime/methodobject.cs deleted file mode 100644 index 5567540fb4..0000000000 --- a/Pythonnet.Runtime/methodobject.cs +++ /dev/null @@ -1,188 +0,0 @@ -// ========================================================================== -// This software is subject to the provisions of the Zope Public License, -// Version 2.0 (ZPL). A copy of the ZPL should accompany this distribution. -// THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED -// WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -// WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS -// FOR A PARTICULAR PURPOSE. -// ========================================================================== - -using System; -using System.Collections; -using System.Reflection; - -namespace Python.Runtime { - - //======================================================================== - // Implements a Python type that represents a CLR method. Method objects - // support a subscript syntax [] to allow explicit overload selection. - //======================================================================== - - internal class MethodObject : ExtensionType { - - internal MethodInfo[] info; - internal string name; - internal MethodBinding unbound; - internal MethodBinder binder; - internal bool is_static = false; - internal IntPtr doc; - - public MethodObject(string name, MethodInfo[] info) : base() { - _MethodObject(name, info); - } - - public MethodObject(string name, MethodInfo[] info, bool allow_threads) : base() - { - _MethodObject(name, info); - binder.allow_threads = allow_threads; - } - - private void _MethodObject(string name, MethodInfo[] info) - { - this.name = name; - this.info = info; - binder = new MethodBinder(); - for (int i = 0; i < info.Length; i++) - { - MethodInfo item = (MethodInfo)info[i]; - binder.AddMethod(item); - if (item.IsStatic) - { - this.is_static = true; - } - } - } - - public virtual IntPtr Invoke(IntPtr inst, IntPtr args, IntPtr kw) { - return this.Invoke(inst, args, kw, null); - } - - public virtual IntPtr Invoke(IntPtr target, IntPtr args, IntPtr kw, - MethodBase info) { - return binder.Invoke(target, args, kw, info, this.info); - } - - //==================================================================== - // Helper to get docstrings from reflected method / param info. - //==================================================================== - - internal IntPtr GetDocString() { - if (doc != IntPtr.Zero) { - return doc; - } - string str = ""; - Type marker = typeof(DocStringAttribute); - MethodBase[] methods = binder.GetMethods(); - foreach (MethodBase method in methods) { - if (str.Length > 0) - str += Environment.NewLine; - Attribute[] attrs = (Attribute[]) method.GetCustomAttributes(marker, false); - if (attrs.Length == 0) { - str += method.ToString(); - } - else { - DocStringAttribute attr = (DocStringAttribute)attrs[0]; - str += attr.DocString; - } - } - doc = Runtime.PyString_FromString(str); - return doc; - } - - - //==================================================================== - // This is a little tricky: a class can actually have a static method - // and instance methods all with the same name. That makes it tough - // to support calling a method 'unbound' (passing the instance as the - // first argument), because in this case we can't know whether to call - // the instance method unbound or call the static method. - // - // The rule we is that if there are both instance and static methods - // with the same name, then we always call the static method. So this - // method returns true if any of the methods that are represented by - // the descriptor are static methods (called by MethodBinding). - //==================================================================== - - internal bool IsStatic() { - return this.is_static; - } - - //==================================================================== - // Descriptor __getattribute__ implementation. - //==================================================================== - - public static IntPtr tp_getattro(IntPtr ob, IntPtr key) { - MethodObject self = (MethodObject)GetManagedObject(ob); - - if (!Runtime.PyString_Check(key)) { - return Exceptions.RaiseTypeError("string expected"); - } - - string name = Runtime.GetManagedString(key); - if (name == "__doc__") { - IntPtr doc = self.GetDocString(); - Runtime.Incref(doc); - return doc; - } - - return Runtime.PyObject_GenericGetAttr(ob, key); - } - - //==================================================================== - // Descriptor __get__ implementation. Accessing a CLR method returns - // a "bound" method similar to a Python bound method. - //==================================================================== - - public static IntPtr tp_descr_get(IntPtr ds, IntPtr ob, IntPtr tp) { - MethodObject self = (MethodObject)GetManagedObject(ds); - MethodBinding binding; - - // If the method is accessed through its type (rather than via - // an instance) we return an 'unbound' MethodBinding that will - // cached for future accesses through the type. - - if (ob == IntPtr.Zero) { - if (self.unbound == null) { - self.unbound = new MethodBinding(self, IntPtr.Zero); - } - binding = self.unbound; - Runtime.Incref(binding.pyHandle);; - return binding.pyHandle; - } - - if (Runtime.PyObject_IsInstance(ob, tp) < 1) { - return Exceptions.RaiseTypeError("invalid argument"); - } - - binding = new MethodBinding(self, ob); - return binding.pyHandle; - } - - //==================================================================== - // Descriptor __repr__ implementation. - //==================================================================== - - public static IntPtr tp_repr(IntPtr ob) { - MethodObject self = (MethodObject)GetManagedObject(ob); - string s = String.Format("", self.name); - return Runtime.PyString_FromStringAndSize(s, s.Length); - } - - //==================================================================== - // Descriptor dealloc implementation. - //==================================================================== - - public static new void tp_dealloc(IntPtr ob) { - MethodObject self = (MethodObject)GetManagedObject(ob); - Runtime.Decref(self.doc); - if (self.unbound != null) { - Runtime.Decref(self.unbound.pyHandle); - } - ExtensionType.FinalizeObject(self); - } - - - } - - -} diff --git a/Pythonnet.Runtime/methodwrapper.cs b/Pythonnet.Runtime/methodwrapper.cs deleted file mode 100644 index 04a49d5924..0000000000 --- a/Pythonnet.Runtime/methodwrapper.cs +++ /dev/null @@ -1,61 +0,0 @@ -// ========================================================================== -// This software is subject to the provisions of the Zope Public License, -// Version 2.0 (ZPL). A copy of the ZPL should accompany this distribution. -// THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED -// WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -// WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS -// FOR A PARTICULAR PURPOSE. -// ========================================================================== - -using System; -using System.Collections; -using System.Runtime.InteropServices; - -namespace Python.Runtime { - - /// - /// A MethodWrapper wraps a static method of a managed type, - /// making it callable by Python as a PyCFunction object. This is - /// currently used mainly to implement special cases like the CLR - /// import hook. - /// - - internal class MethodWrapper { - - public IntPtr mdef; - public IntPtr ptr; - - public MethodWrapper(Type type, string name) { - - // Turn the managed method into a function pointer - - IntPtr fp = Interop.GetThunk(type.GetMethod(name)); - - // XXX - here we create a Python string object, then take the - // char * of the internal string to pass to our methoddef - // structure. Its a hack, and the name is leaked! - - IntPtr ps = Runtime.PyString_FromString(name); - IntPtr sp = Runtime.PyString_AS_STRING(ps); - - // Allocate and initialize a PyMethodDef structure to represent - // the managed method, then create a PyCFunction. - - mdef = Runtime.PyMem_Malloc(4 * IntPtr.Size); - Marshal.WriteIntPtr(mdef, sp); - Marshal.WriteIntPtr(mdef, (1 * IntPtr.Size), fp); - Marshal.WriteIntPtr(mdef, (2 * IntPtr.Size), (IntPtr)0x0002); - Marshal.WriteIntPtr(mdef, (3 * IntPtr.Size), IntPtr.Zero); - ptr = Runtime.PyCFunction_New(mdef, IntPtr.Zero); - } - - public IntPtr Call(IntPtr args, IntPtr kw) { - return Runtime.PyCFunction_Call(ptr, args, kw); - } - - - } - - -} - diff --git a/Pythonnet.Runtime/modulefunctionobject.cs b/Pythonnet.Runtime/modulefunctionobject.cs deleted file mode 100644 index 5c9a4de21c..0000000000 --- a/Pythonnet.Runtime/modulefunctionobject.cs +++ /dev/null @@ -1,58 +0,0 @@ -// ========================================================================== -// This software is subject to the provisions of the Zope Public License, -// Version 2.0 (ZPL). A copy of the ZPL should accompany this distribution. -// THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED -// WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -// WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS -// FOR A PARTICULAR PURPOSE. -// ========================================================================== - -using System; -using System.Collections; -using System.Reflection; - -namespace Python.Runtime -{ - /// - /// Module level functions - /// - internal class ModuleFunctionObject : MethodObject - { - - public ModuleFunctionObject(string name, MethodInfo[] info, bool allow_threads) - : base(name, info, allow_threads) - { - for (int i = 0; i < info.Length; i++) - { - MethodInfo item = (MethodInfo)info[i]; - if (!item.IsStatic) - { - throw new Exception("Module function must be static."); - } - } - } - - //==================================================================== - // __call__ implementation. - //==================================================================== - - public static IntPtr tp_call(IntPtr ob, IntPtr args, IntPtr kw) - { - ModuleFunctionObject self = (ModuleFunctionObject)GetManagedObject(ob); - return self.Invoke(ob, args, kw); - } - - //==================================================================== - // __repr__ implementation. - //==================================================================== - - public static new IntPtr tp_repr(IntPtr ob) - { - ModuleFunctionObject self = (ModuleFunctionObject)GetManagedObject(ob); - string s = String.Format("", self.name); - return Runtime.PyString_FromStringAndSize(s, s.Length); - } - - } -} - diff --git a/Pythonnet.Runtime/moduleobject.cs b/Pythonnet.Runtime/moduleobject.cs deleted file mode 100644 index 3a39919477..0000000000 --- a/Pythonnet.Runtime/moduleobject.cs +++ /dev/null @@ -1,432 +0,0 @@ -// ========================================================================== -// This software is subject to the provisions of the Zope Public License, -// Version 2.0 (ZPL). A copy of the ZPL should accompany this distribution. -// THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED -// WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -// WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS -// FOR A PARTICULAR PURPOSE. -// ========================================================================== - -using System; -using System.Collections.Specialized; -using System.Runtime.InteropServices; -using System.Collections.Generic; -using System.Collections; -using System.Reflection; - -namespace Python.Runtime { - - //======================================================================== - // Implements a Python type that provides access to CLR namespaces. The - // type behaves like a Python module, and can contain other sub-modules. - //======================================================================== - - internal class ModuleObject : ExtensionType { - - Dictionary cache; - internal string moduleName; - internal IntPtr dict; - protected string _namespace; - - public ModuleObject(string name) : base() { - if (name == String.Empty) - { - throw new ArgumentException("Name must not be empty!"); - } - moduleName = name; - cache = new Dictionary(); - _namespace = name; - - dict = Runtime.PyDict_New(); - IntPtr pyname = Runtime.PyString_FromString(moduleName); - Runtime.PyDict_SetItemString(dict, "__name__", pyname); - Runtime.PyDict_SetItemString(dict, "__file__", Runtime.PyNone); - Runtime.PyDict_SetItemString(dict, "__doc__", Runtime.PyNone); - Runtime.Decref(pyname); - - Marshal.WriteIntPtr(this.pyHandle, ObjectOffset.ob_dict, dict); - - InitializeModuleMembers(); - } - - - //=================================================================== - // Returns a ClassBase object representing a type that appears in - // this module's namespace or a ModuleObject representing a child - // namespace (or null if the name is not found). This method does - // not increment the Python refcount of the returned object. - //=================================================================== - - public ManagedType GetAttribute(string name, bool guess) { - ManagedType cached = null; - this.cache.TryGetValue(name, out cached); - if (cached != null) { - return cached; - } - - ModuleObject m; - ClassBase c; - Type type; - - //if (AssemblyManager.IsValidNamespace(name)) - //{ - // IntPtr py_mod_name = Runtime.PyString_FromString(name); - // IntPtr modules = Runtime.PyImport_GetModuleDict(); - // IntPtr module = Runtime.PyDict_GetItem(modules, py_mod_name); - // if (module != IntPtr.Zero) - // return (ManagedType)this; - // return null; - //} - - string qname = (_namespace == String.Empty) ? name : - _namespace + "." + name; - - // If the fully-qualified name of the requested attribute is - // a namespace exported by a currently loaded assembly, return - // a new ModuleObject representing that namespace. - - if (AssemblyManager.IsValidNamespace(qname)) { - m = new ModuleObject(qname); - StoreAttribute(name, m); - return (ManagedType) m; - } - - // Look for a type in the current namespace. Note that this - // includes types, delegates, enums, interfaces and structs. - // Only public namespace members are exposed to Python. - - type = AssemblyManager.LookupType(qname); - if (type != null) { - if (!type.IsPublic) { - return null; - } - c = ClassManager.GetClass(type); - StoreAttribute(name, c); - return (ManagedType) c; - } - - // This is a little repetitive, but it ensures that the right - // thing happens with implicit assembly loading at a reasonable - // cost. Ask the AssemblyManager to do implicit loading for each - // of the steps in the qualified name, then try it again. - bool fromFile; - if (AssemblyManager.LoadImplicit(qname, out fromFile)) { - bool ignore = name.StartsWith("__"); - if (true == fromFile && (!ignore)) { - string deprWarning = String.Format("\nThe module was found, but not in a referenced namespace.\n" + - "Implicit loading is deprecated. Please use clr.AddReference(\"{0}\").", qname); - Exceptions.deprecation(deprWarning); - } - if (AssemblyManager.IsValidNamespace(qname)) { - m = new ModuleObject(qname); - StoreAttribute(name, m); - return (ManagedType) m; - } - - type = AssemblyManager.LookupType(qname); - if (type != null) { - if (!type.IsPublic) { - return null; - } - c = ClassManager.GetClass(type); - StoreAttribute(name, c); - return (ManagedType) c; - } - } - - // We didn't find the name, so we may need to see if there is a - // generic type with this base name. If so, we'll go ahead and - // return it. Note that we store the mapping of the unmangled - // name to generic type - it is technically possible that some - // future assembly load could contribute a non-generic type to - // the current namespace with the given basename, but unlikely - // enough to complicate the implementation for now. - - if (guess) { - string gname = GenericUtil.GenericNameForBaseName( - _namespace, name); - if (gname != null) { - ManagedType o = GetAttribute(gname, false); - if (o != null) { - StoreAttribute(name, o); - return o; - } - } - } - - return null; - } - - - //=================================================================== - // Stores an attribute in the instance dict for future lookups. - //=================================================================== - - private void StoreAttribute(string name, ManagedType ob) { - Runtime.PyDict_SetItemString(dict, name, ob.pyHandle); - cache[name] = ob; - } - - - //=================================================================== - // Preloads all currently-known names for the module namespace. This - // can be called multiple times, to add names from assemblies that - // may have been loaded since the last call to the method. - //=================================================================== - - public void LoadNames() { - ManagedType m = null; - foreach (string name in AssemblyManager.GetNames(_namespace)) { - this.cache.TryGetValue(name, out m); - if (m == null) { - ManagedType attr = this.GetAttribute(name, true); - if (Runtime.wrap_exceptions) { - if (attr is ExceptionClassObject) { - ExceptionClassObject c = attr as ExceptionClassObject; - if (c != null) { - IntPtr p = attr.pyHandle; - IntPtr r =Exceptions.GetExceptionClassWrapper(p); - Runtime.PyDict_SetItemString(dict, name, r); - Runtime.Incref(r); - - } - } - } - } - } - } - - /// - /// Initialize module level functions and attributes - /// - internal void InitializeModuleMembers() - { - Type funcmarker = typeof(ModuleFunctionAttribute); - Type propmarker = typeof(ModulePropertyAttribute); - Type ftmarker = typeof(ForbidPythonThreadsAttribute); - Type type = this.GetType(); - - BindingFlags flags = BindingFlags.Public | BindingFlags.Static; - - while (type != null) - { - MethodInfo[] methods = type.GetMethods(flags); - for (int i = 0; i < methods.Length; i++) - { - MethodInfo method = methods[i]; - object[] attrs = method.GetCustomAttributes(funcmarker, false); - object[] forbid = method.GetCustomAttributes(ftmarker, false); - bool allow_threads = (forbid.Length == 0); - if (attrs.Length > 0) - { - string name = method.Name; - MethodInfo[] mi = new MethodInfo[1]; - mi[0] = method; - ModuleFunctionObject m = new ModuleFunctionObject(name, mi, allow_threads); - StoreAttribute(name, m); - } - } - - PropertyInfo[] properties = type.GetProperties(); - for (int i = 0; i < properties.Length; i++) - { - PropertyInfo property = properties[i]; - object[] attrs = property.GetCustomAttributes(propmarker, false); - if (attrs.Length > 0) - { - string name = property.Name; - ModulePropertyObject p = new ModulePropertyObject(property); - StoreAttribute(name, p); - } - } - type = type.BaseType; - } - } - - - //==================================================================== - // ModuleObject __getattribute__ implementation. Module attributes - // are always either classes or sub-modules representing subordinate - // namespaces. CLR modules implement a lazy pattern - the sub-modules - // and classes are created when accessed and cached for future use. - //==================================================================== - - public static IntPtr tp_getattro(IntPtr ob, IntPtr key) { - ModuleObject self = (ModuleObject)GetManagedObject(ob); - - if (!Runtime.PyString_Check(key)) { - Exceptions.SetError(Exceptions.TypeError, "string expected"); - return IntPtr.Zero; - } - - IntPtr op = Runtime.PyDict_GetItem(self.dict, key); - if (op != IntPtr.Zero) { - Runtime.Incref(op); - return op; - } - - string name = Runtime.GetManagedString(key); - if (name == "__dict__") { - Runtime.Incref(self.dict); - return self.dict; - } - - ManagedType attr = self.GetAttribute(name, true); - - if (attr == null) { - Exceptions.SetError(Exceptions.AttributeError, name); - return IntPtr.Zero; - } - - // XXX - hack required to recognize exception types. These types - // may need to be wrapped in old-style class wrappers in versions - // of Python where new-style classes cannot be used as exceptions. - - if (Runtime.wrap_exceptions) { - if (attr is ExceptionClassObject) { - ExceptionClassObject c = attr as ExceptionClassObject; - if (c != null) { - IntPtr p = attr.pyHandle; - IntPtr r = Exceptions.GetExceptionClassWrapper(p); - Runtime.PyDict_SetItemString(self.dict, name, r); - Runtime.Incref(r); - return r; - } - } - } - - Runtime.Incref(attr.pyHandle); - return attr.pyHandle; - } - - //==================================================================== - // ModuleObject __repr__ implementation. - //==================================================================== - - public static IntPtr tp_repr(IntPtr ob) { - ModuleObject self = (ModuleObject)GetManagedObject(ob); - string s = String.Format("", self.moduleName); - return Runtime.PyString_FromString(s); - } - - - - } - - /// - /// The CLR module is the root handler used by the magic import hook - /// to import assemblies. It has a fixed module name "clr" and doesn't - /// provide a namespace. - /// - internal class CLRModule : ModuleObject - { - protected static bool hacked = false; - protected static bool interactive_preload = true; - internal static bool preload; - // XXX Test performance of new features // - internal static bool _SuppressDocs = false; - internal static bool _SuppressOverloads = false; - - public CLRModule() : base("clr") { - _namespace = String.Empty; - - // This hackery is required in order to allow a plain Python to - // import the managed runtime via the CLR bootstrapper module. - // The standard Python machinery in control at the time of the - // import requires the module to pass PyModule_Check. :( - if (!hacked) - { - IntPtr type = this.tpHandle; - IntPtr mro = Marshal.ReadIntPtr(type, TypeOffset.tp_mro); - IntPtr ext = Runtime.ExtendTuple(mro, Runtime.PyModuleType); - Marshal.WriteIntPtr(type, TypeOffset.tp_mro, ext); - Runtime.Decref(mro); - hacked = true; - } - } - - /// - /// The initializing of the preload hook has to happen as late as - /// possible since sys.ps1 is created after the CLR module is - /// created. - /// - internal void InitializePreload() { - if (interactive_preload) { - interactive_preload = false; - if (Runtime.PySys_GetObject("ps1") != IntPtr.Zero) { - preload = true; - } else { - Exceptions.Clear(); - preload = false; - } - } - } - - [ModuleFunctionAttribute()] - public static bool getPreload() { - return preload; - } - - [ModuleFunctionAttribute()] - public static void setPreload(bool preloadFlag) - { - preload = preloadFlag; - } - - //[ModulePropertyAttribute] - public static bool SuppressDocs { - get { return _SuppressDocs; } - set { _SuppressDocs = value; } - } - - //[ModulePropertyAttribute] - public static bool SuppressOverloads { - get { return _SuppressOverloads; } - set { _SuppressOverloads = value; } - } - - [ModuleFunctionAttribute()] - [ForbidPythonThreadsAttribute()] - public static Assembly AddReference(string name) - { - AssemblyManager.UpdatePath(); - Assembly assembly = null; - assembly = AssemblyManager.LoadAssemblyPath(name); - if (assembly == null) - { - assembly = AssemblyManager.LoadAssembly(name); - } - if (assembly == null) - { - string msg = String.Format("Unable to find assembly '{0}'.", name); - throw new System.IO.FileNotFoundException(msg); - } - return assembly ; - } - - [ModuleFunctionAttribute()] - [ForbidPythonThreadsAttribute()] - public static string FindAssembly(string name) - { - AssemblyManager.UpdatePath(); - return AssemblyManager.FindAssembly(name); - } - - [ModuleFunctionAttribute()] - public static String[] ListAssemblies(bool verbose) - { - AssemblyName[] assnames = AssemblyManager.ListAssemblies(); - String[] names = new String[assnames.Length]; - for (int i = 0; i < assnames.Length; i++) - { - if (verbose) - names[i] = assnames[i].FullName; - else - names[i] = assnames[i].Name; - } - return names; - } - - } - -} diff --git a/Pythonnet.Runtime/modulepropertyobject.cs b/Pythonnet.Runtime/modulepropertyobject.cs deleted file mode 100644 index f833696bf8..0000000000 --- a/Pythonnet.Runtime/modulepropertyobject.cs +++ /dev/null @@ -1,30 +0,0 @@ -// ========================================================================== -// This software is subject to the provisions of the Zope Public License, -// Version 2.0 (ZPL). A copy of the ZPL should accompany this distribution. -// THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED -// WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -// WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS -// FOR A PARTICULAR PURPOSE. -// ========================================================================== - -using System; -using System.Collections; -using System.Reflection; -using System.Security.Permissions; - -namespace Python.Runtime { - - /// - /// Module level properties (attributes) - /// - internal class ModulePropertyObject : ExtensionType { - - public ModulePropertyObject(PropertyInfo md) : base() - { - throw new NotImplementedException("ModulePropertyObject"); - } - - } - -} - diff --git a/Pythonnet.Runtime/monosupport.cs b/Pythonnet.Runtime/monosupport.cs deleted file mode 100644 index 6208b498ec..0000000000 --- a/Pythonnet.Runtime/monosupport.cs +++ /dev/null @@ -1,60 +0,0 @@ -// ========================================================================== -// This software is subject to the provisions of the Zope Public License, -// Version 2.0 (ZPL). A copy of the ZPL should accompany this distribution. -// THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED -// WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -// WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS -// FOR A PARTICULAR PURPOSE. -// ========================================================================== - -#if (UCS4) -using System; -using System.Runtime.InteropServices; -using System.Text; -using Mono.Unix; - -namespace Python.Runtime { - // The Utf32Marshaler was written Jonathan Pryor and has been placed - // in the PUBLIC DOMAIN. - public class Utf32Marshaler : ICustomMarshaler { - private static Utf32Marshaler instance = new - Utf32Marshaler (); - - public static ICustomMarshaler GetInstance (string s) - { - return instance; - } - - public void CleanUpManagedData (object o) - { - } - - public void CleanUpNativeData (IntPtr pNativeData) - { - UnixMarshal.FreeHeap (pNativeData); - } - - public int GetNativeDataSize () - { - return IntPtr.Size; - } - - public IntPtr MarshalManagedToNative (object obj) - { - string s = obj as string; - if (s == null) - return IntPtr.Zero; - return UnixMarshal.StringToHeap (s, - Encoding.UTF32); - } - - public object MarshalNativeToManaged (IntPtr - pNativeData) - { - return UnixMarshal.PtrToString (pNativeData, - Encoding.UTF32); - } - } -} -#endif - diff --git a/Pythonnet.Runtime/nativecall.cs b/Pythonnet.Runtime/nativecall.cs deleted file mode 100644 index d2c4bf5b3a..0000000000 --- a/Pythonnet.Runtime/nativecall.cs +++ /dev/null @@ -1,166 +0,0 @@ -// ========================================================================== -// This software is subject to the provisions of the Zope Public License, -// Version 2.0 (ZPL). A copy of the ZPL should accompany this distribution. -// THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED -// WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -// WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS -// FOR A PARTICULAR PURPOSE. -// ========================================================================== - -using System; -using System.Threading; -using System.Runtime.InteropServices; -using System.Collections; -using System.Reflection; -using System.Reflection.Emit; - -namespace Python.Runtime { - - /// - /// Provides support for calling native code indirectly through - /// function pointers. Most of the important parts of the Python - /// C API can just be wrapped with p/invoke, but there are some - /// situations (specifically, calling functions through Python - /// type structures) where we need to call functions indirectly. - /// - /// This class uses Reflection.Emit to generate IJW thunks that - /// support indirect calls to native code using various common - /// call signatures. This is mainly a workaround for the fact - /// that you can't spell an indirect call in C# (but can in IL). - /// - /// Another approach that would work is for this to be turned - /// into a separate utility program that could be run during the - /// build process to generate the thunks as a separate assembly - /// that could then be referenced by the main Python runtime. - /// - - internal class NativeCall { - - static AssemblyBuilder aBuilder; - static ModuleBuilder mBuilder; - - public static INativeCall Impl; - - static NativeCall() { - - // The static constructor is responsible for generating the - // assembly and the methods that implement the IJW thunks. - // - // To do this, we actually use reflection on the INativeCall - // interface (defined below) and generate the required thunk - // code based on the method signatures. - - AssemblyName aname = new AssemblyName(); - aname.Name = "e__NativeCall_Assembly"; - AssemblyBuilderAccess aa = AssemblyBuilderAccess.Run; - - aBuilder = Thread.GetDomain().DefineDynamicAssembly(aname, aa); - mBuilder = aBuilder.DefineDynamicModule("e__NativeCall_Module"); - - TypeAttributes ta = TypeAttributes.Public; - TypeBuilder tBuilder = mBuilder.DefineType("e__NativeCall", ta); - - Type iType = typeof(INativeCall); - tBuilder.AddInterfaceImplementation(iType); - - // Use reflection to loop over the INativeCall interface methods, - // calling GenerateThunk to create a managed thunk for each one. - - foreach (MethodInfo method in iType.GetMethods()) { - GenerateThunk(tBuilder, method); - } - - Type theType = tBuilder.CreateType(); - - Impl = (INativeCall)Activator.CreateInstance(theType); - - } - - private static void GenerateThunk(TypeBuilder tb, MethodInfo method) { - - ParameterInfo[] pi = method.GetParameters(); - int count = pi.Length; - int argc = count - 1; - - Type[] args = new Type[count]; - for (int i = 0; i < count; i++) { - args[i] = pi[i].ParameterType; - } - - MethodBuilder mb = tb.DefineMethod( - method.Name, - MethodAttributes.Public | - MethodAttributes.Virtual, - method.ReturnType, - args - ); - - // Build the method signature for the actual native function. - // This is essentially the signature of the wrapper method - // minus the first argument (the passed in function pointer). - - Type[] nargs = new Type[argc]; - for (int i = 1; i < count; i++) { - nargs[(i - 1)] = args[i]; - } - - // IL generation: the (implicit) first argument of the method - // is the 'this' pointer and the second is the function pointer. - // This code pushes the real args onto the stack, followed by - // the function pointer, then the calli opcode to make the call. - - ILGenerator il = mb.GetILGenerator(); - - for (int i = 0; i < argc; i++) { - il.Emit(OpCodes.Ldarg_S, (i + 2)); - } - - il.Emit(OpCodes.Ldarg_1); - - il.EmitCalli(OpCodes.Calli, - CallingConvention.Cdecl, - method.ReturnType, - nargs - ); - - il.Emit(OpCodes.Ret); - - tb.DefineMethodOverride(mb, method); - return; - } - - - public static void Void_Call_1(IntPtr fp, IntPtr a1) { - Impl.Void_Call_1(fp, a1); - } - - public static IntPtr Call_3(IntPtr fp, IntPtr a1, IntPtr a2, - IntPtr a3) { - return Impl.Call_3(fp, a1, a2, a3); - } - - public static int Int_Call_3(IntPtr fp, IntPtr a1, IntPtr a2, - IntPtr a3) { - return Impl.Int_Call_3(fp, a1, a2, a3); - } - - } - - - /// - /// Defines native call signatures to be generated by NativeCall. - /// - - public interface INativeCall { - - void Void_Call_0(IntPtr funcPtr); - - void Void_Call_1(IntPtr funcPtr, IntPtr arg1); - - int Int_Call_3(IntPtr funcPtr, IntPtr t, IntPtr n, IntPtr v); - - IntPtr Call_3(IntPtr funcPtr, IntPtr a1, IntPtr a2, IntPtr a3); - - } - -} diff --git a/Pythonnet.Runtime/oldmodule.il b/Pythonnet.Runtime/oldmodule.il deleted file mode 100644 index 6ecd2c1363..0000000000 --- a/Pythonnet.Runtime/oldmodule.il +++ /dev/null @@ -1,274 +0,0 @@ -// ========================================================================== -// This software is subject to the provisions of the Zope Public License, -// Version 2.0 (ZPL). A copy of the ZPL should accompany this distribution. -// THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED -// WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -// WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS -// FOR A PARTICULAR PURPOSE. -// ========================================================================== - -//============================================================================ -// This file is a hand-maintained stub - it implements clr.dll, which can be -// loaded by a standard CPython interpreter as an extension module. When it -// is loaded, it bootstraps the managed runtime integration layer and defers -// to it to do initialization and put the clr module into sys.modules, etc. - -// The "USE_PYTHON_RUNTIME_*" defines control what extra evidence is used -// to help the CLR find the appropriate Python.Runtime assembly. - -// If defined, the "pythonRuntimeVersionString" variable must be set to -// Python.Runtime's current version. -#define USE_PYTHON_RUNTIME_VERSION - -// If defined, the "PythonRuntimePublicKeyTokenData" data array must be -// set to Python.Runtime's public key token. -//#define USE_PYTHON_RUNTIME_PUBLIC_KEY_TOKEN - -// If DEBUG_PRINT is defined, a few System.Console.WriteLine calls are made -// to indicate what's going on during the load... -//#define DEBUG_PRINT -//============================================================================ - -.assembly extern mscorlib -{ - .publickeytoken = (B7 7A 5C 56 19 34 E0 89 ) - .ver 2:0:0:0 -} - -.assembly clr -{ - .hash algorithm 0x00008004 - .ver 2:0:0:2 -} - -.module clr.dll -.imagebase 0x00400000 -.subsystem 0x00000003 -.file alignment 512 - -// This includes the platform-specific IL. The include search path -// is set depending on whether we're compiling 32 or 64 bit. -// This MUST come before any other .data directives! -// Why, oh why, can't ilasm support command line #defines? :( -#include "clrmodule-platform.il" - -#ifdef USE_PYTHON_RUNTIME_PUBLIC_KEY_TOKEN -.data PythonRuntimePublicKeyTokenData = bytearray (64 e1 4e 84 5a bf 2e 60) -#endif - -.class public auto ansi beforefieldinit clrModule extends [mscorlib]System.Object -{ -#ifdef USE_PYTHON_RUNTIME_PUBLIC_KEY_TOKEN - .field static assembly int64 PythonRuntimePublicKeyToken at PythonRuntimePublicKeyTokenData -#endif - - .method public hidebysig specialname rtspecialname instance void - .ctor() cil managed - { - .maxstack 1 - ldarg.0 - call instance void [mscorlib]System.Object::.ctor() - ret - } - - .method public hidebysig static void modopt([mscorlib]System.Runtime.CompilerServices.CallConvCdecl) - initclr() cil managed - { - .vtentry 1:1 - .export [1] as initclr - - .maxstack 6 - .locals init ( - class [mscorlib]System.Reflection.Assembly pythonRuntime, - class [mscorlib]System.Reflection.Assembly executingAssembly, - class [mscorlib]System.Reflection.AssemblyName pythonRuntimeName, - class [mscorlib]System.Type pythonEngineType, - int8[] publicKeyToken, - string assemblyDirectory, - string pythonRuntimeVersionString, - string pythonRuntimeDllPath) - - // pythonRuntime = null; - ldnull - stloc pythonRuntime - - .try - { -#ifdef DEBUG_PRINT - ldstr "Attempting to load Python.Runtime using standard binding rules... " - call void [mscorlib]System.Console::Write(string) -#endif - - // Attempt to find and load Python.Runtime using standard assembly binding rules. - // This roughly translates into looking in order: - // - GAC - // - ApplicationBase - // - A PrivateBinPath under ApplicationBase - // With an unsigned assembly, the GAC is skipped. - - // System.Reflection.AssemblyName pythonRuntimeName = new System.Reflection.AssemblyName(); - newobj instance void [mscorlib]System.Reflection.AssemblyName::.ctor() - stloc pythonRuntimeName - - // pythonRuntimeName.Name = "Python.Runtime"; - ldloc pythonRuntimeName - ldstr "Python.Runtime" - callvirt instance void [mscorlib]System.Reflection.AssemblyName::set_Name(string) - -#ifdef USE_PYTHON_RUNTIME_VERSION - // pythonRuntimeVersionString = "..."; - ldstr "2.0.0.2" - stloc pythonRuntimeVersionString - - // pythonRuntimeName.Version = new Version(pythonRuntimeVersionString); - ldloc pythonRuntimeName - ldloc pythonRuntimeVersionString - newobj instance void [mscorlib]System.Version::.ctor(string) - callvirt instance void [mscorlib]System.Reflection.AssemblyName::set_Version(class [mscorlib]System.Version) -#endif - -#ifdef USE_PYTHON_RUNTIME_PUBLIC_KEY_TOKEN - // publicKeyToken = new byte[] { ... }; - ldc.i4.8 - newarr [mscorlib]System.Byte - dup - ldtoken field int64 clrModule::PythonRuntimePublicKeyToken - call void [mscorlib]System.Runtime.CompilerServices.RuntimeHelpers::InitializeArray(class [mscorlib]System.Array, valuetype [mscorlib]System.RuntimeFieldHandle) - stloc publicKeyToken - - // pythonRuntimeName.SetPublicKeyToken(publicKeyToken); - ldloc pythonRuntimeName - ldloc publicKeyToken - callvirt instance void [mscorlib]System.Reflection.AssemblyName::SetPublicKeyToken(uint8[]) -#endif - - // pythonRuntimeName.CultureInfo = System.Globalization.CultureInfo.InvariantCulture; - ldloc pythonRuntimeName - call class [mscorlib]System.Globalization.CultureInfo [mscorlib]System.Globalization.CultureInfo::get_InvariantCulture() - callvirt instance void [mscorlib]System.Reflection.AssemblyName::set_CultureInfo(class [mscorlib]System.Globalization.CultureInfo) - - // return System.Reflection.Assembly.Load(pythonRuntimeName); - ldloc pythonRuntimeName - call class [mscorlib]System.Reflection.Assembly [mscorlib]System.Reflection.Assembly::Load(class [mscorlib]System.Reflection.AssemblyName) - stloc pythonRuntime - -#ifdef DEBUG_PRINT - ldstr "Success!" - call void [mscorlib]System.Console::WriteLine(string) -#endif - leave.s LOADED_PYTHON_RUNTIME - } - catch [mscorlib]System.Object - { -#ifdef DEBUG_PRINT - ldstr "Failed." - call void [mscorlib]System.Console::WriteLine(string) -#endif - leave.s EXIT_CLR_LOAD - } - EXIT_CLR_LOAD: nop - - .try - { - // If the above fails for any reason, we fallback to attempting to load "Python.Runtime.dll" - // from the directory this assembly is running in. "This assembly" is probably "clr.pyd", - // sitting somewhere in PYTHONPATH. This is using Assembly.LoadFrom, and inherits all the - // caveats of that call. See MSDN docs for details. - // Suzanne Cook's blog is also an excellent source of info on this: - // http://blogs.msdn.com/suzcook/ - // http://blogs.msdn.com/suzcook/archive/2003/05/29/57143.aspx - // http://blogs.msdn.com/suzcook/archive/2003/06/13/57180.aspx - // executingAssembly = System.Reflection.Assembly.GetExecutingAssembly(); - call class [mscorlib]System.Reflection.Assembly [mscorlib]System.Reflection.Assembly::GetExecutingAssembly() - stloc executingAssembly - - // assemblyDirectory = System.IO.Path.GetDirectoryName(executingAssembly.Location); - ldloc executingAssembly - callvirt instance string [mscorlib]System.Reflection.Assembly::get_Location() - call string [mscorlib]System.IO.Path::GetDirectoryName(string) - stloc assemblyDirectory - - // pythonRuntimeDllPath = System.IO.Path.Combine(assemblyDirectory, "Python.Runtime.dll"); - ldloc assemblyDirectory - ldstr "Python.Runtime.dll" - call string [mscorlib]System.IO.Path::Combine(string, string) - stloc pythonRuntimeDllPath - -#ifdef DEBUG_PRINT - ldstr "Attempting to load Python.Runtime from: '{0}'... " - ldloc pythonRuntimeDllPath - call void [mscorlib]System.Console::Write(string, object) -#endif - - // pythonRuntime = System.Reflection.Assembly.LoadFrom(pythonRuntimeDllPath); - ldloc pythonRuntimeDllPath - call class [mscorlib]System.Reflection.Assembly [mscorlib]System.Reflection.Assembly::LoadFrom(string) - stloc pythonRuntime - -#ifdef DEBUG_PRINT - ldstr "Success!" - call void [mscorlib]System.Console::WriteLine(string) -#endif - leave.s LOADED_PYTHON_RUNTIME - } - catch [mscorlib]System.Object - { -#ifdef DEBUG_PRINT - ldstr "Failed." - call void [mscorlib]System.Console::WriteLine(string) -#endif - leave.s EXIT_PYTHONPATH_LOAD - } - EXIT_PYTHONPATH_LOAD: nop - - // If we get here, we haven't loaded Python.Runtime, so bail. -#ifdef DEBUG_PRINT - ldstr "Could not load Python.Runtime, so sad." - call void [mscorlib]System.Console::WriteLine(string) -#endif - ret; - - // Once here, we've successfully loaded SOME version of Python.Runtime - // So now we get the PythonEngine and execute the InitExt method on it. - LOADED_PYTHON_RUNTIME: nop - .try - { -#ifdef DEBUG_PRINT - ldstr "Running Python.Runtime.PythonEngine.InitExt()" - call void [mscorlib]System.Console::WriteLine(string) -#endif - // pythonEngineType = pythonRuntime.GetType("Python.Runtime.PythonEngine"); - ldloc pythonRuntime - ldstr "Python.Runtime.PythonEngine" - callvirt instance class [mscorlib]System.Type [mscorlib]System.Reflection.Assembly::GetType(string) - stloc pythonEngineType - - // pythonEngineType.InvokeMember("InitExt", System.Reflection.BindingFlags.InvokeMethod, null, null, null); - ldloc pythonEngineType - ldstr "InitExt" - ldc.i4 0x100 - ldnull - ldnull - ldnull - callvirt instance object [mscorlib]System.Type::InvokeMember( string, - valuetype [mscorlib]System.Reflection.BindingFlags, - class [mscorlib]System.Reflection.Binder, - object, - object[]) - pop - leave.s EXIT_TRY_INVOKE - } - catch [mscorlib]System.Object - { -#ifdef DEBUG_PRINT - ldstr "Error calling Python.Runtime.PythonEngine.InitExt()." - call void [mscorlib]System.Console::WriteLine(string) -#endif - leave.s EXIT_TRY_INVOKE - } - EXIT_TRY_INVOKE: nop - - ret - } -} - diff --git a/Pythonnet.Runtime/overload.cs b/Pythonnet.Runtime/overload.cs deleted file mode 100644 index 0b7ef248cc..0000000000 --- a/Pythonnet.Runtime/overload.cs +++ /dev/null @@ -1,83 +0,0 @@ -// ========================================================================== -// This software is subject to the provisions of the Zope Public License, -// Version 2.0 (ZPL). A copy of the ZPL should accompany this distribution. -// THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED -// WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -// WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS -// FOR A PARTICULAR PURPOSE. -// ========================================================================== - -using System; -using System.Reflection; - -namespace Python.Runtime { - - //======================================================================== - // Implements the __overloads__ attribute of method objects. This object - // supports the [] syntax to explicitly select an overload by signature. - //======================================================================== - - internal class OverloadMapper : ExtensionType { - - MethodObject m; - IntPtr target; - - public OverloadMapper(MethodObject m, IntPtr target) : base() { - Runtime.Incref(target); - this.target = target; - this.m = m; - } - - //==================================================================== - // Implement explicit overload selection using subscript syntax ([]). - //==================================================================== - - public static IntPtr mp_subscript(IntPtr tp, IntPtr idx) { - OverloadMapper self = (OverloadMapper)GetManagedObject(tp); - - // Note: if the type provides a non-generic method with N args - // and a generic method that takes N params, then we always - // prefer the non-generic version in doing overload selection. - - Type[] types = Runtime.PythonArgsToTypeArray(idx); - if (types == null) { - return Exceptions.RaiseTypeError("type(s) expected"); - } - - MethodInfo mi = MethodBinder.MatchSignature(self.m.info, types); - if (mi == null) { - string e = "No match found for signature"; - return Exceptions.RaiseTypeError(e); - } - - MethodBinding mb = new MethodBinding(self.m, self.target); - mb.info = mi; - Runtime.Incref(mb.pyHandle); - return mb.pyHandle; - } - - //==================================================================== - // OverloadMapper __repr__ implementation. - //==================================================================== - - public static IntPtr tp_repr(IntPtr op) { - OverloadMapper self = (OverloadMapper)GetManagedObject(op); - IntPtr doc = self.m.GetDocString(); - Runtime.Incref(doc); - return doc; - } - - //==================================================================== - // OverloadMapper dealloc implementation. - //==================================================================== - - public static new void tp_dealloc(IntPtr ob) { - OverloadMapper self = (OverloadMapper)GetManagedObject(ob); - Runtime.Decref(self.target); - ExtensionType.FinalizeObject(self); - } - - } - - -} diff --git a/Pythonnet.Runtime/propertyobject.cs b/Pythonnet.Runtime/propertyobject.cs deleted file mode 100644 index d61dc01344..0000000000 --- a/Pythonnet.Runtime/propertyobject.cs +++ /dev/null @@ -1,164 +0,0 @@ -// ========================================================================== -// This software is subject to the provisions of the Zope Public License, -// Version 2.0 (ZPL). A copy of the ZPL should accompany this distribution. -// THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED -// WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -// WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS -// FOR A PARTICULAR PURPOSE. -// ========================================================================== - -using System; -using System.Collections; -using System.Reflection; -using System.Security.Permissions; - -namespace Python.Runtime { - - //======================================================================== - // Implements a Python descriptor type that manages CLR properties. - //======================================================================== - - internal class PropertyObject : ExtensionType { - - PropertyInfo info; - MethodInfo getter; - MethodInfo setter; - - [StrongNameIdentityPermissionAttribute(SecurityAction.Assert)] - public PropertyObject(PropertyInfo md) : base() { - getter = md.GetGetMethod(true); - setter = md.GetSetMethod(true); - info = md; - } - - - //==================================================================== - // Descriptor __get__ implementation. This method returns the - // value of the property on the given object. The returned value - // is converted to an appropriately typed Python object. - //==================================================================== - - public static IntPtr tp_descr_get(IntPtr ds, IntPtr ob, IntPtr tp) { - PropertyObject self = (PropertyObject)GetManagedObject(ds); - MethodInfo getter = self.getter; - Object result; - - - if (getter == null) { - return Exceptions.RaiseTypeError("property cannot be read"); - } - - if ((ob == IntPtr.Zero) || (ob == Runtime.PyNone)) { - if (!(getter.IsStatic)) { - Exceptions.SetError(Exceptions.TypeError, - "instance property must be accessed through " + - "a class instance" - ); - return IntPtr.Zero; - } - - try { - result = self.info.GetValue(null, null); - return Converter.ToPython(result, self.info.PropertyType); - } - catch(Exception e) { - return Exceptions.RaiseTypeError(e.Message); - } - } - - CLRObject co = GetManagedObject(ob) as CLRObject; - if (co == null) { - return Exceptions.RaiseTypeError("invalid target"); - } - - try { - result = self.info.GetValue(co.inst, null); - return Converter.ToPython(result, self.info.PropertyType); - } - catch(Exception e) { - if (e.InnerException != null) { - e = e.InnerException; - } - Exceptions.SetError(e); - return IntPtr.Zero; - } - } - - - //==================================================================== - // Descriptor __set__ implementation. This method sets the value of - // a property based on the given Python value. The Python value must - // be convertible to the type of the property. - //==================================================================== - - public static new int tp_descr_set(IntPtr ds, IntPtr ob, IntPtr val) { - PropertyObject self = (PropertyObject)GetManagedObject(ds); - MethodInfo setter = self.setter; - Object newval; - - if (val == IntPtr.Zero) { - Exceptions.RaiseTypeError("cannot delete property"); - return -1; - } - - if (setter == null) { - Exceptions.RaiseTypeError("property is read-only"); - return -1; - } - - - if (!Converter.ToManaged(val, self.info.PropertyType, out newval, - true)) { - return -1; - } - - bool is_static = setter.IsStatic; - - if ((ob == IntPtr.Zero) || (ob == Runtime.PyNone)) { - if (!(is_static)) { - Exceptions.RaiseTypeError( - "instance property must be set on an instance" - ); - return -1; - } - } - - try { - if (!is_static) { - CLRObject co = GetManagedObject(ob) as CLRObject; - if (co == null) { - Exceptions.RaiseTypeError("invalid target"); - return -1; - } - self.info.SetValue(co.inst, newval, null); - } - else { - self.info.SetValue(null, newval, null); - } - return 0; - } - catch(Exception e) { - if (e.InnerException != null) { - e = e.InnerException; - } - Exceptions.SetError(e); - return -1; - } - - } - - - //==================================================================== - // Descriptor __repr__ implementation. - //==================================================================== - - public static IntPtr tp_repr(IntPtr ob) { - PropertyObject self = (PropertyObject)GetManagedObject(ob); - string s = String.Format("", self.info.Name); - return Runtime.PyString_FromStringAndSize(s, s.Length); - } - - } - - -} diff --git a/Pythonnet.Runtime/pyansistring.cs b/Pythonnet.Runtime/pyansistring.cs deleted file mode 100644 index db8e249a16..0000000000 --- a/Pythonnet.Runtime/pyansistring.cs +++ /dev/null @@ -1,82 +0,0 @@ -// ========================================================================== -// This is a user contribution to the pythondotnet project. -// THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED -// WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -// WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS -// FOR A PARTICULAR PURPOSE. -// ========================================================================== - -using System; - -namespace Python.Runtime { - - public class PyAnsiString : PySequence - { - /// - /// PyAnsiString Constructor - /// - /// - /// - /// Creates a new PyAnsiString from an existing object reference. Note - /// that the instance assumes ownership of the object reference. - /// The object reference is not checked for type-correctness. - /// - - public PyAnsiString(IntPtr ptr) : base(ptr) { } - - - /// - /// PyString Constructor - /// - /// - /// - /// Copy constructor - obtain a PyAnsiString from a generic PyObject. - /// An ArgumentException will be thrown if the given object is not - /// a Python string object. - /// - - public PyAnsiString(PyObject o) - : base() - { - if (!IsStringType(o)) - { - throw new ArgumentException("object is not a string"); - } - Runtime.Incref(o.obj); - obj = o.obj; - } - - - /// - /// PyAnsiString Constructor - /// - /// - /// - /// Creates a Python string from a managed string. - /// - - public PyAnsiString(string s) - : base() - { - obj = Runtime.PyString_FromStringAndSize(s, s.Length); - if (obj == IntPtr.Zero) - { - throw new PythonException(); - } - } - - - /// - /// IsStringType Method - /// - /// - /// - /// Returns true if the given object is a Python string. - /// - - public static bool IsStringType(PyObject value) - { - return Runtime.PyString_Check(value.obj); - } - } -} \ No newline at end of file diff --git a/Pythonnet.Runtime/pydict.cs b/Pythonnet.Runtime/pydict.cs deleted file mode 100644 index cd85c7126d..0000000000 --- a/Pythonnet.Runtime/pydict.cs +++ /dev/null @@ -1,208 +0,0 @@ -// ========================================================================== -// This software is subject to the provisions of the Zope Public License, -// Version 2.0 (ZPL). A copy of the ZPL should accompany this distribution. -// THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED -// WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -// WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS -// FOR A PARTICULAR PURPOSE. -// ========================================================================== - -using System; -using System.Runtime.InteropServices; - -namespace Python.Runtime { - - /// - /// Represents a Python dictionary object. See the documentation at - /// http://www.python.org/doc/current/api/dictObjects.html for details. - /// - - public class PyDict : PyObject { - - /// - /// PyDict Constructor - /// - /// - /// - /// Creates a new PyDict from an existing object reference. Note - /// that the instance assumes ownership of the object reference. - /// The object reference is not checked for type-correctness. - /// - - public PyDict(IntPtr ptr) : base(ptr) {} - - - /// - /// PyDict Constructor - /// - /// - /// - /// Creates a new Python dictionary object. - /// - - public PyDict() : base() { - obj = Runtime.PyDict_New(); - if (obj == IntPtr.Zero) { - throw new PythonException(); - } - } - - - /// - /// PyDict Constructor - /// - /// - /// - /// Copy constructor - obtain a PyDict from a generic PyObject. An - /// ArgumentException will be thrown if the given object is not a - /// Python dictionary object. - /// - - public PyDict(PyObject o) : base() { - if (!IsDictType(o)) { - throw new ArgumentException("object is not a dict"); - } - Runtime.Incref(o.obj); - obj = o.obj; - } - - - /// - /// IsDictType Method - /// - /// - /// - /// Returns true if the given object is a Python dictionary. - /// - - public static bool IsDictType(PyObject value) { - return Runtime.PyDict_Check(value.obj); - } - - - /// - /// HasKey Method - /// - /// - /// - /// Returns true if the object key appears in the dictionary. - /// - - public bool HasKey(PyObject key) { - return (Runtime.PyMapping_HasKey(obj, key.obj) != 0); - } - - - /// - /// HasKey Method - /// - /// - /// - /// Returns true if the string key appears in the dictionary. - /// - - public bool HasKey(string key) { - return HasKey(new PyString(key)); - } - - - /// - /// Keys Method - /// - /// - /// - /// Returns a sequence containing the keys of the dictionary. - /// - - public PyObject Keys() { - IntPtr items = Runtime.PyDict_Keys(obj); - if (items == IntPtr.Zero) { - throw new PythonException(); - } - return new PyObject(items); - } - - - /// - /// Values Method - /// - /// - /// - /// Returns a sequence containing the values of the dictionary. - /// - - public PyObject Values() { - IntPtr items = Runtime.PyDict_Values(obj); - if (items == IntPtr.Zero) { - throw new PythonException(); - } - return new PyObject(items); - } - - - /// - /// Items Method - /// - /// - /// - /// Returns a sequence containing the items of the dictionary. - /// - - public PyObject Items() { - IntPtr items = Runtime.PyDict_Items(obj); - if (items == IntPtr.Zero) { - throw new PythonException(); - } - return new PyObject(items); - } - - - /// - /// Copy Method - /// - /// - /// - /// Returns a copy of the dictionary. - /// - - public PyDict Copy() { - IntPtr op = Runtime.PyDict_Copy(obj); - if (op == IntPtr.Zero) { - throw new PythonException(); - } - return new PyDict(op); - } - - - /// - /// Update Method - /// - /// - /// - /// Update the dictionary from another dictionary. - /// - - public void Update(PyObject other) { - int result = Runtime.PyDict_Update(obj, other.obj); - if (result < 0) { - throw new PythonException(); - } - } - - - /// - /// Clear Method - /// - /// - /// - /// Clears the dictionary. - /// - - public void Clear() { - Runtime.PyDict_Clear(obj); - } - - - } - -} diff --git a/Pythonnet.Runtime/pyfloat.cs b/Pythonnet.Runtime/pyfloat.cs deleted file mode 100644 index 960892594c..0000000000 --- a/Pythonnet.Runtime/pyfloat.cs +++ /dev/null @@ -1,122 +0,0 @@ -// ========================================================================== -// This software is subject to the provisions of the Zope Public License, -// Version 2.0 (ZPL). A copy of the ZPL should accompany this distribution. -// THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED -// WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -// WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS -// FOR A PARTICULAR PURPOSE. -// ========================================================================== - -using System; -using System.Runtime.InteropServices; - -namespace Python.Runtime { - - /// - /// Represents a Python float object. See the documentation at - /// http://www.python.org/doc/current/api/floatObjects.html - /// - - public class PyFloat : PyNumber { - - /// - /// PyFloat Constructor - /// - /// - /// - /// Creates a new PyFloat from an existing object reference. Note - /// that the instance assumes ownership of the object reference. - /// The object reference is not checked for type-correctness. - /// - - public PyFloat(IntPtr ptr) : base(ptr) {} - - - /// - /// PyFloat Constructor - /// - /// - /// - /// Copy constructor - obtain a PyFloat from a generic PyObject. An - /// ArgumentException will be thrown if the given object is not a - /// Python float object. - /// - - public PyFloat(PyObject o) : base() { - if (!IsFloatType(o)) { - throw new ArgumentException("object is not a float"); - } - Runtime.Incref(o.obj); - obj = o.obj; - } - - - /// - /// PyFloat Constructor - /// - /// - /// - /// Creates a new Python float from a double value. - /// - - public PyFloat(double value) : base() { - obj = Runtime.PyFloat_FromDouble(value); - if (obj == IntPtr.Zero) { - throw new PythonException(); - } - } - - - /// - /// PyFloat Constructor - /// - /// - /// - /// Creates a new Python float from a string value. - /// - - public PyFloat(string value) : base() { - PyString s = new PyString(value); - obj = Runtime.PyFloat_FromString(s.obj, IntPtr.Zero); - if (obj == IntPtr.Zero) { - throw new PythonException(); - } - } - - - /// - /// IsFloatType Method - /// - /// - /// - /// Returns true if the given object is a Python float. - /// - - public static bool IsFloatType(PyObject value) { - return Runtime.PyFloat_Check(value.obj); - } - - - /// - /// AsFloat Method - /// - /// - /// - /// - /// Convert a Python object to a Python float if possible, raising - /// a PythonException if the conversion is not possible. This is - /// equivalent to the Python expression "float(object)". - /// - - public static PyFloat AsFloat(PyObject value) { - IntPtr op = Runtime.PyNumber_Float(value.obj); - if (op == IntPtr.Zero) { - throw new PythonException(); - } - return new PyFloat(op); - } - - - } - -} diff --git a/Pythonnet.Runtime/pyint.cs b/Pythonnet.Runtime/pyint.cs deleted file mode 100644 index 7e5f07b6aa..0000000000 --- a/Pythonnet.Runtime/pyint.cs +++ /dev/null @@ -1,257 +0,0 @@ -// ========================================================================== -// This software is subject to the provisions of the Zope Public License, -// Version 2.0 (ZPL). A copy of the ZPL should accompany this distribution. -// THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED -// WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -// WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS -// FOR A PARTICULAR PURPOSE. -// ========================================================================== - -using System; -using System.Runtime.InteropServices; - -namespace Python.Runtime { - - /// - /// Represents a Python integer object. See the documentation at - /// http://www.python.org/doc/current/api/intObjects.html for details. - /// - - public class PyInt : PyNumber { - - /// - /// PyInt Constructor - /// - /// - /// - /// Creates a new PyInt from an existing object reference. Note - /// that the instance assumes ownership of the object reference. - /// The object reference is not checked for type-correctness. - /// - - public PyInt(IntPtr ptr) : base(ptr) {} - - - /// - /// PyInt Constructor - /// - /// - /// - /// Copy constructor - obtain a PyInt from a generic PyObject. An - /// ArgumentException will be thrown if the given object is not a - /// Python int object. - /// - - public PyInt(PyObject o) : base() { - if (!IsIntType(o)) { - throw new ArgumentException("object is not an int"); - } - Runtime.Incref(o.obj); - obj = o.obj; - } - - - /// - /// PyInt Constructor - /// - /// - /// - /// Creates a new Python int from an int32 value. - /// - - public PyInt(int value) : base() { - obj = Runtime.PyInt_FromInt32(value); - if (obj == IntPtr.Zero) { - throw new PythonException(); - } - } - - - /// - /// PyInt Constructor - /// - /// - /// - /// Creates a new Python int from a uint32 value. - /// - - [CLSCompliant(false)] - public PyInt(uint value) : base(IntPtr.Zero) { - obj = Runtime.PyInt_FromInt64((long)value); - if (obj == IntPtr.Zero) { - throw new PythonException(); - } - } - - - /// - /// PyInt Constructor - /// - /// - /// - /// Creates a new Python int from an int64 value. - /// - - public PyInt(long value) : base(IntPtr.Zero) { - obj = Runtime.PyInt_FromInt64(value); - if (obj == IntPtr.Zero) { - throw new PythonException(); - } - } - - - /// - /// PyInt Constructor - /// - /// - /// - /// Creates a new Python int from a uint64 value. - /// - - [CLSCompliant(false)] - public PyInt(ulong value) : base(IntPtr.Zero) { - obj = Runtime.PyInt_FromInt64((long)value); - if (obj == IntPtr.Zero) { - throw new PythonException(); - } - } - - - /// - /// PyInt Constructor - /// - /// - /// - /// Creates a new Python int from an int16 value. - /// - - public PyInt(short value) : this((int)value) {} - - - /// - /// PyInt Constructor - /// - /// - /// - /// Creates a new Python int from a uint16 value. - /// - - [CLSCompliant(false)] - public PyInt(ushort value) : this((int)value) {} - - - /// - /// PyInt Constructor - /// - /// - /// - /// Creates a new Python int from a byte value. - /// - - public PyInt(byte value) : this((int)value) {} - - - /// - /// PyInt Constructor - /// - /// - /// - /// Creates a new Python int from an sbyte value. - /// - - [CLSCompliant(false)] - public PyInt(sbyte value) : this((int)value) {} - - - /// - /// PyInt Constructor - /// - /// - /// - /// Creates a new Python int from a string value. - /// - - public PyInt(string value) : base() { - obj = Runtime.PyInt_FromString(value, IntPtr.Zero, 0); - if (obj == IntPtr.Zero) { - throw new PythonException(); - } - } - - - /// - /// IsIntType Method - /// - /// - /// - /// Returns true if the given object is a Python int. - /// - - public static bool IsIntType(PyObject value) { - return Runtime.PyInt_Check(value.obj); - } - - - /// - /// AsInt Method - /// - /// - /// - /// - /// Convert a Python object to a Python int if possible, raising - /// a PythonException if the conversion is not possible. This is - /// equivalent to the Python expression "int(object)". - /// - - public static PyInt AsInt(PyObject value) { - IntPtr op = Runtime.PyNumber_Int(value.obj); - if (op == IntPtr.Zero) { - throw new PythonException(); - } - return new PyInt(op); - } - - - /// - /// ToInt16 Method - /// - /// - /// - /// Return the value of the Python int object as an int16. - /// - - public short ToInt16() { - return System.Convert.ToInt16(this.ToInt32()); - } - - - /// - /// ToInt32 Method - /// - /// - /// - /// Return the value of the Python int object as an int32. - /// - - public int ToInt32() { - return Runtime.PyInt_AsLong(obj); - } - - - /// - /// ToInt64 Method - /// - /// - /// - /// Return the value of the Python int object as an int64. - /// - - public long ToInt64() { - return System.Convert.ToInt64(this.ToInt32()); - } - - - - } - -} diff --git a/Pythonnet.Runtime/pyiter.cs b/Pythonnet.Runtime/pyiter.cs deleted file mode 100644 index 8d8ad44d7d..0000000000 --- a/Pythonnet.Runtime/pyiter.cs +++ /dev/null @@ -1,76 +0,0 @@ -// ========================================================================== -// This software is subject to the provisions of the Zope Public License, -// Version 2.0 (ZPL). A copy of the ZPL should accompany this distribution. -// THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED -// WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -// WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS -// FOR A PARTICULAR PURPOSE. -// ========================================================================== - -using System; -using System.Collections.Generic; - -namespace Python.Runtime -{ - /// - /// Represents a standard Python iterator object. See the documentation at - /// http://www.python.org/doc/2.4.4/api/iterator.html for details. - /// - public class PyIter : PyObject, IEnumerator - { - private PyObject _current = null; - - /// - /// PyIter Constructor - /// - /// - /// - /// Creates a new PyIter from an existing iterator reference. Note - /// that the instance assumes ownership of the object reference. - /// The object reference is not checked for type-correctness. - /// - - public PyIter(IntPtr ptr) : base(ptr) {} - - /// - /// PyIter Constructor - /// - /// - /// - /// Creates a Python iterator from an iterable. Like doing "iter(iterable)" in python. - /// - - public PyIter(PyObject iterable) : base() - { - obj = Runtime.PyObject_GetIter(iterable.obj); - if (obj == IntPtr.Zero) - throw new PythonException(); - } - - #region IEnumerator Members - - public bool MoveNext() - { - IntPtr next = Runtime.PyIter_Next(obj); - if (next == IntPtr.Zero) - { - _current = null; //release reference - return false; - } - _current = new PyObject(next); - return true; - } - - public void Reset() - { - //Not supported in python. - } - - public object Current - { - get { return _current; } - } - - #endregion - } -} diff --git a/Pythonnet.Runtime/pylist.cs b/Pythonnet.Runtime/pylist.cs deleted file mode 100644 index 3954823327..0000000000 --- a/Pythonnet.Runtime/pylist.cs +++ /dev/null @@ -1,189 +0,0 @@ -// ========================================================================== -// This software is subject to the provisions of the Zope Public License, -// Version 2.0 (ZPL). A copy of the ZPL should accompany this distribution. -// THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED -// WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -// WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS -// FOR A PARTICULAR PURPOSE. -// ========================================================================== - -using System; - -namespace Python.Runtime { - - /// - /// Represents a standard Python list object. See the documentation at - /// http://www.python.org/doc/current/api/listObjects.html for details. - /// - - public class PyList : PySequence { - - /// - /// PyList Constructor - /// - /// - /// - /// Creates a new PyList from an existing object reference. Note - /// that the instance assumes ownership of the object reference. - /// The object reference is not checked for type-correctness. - /// - - public PyList(IntPtr ptr) : base(ptr) {} - - - /// - /// PyList Constructor - /// - /// - /// - /// Copy constructor - obtain a PyList from a generic PyObject. An - /// ArgumentException will be thrown if the given object is not a - /// Python list object. - /// - - public PyList(PyObject o) : base() { - if (!IsListType(o)) { - throw new ArgumentException("object is not a list"); - } - Runtime.Incref(o.obj); - obj = o.obj; - } - - - /// - /// PyList Constructor - /// - /// - /// - /// Creates a new empty Python list object. - /// - - public PyList() : base() { - obj = Runtime.PyList_New(0); - if (obj == IntPtr.Zero) { - throw new PythonException(); - } - } - - - /// - /// PyList Constructor - /// - /// - /// - /// Creates a new Python list object from an array of PyObjects. - /// - - public PyList(PyObject[] items) : base() { - int count = items.Length; - obj = Runtime.PyList_New(count); - for (int i = 0; i < count; i++) { - IntPtr ptr = items[i].obj; - Runtime.Incref(ptr); - int r = Runtime.PyList_SetItem(obj, i, ptr); - if (r < 0) { - throw new PythonException(); - } - } - } - - - /// - /// IsListType Method - /// - /// - /// - /// Returns true if the given object is a Python list. - /// - - public static bool IsListType(PyObject value) { - return Runtime.PyList_Check(value.obj); - } - - - /// - /// AsList Method - /// - /// - /// - /// Converts a Python object to a Python list if possible, raising - /// a PythonException if the conversion is not possible. This is - /// equivalent to the Python expression "list(object)". - /// - - public static PyList AsList(PyObject value) { - IntPtr op = Runtime.PySequence_List(value.obj); - if (op == IntPtr.Zero) { - throw new PythonException(); - } - return new PyList(op); - } - - - /// - /// Append Method - /// - /// - /// - /// Append an item to the list object. - /// - - public void Append(PyObject item) { - int r = Runtime.PyList_Append(obj, item.obj); - if (r < 0) { - throw new PythonException(); - } - } - - /// - /// Insert Method - /// - /// - /// - /// Insert an item in the list object at the given index. - /// - - public void Insert(int index, PyObject item) { - int r = Runtime.PyList_Insert(obj, index, item.obj); - if (r < 0) { - throw new PythonException(); - } - } - - - /// - /// Reverse Method - /// - /// - /// - /// Reverse the order of the list object in place. - /// - - public void Reverse() { - int r = Runtime.PyList_Reverse(obj); - if (r < 0) { - throw new PythonException(); - } - } - - - /// - /// Sort Method - /// - /// - /// - /// Sort the list in place. - /// - - public void Sort() { - int r = Runtime.PyList_Sort(obj); - if (r < 0) { - throw new PythonException(); - } - } - - - } - - -} diff --git a/Pythonnet.Runtime/pylong.cs b/Pythonnet.Runtime/pylong.cs deleted file mode 100644 index 999c75adce..0000000000 --- a/Pythonnet.Runtime/pylong.cs +++ /dev/null @@ -1,291 +0,0 @@ -// ========================================================================== -// This software is subject to the provisions of the Zope Public License, -// Version 2.0 (ZPL). A copy of the ZPL should accompany this distribution. -// THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED -// WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -// WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS -// FOR A PARTICULAR PURPOSE. -// ========================================================================== - -using System; - -namespace Python.Runtime { - - /// - /// Represents a Python long int object. See the documentation at - /// http://www.python.org/doc/current/api/longObjects.html - /// - - public class PyLong : PyNumber { - - /// - /// PyLong Constructor - /// - /// - /// - /// Creates a new PyLong from an existing object reference. Note - /// that the instance assumes ownership of the object reference. - /// The object reference is not checked for type-correctness. - /// - - public PyLong(IntPtr ptr) : base(ptr) {} - - - /// - /// PyLong Constructor - /// - /// - /// - /// Copy constructor - obtain a PyLong from a generic PyObject. An - /// ArgumentException will be thrown if the given object is not a - /// Python long object. - /// - - public PyLong(PyObject o) : base() { - if (!IsLongType(o)) { - throw new ArgumentException("object is not a long"); - } - Runtime.Incref(o.obj); - obj = o.obj; - } - - - /// - /// PyLong Constructor - /// - /// - /// - /// Creates a new PyLong from an int32 value. - /// - - public PyLong(int value) : base() { - obj = Runtime.PyLong_FromLong((long)value); - if (obj == IntPtr.Zero) { - throw new PythonException(); - } - } - - - /// - /// PyLong Constructor - /// - /// - /// - /// Creates a new PyLong from a uint32 value. - /// - - [CLSCompliant(false)] - public PyLong(uint value) : base() { - obj = Runtime.PyLong_FromLong((long)value); - if (obj == IntPtr.Zero) { - throw new PythonException(); - } - } - - - /// - /// PyLong Constructor - /// - /// - /// - /// Creates a new PyLong from an int64 value. - /// - - public PyLong(long value) : base() { - obj = Runtime.PyLong_FromLongLong(value); - if (obj == IntPtr.Zero) { - throw new PythonException(); - } - } - - - /// - /// PyLong Constructor - /// - /// - /// - /// Creates a new PyLong from a uint64 value. - /// - - [CLSCompliant(false)] - public PyLong(ulong value) : base() { - obj = Runtime.PyLong_FromUnsignedLongLong(value); - if (obj == IntPtr.Zero) { - throw new PythonException(); - } - } - - - /// - /// PyLong Constructor - /// - /// - /// - /// Creates a new PyLong from an int16 value. - /// - - public PyLong(short value) : base() { - obj = Runtime.PyLong_FromLong((long)value); - if (obj == IntPtr.Zero) { - throw new PythonException(); - } - } - - - /// - /// PyLong Constructor - /// - /// - /// - /// Creates a new PyLong from an uint16 value. - /// - - [CLSCompliant(false)] - public PyLong(ushort value) : base() { - obj = Runtime.PyLong_FromLong((long)value); - if (obj == IntPtr.Zero) { - throw new PythonException(); - } - } - - - /// - /// PyLong Constructor - /// - /// - /// - /// Creates a new PyLong from a byte value. - /// - - public PyLong(byte value) : base() { - obj = Runtime.PyLong_FromLong((long)value); - if (obj == IntPtr.Zero) { - throw new PythonException(); - } - } - - - /// - /// PyLong Constructor - /// - /// - /// - /// Creates a new PyLong from an sbyte value. - /// - - [CLSCompliant(false)] - public PyLong(sbyte value) : base() { - obj = Runtime.PyLong_FromLong((long)value); - if (obj == IntPtr.Zero) { - throw new PythonException(); - } - } - - - /// - /// PyLong Constructor - /// - /// - /// - /// Creates a new PyLong from an double value. - /// - - public PyLong(double value) : base() { - obj = Runtime.PyLong_FromDouble(value); - if (obj == IntPtr.Zero) { - throw new PythonException(); - } - } - - - /// - /// PyLong Constructor - /// - /// - /// - /// Creates a new PyLong from a string value. - /// - - public PyLong(string value) : base() { - obj = Runtime.PyLong_FromString(value, IntPtr.Zero, 0); - if (obj == IntPtr.Zero) { - throw new PythonException(); - } - } - - - /// - /// IsLongType Method - /// - /// - /// - /// Returns true if the given object is a Python long. - /// - - public static bool IsLongType(PyObject value) { - return Runtime.PyLong_Check(value.obj); - } - - - /// - /// AsLong Method - /// - /// - /// - /// - /// Convert a Python object to a Python long if possible, raising - /// a PythonException if the conversion is not possible. This is - /// equivalent to the Python expression "long(object)". - /// - - public static PyLong AsLong(PyObject value) { - IntPtr op = Runtime.PyNumber_Long(value.obj); - if (op == IntPtr.Zero) { - throw new PythonException(); - } - return new PyLong(op); - } - - /// - /// ToInt16 Method - /// - /// - /// - /// Return the value of the Python long object as an int16. - /// - - public short ToInt16() - { - return System.Convert.ToInt16(this.ToInt64()); - } - - - /// - /// ToInt32 Method - /// - /// - /// - /// Return the value of the Python long object as an int32. - /// - - public int ToInt32() - { - return System.Convert.ToInt32(this.ToInt64()); - } - - - /// - /// ToInt64 Method - /// - /// - /// - /// Return the value of the Python long object as an int64. - /// - - public long ToInt64() - { - return Runtime.PyLong_AsLongLong(obj); - } - } - -} diff --git a/Pythonnet.Runtime/pynumber.cs b/Pythonnet.Runtime/pynumber.cs deleted file mode 100644 index c03c8c5276..0000000000 --- a/Pythonnet.Runtime/pynumber.cs +++ /dev/null @@ -1,42 +0,0 @@ -// ========================================================================== -// This software is subject to the provisions of the Zope Public License, -// Version 2.0 (ZPL). A copy of the ZPL should accompany this distribution. -// THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED -// WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -// WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS -// FOR A PARTICULAR PURPOSE. -// ========================================================================== - -using System; - -namespace Python.Runtime { - - /// - /// Represents a generic Python number. The methods of this class are - /// equivalent to the Python "abstract number API". See - /// http://www.python.org/doc/current/api/number.html for details. - /// - - public class PyNumber : PyObject { - - protected PyNumber(IntPtr ptr) : base(ptr) {} - - protected PyNumber() : base() {} - - - /// - /// IsNumberType Method - /// - /// - /// - /// Returns true if the given object is a Python numeric type. - /// - - public static bool IsNumberType(PyObject value) { - return Runtime.PyNumber_Check(value.obj); - } - - - } - -} diff --git a/Pythonnet.Runtime/pyobject.cs b/Pythonnet.Runtime/pyobject.cs deleted file mode 100644 index 099b9fdf46..0000000000 --- a/Pythonnet.Runtime/pyobject.cs +++ /dev/null @@ -1,869 +0,0 @@ -// ========================================================================== -// This software is subject to the provisions of the Zope Public License, -// Version 2.0 (ZPL). A copy of the ZPL should accompany this distribution. -// THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED -// WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -// WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS -// FOR A PARTICULAR PURPOSE. -// ========================================================================== - -using System; - -namespace Python.Runtime { - - /// - /// Represents a generic Python object. The methods of this class are - /// generally equivalent to the Python "abstract object API". See - /// http://www.python.org/doc/current/api/object.html for details. - /// - - public class PyObject : IDisposable { - - protected internal IntPtr obj = IntPtr.Zero; - private bool disposed = false; - - /// - /// PyObject Constructor - /// - /// - /// - /// Creates a new PyObject from an IntPtr object reference. Note that - /// the PyObject instance assumes ownership of the object reference - /// and the reference will be DECREFed when the PyObject is garbage - /// collected or explicitly disposed. - /// - - public PyObject(IntPtr ptr) { - obj = ptr; - } - - // Protected default constructor to allow subclasses to manage - // initialization in different ways as appropriate. - - protected PyObject() {} - - // Ensure that encapsulated Python object is decref'ed appropriately - // when the managed wrapper is garbage-collected. - - ~PyObject() { - Dispose(); - } - - - /// - /// Handle Property - /// - /// - /// - /// Gets the native handle of the underlying Python object. This - /// value is generally for internal use by the PythonNet runtime. - /// - - public IntPtr Handle { - get { return obj; } - } - - - /// - /// FromManagedObject Method - /// - /// - /// - /// Given an arbitrary managed object, return a Python instance that - /// reflects the managed object. - /// - - public static PyObject FromManagedObject(object ob) { - // Special case: if ob is null, we return None. - if (ob == null) { - Runtime.Incref(Runtime.PyNone); - return new PyObject(Runtime.PyNone); - } - IntPtr op = CLRObject.GetInstHandle(ob); - return new PyObject(op); - } - - - /// - /// AsManagedObject Method - /// - /// - /// - /// Return a managed object of the given type, based on the - /// value of the Python object. - /// - - public object AsManagedObject(Type t) { - Object result; - if (!Converter.ToManaged(this.Handle, t, out result, false)) { - throw new InvalidCastException("cannot convert object to target type"); - } - return result; - } - - - /// - /// Dispose Method - /// - /// - /// - /// The Dispose method provides a way to explicitly release the - /// Python object represented by a PyObject instance. It is a good - /// idea to call Dispose on PyObjects that wrap resources that are - /// limited or need strict lifetime control. Otherwise, references - /// to Python objects will not be released until a managed garbage - /// collection occurs. - /// - - public void Dispose() { - if (!disposed) { - if (Runtime.Py_IsInitialized() > 0) { - IntPtr gs = PythonEngine.AcquireLock(); - Runtime.Decref(obj); - obj = IntPtr.Zero; - PythonEngine.ReleaseLock(gs); - } - GC.SuppressFinalize(this); - disposed = true; - } - } - - - /// - /// GetPythonType Method - /// - /// - /// - /// Returns the Python type of the object. This method is equivalent - /// to the Python expression: type(object). - /// - - public PyObject GetPythonType() { - IntPtr tp = Runtime.PyObject_Type(obj); - return new PyObject(tp); - } - - - /// - /// TypeCheck Method - /// - /// - /// - /// Returns true if the object o is of type typeOrClass or a subtype - /// of typeOrClass. - /// - - public bool TypeCheck(PyObject typeOrClass) { - return Runtime.PyObject_TypeCheck(obj, typeOrClass.obj); - } - - - /// - /// HasAttr Method - /// - /// - /// - /// Returns true if the object has an attribute with the given name. - /// - - public bool HasAttr(string name) { - return (Runtime.PyObject_HasAttrString(obj, name) != 0); - } - - - /// - /// HasAttr Method - /// - /// - /// - /// Returns true if the object has an attribute with the given name, - /// where name is a PyObject wrapping a string or unicode object. - /// - - public bool HasAttr(PyObject name) { - return (Runtime.PyObject_HasAttr(obj, name.obj) != 0); - } - - - /// - /// GetAttr Method - /// - /// - /// - /// Returns the named attribute of the Python object, or raises a - /// PythonException if the attribute access fails. - /// - - public PyObject GetAttr(string name) { - IntPtr op = Runtime.PyObject_GetAttrString(obj, name); - if (op == IntPtr.Zero) { - throw new PythonException(); - } - return new PyObject(op); - } - - - /// - /// GetAttr Method - /// - /// - /// - /// Returns the named attribute of the Python object, or the given - /// default object if the attribute access fails. - /// - - public PyObject GetAttr(string name, PyObject _default) { - IntPtr op = Runtime.PyObject_GetAttrString(obj, name); - if (op == IntPtr.Zero) { - Runtime.PyErr_Clear(); - return _default; - } - return new PyObject(op); - } - - - /// - /// GetAttr Method - /// - /// - /// - /// Returns the named attribute of the Python object or raises a - /// PythonException if the attribute access fails. The name argument - /// is a PyObject wrapping a Python string or unicode object. - /// - - public PyObject GetAttr(PyObject name) { - IntPtr op = Runtime.PyObject_GetAttr(obj, name.obj); - if (op == IntPtr.Zero) { - throw new PythonException(); - } - return new PyObject(op); - } - - - /// - /// GetAttr Method - /// - /// - /// - /// Returns the named attribute of the Python object, or the given - /// default object if the attribute access fails. The name argument - /// is a PyObject wrapping a Python string or unicode object. - /// - - public PyObject GetAttr(PyObject name, PyObject _default) { - IntPtr op = Runtime.PyObject_GetAttr(obj, name.obj); - if (op == IntPtr.Zero) { - Runtime.PyErr_Clear(); - return _default; - } - return new PyObject(op); - } - - - /// - /// SetAttr Method - /// - /// - /// - /// Set an attribute of the object with the given name and value. This - /// method throws a PythonException if the attribute set fails. - /// - - public void SetAttr(string name, PyObject value) { - int r = Runtime.PyObject_SetAttrString(obj, name, value.obj); - if (r < 0) { - throw new PythonException(); - } - } - - - /// - /// SetAttr Method - /// - /// - /// - /// Set an attribute of the object with the given name and value, - /// where the name is a Python string or unicode object. This method - /// throws a PythonException if the attribute set fails. - /// - - public void SetAttr(PyObject name, PyObject value) { - int r = Runtime.PyObject_SetAttr(obj, name.obj, value.obj); - if (r < 0) { - throw new PythonException(); - } - } - - - /// - /// DelAttr Method - /// - /// - /// - /// Delete the named attribute of the Python object. This method - /// throws a PythonException if the attribute set fails. - /// - - public void DelAttr(string name) { - int r = Runtime.PyObject_SetAttrString(obj, name, IntPtr.Zero); - if (r < 0) { - throw new PythonException(); - } - } - - - /// - /// DelAttr Method - /// - /// - /// - /// Delete the named attribute of the Python object, where name is a - /// PyObject wrapping a Python string or unicode object. This method - /// throws a PythonException if the attribute set fails. - /// - - public void DelAttr(PyObject name) { - int r = Runtime.PyObject_SetAttr(obj, name.obj, IntPtr.Zero); - if (r < 0) { - throw new PythonException(); - } - } - - - /// - /// GetItem Method - /// - /// - /// - /// For objects that support the Python sequence or mapping protocols, - /// return the item at the given object index. This method raises a - /// PythonException if the indexing operation fails. - /// - - public virtual PyObject GetItem(PyObject key) { - IntPtr op = Runtime.PyObject_GetItem(obj, key.obj); - if (op == IntPtr.Zero) { - throw new PythonException(); - } - return new PyObject(op); - } - - - /// - /// GetItem Method - /// - /// - /// - /// For objects that support the Python sequence or mapping protocols, - /// return the item at the given string index. This method raises a - /// PythonException if the indexing operation fails. - /// - - public virtual PyObject GetItem(string key) { - return GetItem(new PyString(key)); - } - - - /// - /// GetItem Method - /// - /// - /// - /// For objects that support the Python sequence or mapping protocols, - /// return the item at the given numeric index. This method raises a - /// PythonException if the indexing operation fails. - /// - - public virtual PyObject GetItem(int index) { - PyInt key = new PyInt(index); - return GetItem((PyObject)key); - } - - - /// - /// SetItem Method - /// - /// - /// - /// For objects that support the Python sequence or mapping protocols, - /// set the item at the given object index to the given value. This - /// method raises a PythonException if the set operation fails. - /// - - public virtual void SetItem(PyObject key, PyObject value) { - int r = Runtime.PyObject_SetItem(obj, key.obj, value.obj); - if (r < 0) { - throw new PythonException(); - } - } - - - /// - /// SetItem Method - /// - /// - /// - /// For objects that support the Python sequence or mapping protocols, - /// set the item at the given string index to the given value. This - /// method raises a PythonException if the set operation fails. - /// - - public virtual void SetItem(string key, PyObject value) { - SetItem(new PyString(key), value); - } - - - /// - /// SetItem Method - /// - /// - /// - /// For objects that support the Python sequence or mapping protocols, - /// set the item at the given numeric index to the given value. This - /// method raises a PythonException if the set operation fails. - /// - - public virtual void SetItem(int index, PyObject value) { - SetItem(new PyInt(index), value); - } - - - /// - /// DelItem Method - /// - /// - /// - /// For objects that support the Python sequence or mapping protocols, - /// delete the item at the given object index. This method raises a - /// PythonException if the delete operation fails. - /// - - public virtual void DelItem(PyObject key) { - int r = Runtime.PyObject_DelItem(obj, key.obj); - if (r < 0) { - throw new PythonException(); - } - } - - - /// - /// DelItem Method - /// - /// - /// - /// For objects that support the Python sequence or mapping protocols, - /// delete the item at the given string index. This method raises a - /// PythonException if the delete operation fails. - /// - - public virtual void DelItem(string key) { - DelItem(new PyString(key)); - } - - - /// - /// DelItem Method - /// - /// - /// - /// For objects that support the Python sequence or mapping protocols, - /// delete the item at the given numeric index. This method raises a - /// PythonException if the delete operation fails. - /// - - public virtual void DelItem(int index) { - DelItem(new PyInt(index)); - } - - - /// - /// Length Method - /// - /// - /// - /// Returns the length for objects that support the Python sequence - /// protocol, or 0 if the object does not support the protocol. - /// - - public virtual int Length() { - int s = Runtime.PyObject_Size(obj); - if (s < 0) { - Runtime.PyErr_Clear(); - return 0; - } - return s; - } - - - /// - /// String Indexer - /// - /// - /// - /// Provides a shorthand for the string versions of the GetItem and - /// SetItem methods. - /// - - public virtual PyObject this[string key] { - get { return GetItem(key); } - set { SetItem(key, value); } - } - - - /// - /// PyObject Indexer - /// - /// - /// - /// Provides a shorthand for the object versions of the GetItem and - /// SetItem methods. - /// - - public virtual PyObject this[PyObject key] { - get { return GetItem(key); } - set { SetItem(key, value); } - } - - - /// - /// Numeric Indexer - /// - /// - /// - /// Provides a shorthand for the numeric versions of the GetItem and - /// SetItem methods. - /// - - public virtual PyObject this[int index] { - get { return GetItem(index); } - set { SetItem(index, value); } - } - - - /// - /// GetIterator Method - /// - /// - /// - /// Return a new (Python) iterator for the object. This is equivalent - /// to the Python expression "iter(object)". A PythonException will be - /// raised if the object cannot be iterated. - /// - - public PyObject GetIterator() { - IntPtr r = Runtime.PyObject_GetIter(obj); - if (r == IntPtr.Zero) { - throw new PythonException(); - } - return new PyObject(r); - } - - - /// - /// Invoke Method - /// - /// - /// - /// Invoke the callable object with the given arguments, passed as a - /// PyObject[]. A PythonException is raised if the invokation fails. - /// - - public PyObject Invoke(params PyObject[] args) { - PyTuple t = new PyTuple(args); - IntPtr r = Runtime.PyObject_Call(obj, t.obj, IntPtr.Zero); - t.Dispose(); - if (r == IntPtr.Zero) { - throw new PythonException(); - } - return new PyObject(r); - } - - - /// - /// Invoke Method - /// - /// - /// - /// Invoke the callable object with the given arguments, passed as a - /// Python tuple. A PythonException is raised if the invokation fails. - /// - - public PyObject Invoke(PyTuple args) { - IntPtr r = Runtime.PyObject_Call(obj, args.obj, IntPtr.Zero); - if (r == IntPtr.Zero) { - throw new PythonException(); - } - return new PyObject(r); - } - - - /// - /// Invoke Method - /// - /// - /// - /// Invoke the callable object with the given positional and keyword - /// arguments. A PythonException is raised if the invokation fails. - /// - - public PyObject Invoke(PyObject[] args, PyDict kw) { - PyTuple t = new PyTuple(args); - IntPtr r = Runtime.PyObject_Call(obj, t.obj, kw.obj); - t.Dispose(); - if (r == IntPtr.Zero) { - throw new PythonException(); - } - return new PyObject(r); - } - - - /// - /// Invoke Method - /// - /// - /// - /// Invoke the callable object with the given positional and keyword - /// arguments. A PythonException is raised if the invokation fails. - /// - - public PyObject Invoke(PyTuple args, PyDict kw) { - IntPtr r = Runtime.PyObject_Call(obj, args.obj, kw.obj); - if (r == IntPtr.Zero) { - throw new PythonException(); - } - return new PyObject(r); - } - - - /// - /// InvokeMethod Method - /// - /// - /// - /// Invoke the named method of the object with the given arguments. - /// A PythonException is raised if the invokation is unsuccessful. - /// - - public PyObject InvokeMethod(string name, params PyObject[] args) { - PyObject method = GetAttr(name); - PyObject result = method.Invoke(args); - method.Dispose(); - return result; - } - - - /// - /// InvokeMethod Method - /// - /// - /// - /// Invoke the named method of the object with the given arguments. - /// A PythonException is raised if the invokation is unsuccessful. - /// - - public PyObject InvokeMethod(string name, PyTuple args) { - PyObject method = GetAttr(name); - PyObject result = method.Invoke(args); - method.Dispose(); - return result; - } - - - /// - /// InvokeMethod Method - /// - /// - /// - /// Invoke the named method of the object with the given arguments - /// and keyword arguments. Keyword args are passed as a PyDict object. - /// A PythonException is raised if the invokation is unsuccessful. - /// - - public PyObject InvokeMethod(string name, PyObject[] args, PyDict kw) { - PyObject method = GetAttr(name); - PyObject result = method.Invoke(args, kw); - method.Dispose(); - return result; - } - - - /// - /// InvokeMethod Method - /// - /// - /// - /// Invoke the named method of the object with the given arguments - /// and keyword arguments. Keyword args are passed as a PyDict object. - /// A PythonException is raised if the invokation is unsuccessful. - /// - - public PyObject InvokeMethod(string name, PyTuple args, PyDict kw) { - PyObject method = GetAttr(name); - PyObject result = method.Invoke(args, kw); - method.Dispose(); - return result; - } - - - /// - /// IsInstance Method - /// - /// - /// - /// Return true if the object is an instance of the given Python type - /// or class. This method always succeeds. - /// - - public bool IsInstance(PyObject typeOrClass) { - int r = Runtime.PyObject_IsInstance(obj, typeOrClass.obj); - if (r < 0) { - Runtime.PyErr_Clear(); - return false; - } - return (r != 0); - } - - - /// - /// IsSubclass Method - /// - /// - /// - /// Return true if the object is identical to or derived from the - /// given Python type or class. This method always succeeds. - /// - - public bool IsSubclass(PyObject typeOrClass) { - int r = Runtime.PyObject_IsSubclass(obj, typeOrClass.obj); - if (r < 0) { - Runtime.PyErr_Clear(); - return false; - } - return (r != 0); - } - - - /// - /// IsCallable Method - /// - /// - /// - /// Returns true if the object is a callable object. This method - /// always succeeds. - /// - - public bool IsCallable() { - return (Runtime.PyCallable_Check(obj) != 0); - } - - - /// - /// IsTrue Method - /// - /// - /// - /// Return true if the object is true according to Python semantics. - /// This method always succeeds. - /// - - public bool IsTrue() { - return (Runtime.PyObject_IsTrue(obj) != 0); - } - - - /// - /// Dir Method - /// - /// - /// - /// Return a list of the names of the attributes of the object. This - /// is equivalent to the Python expression "dir(object)". - /// - - public PyList Dir() { - IntPtr r = Runtime.PyObject_Dir(obj); - if (r == IntPtr.Zero) { - throw new PythonException(); - } - return new PyList(r); - } - - - /// - /// Repr Method - /// - /// - /// - /// Return a string representation of the object. This method is - /// the managed equivalent of the Python expression "repr(object)". - /// - - public string Repr() { - IntPtr strval = Runtime.PyObject_Repr(obj); - string result = Runtime.GetManagedString(strval); - Runtime.Decref(strval); - return result; - } - - - /// - /// ToString Method - /// - /// - /// - /// Return the string representation of the object. This method is - /// the managed equivalent of the Python expression "str(object)". - /// - - public override string ToString() { - IntPtr strval = Runtime.PyObject_Unicode(obj); - string result = Runtime.GetManagedString(strval); - Runtime.Decref(strval); - return result; - } - - - /// - /// Equals Method - /// - /// - /// - /// Return true if this object is equal to the given object. This - /// method is based on Python equality semantics. - /// - - public override bool Equals(object o) { - if (!(o is PyObject)) { - return false; - } - if (obj == ((PyObject) o).obj) { - return true; - } - int r = Runtime.PyObject_Compare(obj, ((PyObject) o).obj); - if (Exceptions.ErrorOccurred()) { - throw new PythonException(); - } - return (r == 0); - } - - - /// - /// GetHashCode Method - /// - /// - /// - /// Return a hashcode based on the Python object. This returns the - /// hash as computed by Python, equivalent to the Python expression - /// "hash(obj)". - /// - - public override int GetHashCode() { - return Runtime.PyObject_Hash(obj).ToInt32(); - } - - - } - - -} diff --git a/Pythonnet.Runtime/pysequence.cs b/Pythonnet.Runtime/pysequence.cs deleted file mode 100644 index 9b41c308b2..0000000000 --- a/Pythonnet.Runtime/pysequence.cs +++ /dev/null @@ -1,172 +0,0 @@ -// ========================================================================== -// This software is subject to the provisions of the Zope Public License, -// Version 2.0 (ZPL). A copy of the ZPL should accompany this distribution. -// THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED -// WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -// WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS -// FOR A PARTICULAR PURPOSE. -// ========================================================================== - -using System; -using System.Collections; - -namespace Python.Runtime { - - /// - /// Represents a generic Python sequence. The methods of this class are - /// equivalent to the Python "abstract sequence API". See - /// http://www.python.org/doc/current/api/sequence.html for details. - /// - - public class PySequence : PyObject, IEnumerable { - - protected PySequence(IntPtr ptr) : base(ptr) {} - - protected PySequence() : base() {} - - - /// - /// IsSequenceType Method - /// - /// - /// - /// Returns true if the given object implements the sequence protocol. - /// - - public static bool IsSequenceType(PyObject value) { - return Runtime.PySequence_Check(value.obj); - } - - - /// - /// GetSlice Method - /// - /// - /// - /// Return the slice of the sequence with the given indices. - /// - - public PyObject GetSlice(int i1, int i2) { - IntPtr op = Runtime.PySequence_GetSlice(obj, i1, i2); - if (op == IntPtr.Zero) { - throw new PythonException(); - } - return new PyObject(op); - } - - - /// - /// SetSlice Method - /// - /// - /// - /// Sets the slice of the sequence with the given indices. - /// - - public void SetSlice(int i1, int i2, PyObject v) { - int r = Runtime.PySequence_SetSlice(obj, i1, i2, v.obj); - if (r < 0) { - throw new PythonException(); - } - } - - - /// - /// DelSlice Method - /// - /// - /// - /// Deletes the slice of the sequence with the given indices. - /// - - public void DelSlice(int i1, int i2) { - int r = Runtime.PySequence_DelSlice(obj, i1, i2); - if (r < 0) { - throw new PythonException(); - } - } - - - /// - /// Index Method - /// - /// - /// - /// Return the index of the given item in the sequence, or -1 if - /// the item does not appear in the sequence. - /// - - public int Index(PyObject item) { - int r = Runtime.PySequence_Index(obj, item.obj); - if (r < 0) { - Runtime.PyErr_Clear(); - return -1; - } - return r; - } - - - /// - /// Contains Method - /// - /// - /// - /// Return true if the sequence contains the given item. This method - /// throws a PythonException if an error occurs during the check. - /// - - public bool Contains(PyObject item) { - int r = Runtime.PySequence_Contains(obj, item.obj); - if (r < 0) { - throw new PythonException(); - } - return (r != 0); - } - - - /// - /// Concat Method - /// - /// - /// - /// Return the concatenation of the sequence object with the passed in - /// sequence object. - /// - - public PyObject Concat(PyObject other) { - IntPtr op = Runtime.PySequence_Concat(obj, other.obj); - if (op == IntPtr.Zero) { - throw new PythonException(); - } - return new PyObject(op); - } - - - /// - /// Repeat Method - /// - /// - /// - /// Return the sequence object repeated N times. This is equivalent - /// to the Python expression "object * count". - /// - - public PyObject Repeat(int count) { - IntPtr op = Runtime.PySequence_Repeat(obj, count); - if (op == IntPtr.Zero) { - throw new PythonException(); - } - return new PyObject(op); - } - - #region IEnumerable Members - - public IEnumerator GetEnumerator() - { - return new PyIter(this); - } - - #endregion -} - -} diff --git a/Pythonnet.Runtime/pystring.cs b/Pythonnet.Runtime/pystring.cs deleted file mode 100644 index 818e124cd5..0000000000 --- a/Pythonnet.Runtime/pystring.cs +++ /dev/null @@ -1,85 +0,0 @@ -// ========================================================================== -// This software is subject to the provisions of the Zope Public License, -// Version 2.0 (ZPL). A copy of the ZPL should accompany this distribution. -// THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED -// WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -// WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS -// FOR A PARTICULAR PURPOSE. -// ========================================================================== - -using System; - -namespace Python.Runtime { - - /// - /// Represents a Python (ansi) string object. See the documentation at - /// http://www.python.org/doc/current/api/stringObjects.html for details. - /// 2011-01-29: ...Then why does the string constructor call PyUnicode_FromUnicode()??? - /// - - public class PyString : PySequence { - - /// - /// PyString Constructor - /// - /// - /// - /// Creates a new PyString from an existing object reference. Note - /// that the instance assumes ownership of the object reference. - /// The object reference is not checked for type-correctness. - /// - - public PyString(IntPtr ptr) : base(ptr) {} - - - /// - /// PyString Constructor - /// - /// - /// - /// Copy constructor - obtain a PyString from a generic PyObject. - /// An ArgumentException will be thrown if the given object is not - /// a Python string object. - /// - - public PyString(PyObject o) : base() { - if (!IsStringType(o)) { - throw new ArgumentException("object is not a string"); - } - Runtime.Incref(o.obj); - obj = o.obj; - } - - - /// - /// PyString Constructor - /// - /// - /// - /// Creates a Python string from a managed string. - /// - - public PyString(string s) : base() { - obj = Runtime.PyUnicode_FromUnicode(s, s.Length); - if (obj == IntPtr.Zero) { - throw new PythonException(); - } - } - - - /// - /// IsStringType Method - /// - /// - /// - /// Returns true if the given object is a Python string. - /// - - public static bool IsStringType(PyObject value) { - return Runtime.PyString_Check(value.obj); - } - - } - - -} diff --git a/Pythonnet.Runtime/pythonengine.cs b/Pythonnet.Runtime/pythonengine.cs deleted file mode 100644 index 07326185f3..0000000000 --- a/Pythonnet.Runtime/pythonengine.cs +++ /dev/null @@ -1,355 +0,0 @@ -// ========================================================================== -// This software is subject to the provisions of the Zope Public License, -// Version 2.0 (ZPL). A copy of the ZPL should accompany this distribution. -// THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED -// WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -// WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS -// FOR A PARTICULAR PURPOSE. -// ========================================================================== - -using System; -using System.Threading; - -namespace Python.Runtime { - - /// - /// This class provides the public interface of the Python runtime. - /// - - public class PythonEngine { - - private static DelegateManager delegateManager; - private static bool initialized; - - #region Properties - - public static bool IsInitialized { - get { - return initialized; - } - } - - internal static DelegateManager DelegateManager { - get { - if (delegateManager == null) { - throw new InvalidOperationException("DelegateManager has not yet been initialized using Python.Runtime.PythonEngine.Initialize()."); - } - return delegateManager; - } - } - - public static string ProgramName { - get { - string result = Runtime.Py_GetProgramName(); - if (result == null) { - return ""; - } - return result; - } - set { - Runtime.Py_SetProgramName(value); - } - } - - public static string PythonHome { - get { - string result = Runtime.Py_GetPythonHome(); - if (result == null) { - return ""; - } - return result; - } - set { - Runtime.Py_SetPythonHome(value); - } - } - - public static string Version { - get { - return Runtime.Py_GetVersion(); - } - } - - public static string BuildInfo { - get { - return Runtime.Py_GetBuildInfo(); - } - } - - public static string Platform { - get { - return Runtime.Py_GetPlatform(); - } - } - - public static string Copyright { - get { - return Runtime.Py_GetCopyright(); - } - } - - public static int RunSimpleString(string code) { - return Runtime.PyRun_SimpleString(code); - } - - #endregion - - - /// - /// Initialize Method - /// - /// - /// - /// Initialize the Python runtime. It is safe to call this method - /// more than once, though initialization will only happen on the - /// first call. It is *not* necessary to hold the Python global - /// interpreter lock (GIL) to call this method. - /// - - public static void Initialize() { - if (!initialized) { - // Creating the delegateManager MUST happen before Runtime.Initialize - // is called. If it happens afterwards, DelegateManager's CodeGenerator - // throws an exception in its ctor. This exception is eaten somehow - // during an initial "import clr", and the world ends shortly thereafter. - // This is probably masking some bad mojo happening somewhere in Runtime.Initialize(). - delegateManager = new DelegateManager(); - Runtime.Initialize(); - initialized = true; - Exceptions.Clear(); - } - } - - - //==================================================================== - // A helper to perform initialization from the context of an active - // CPython interpreter process - this bootstraps the managed runtime - // when it is imported by the CLR extension module. - //==================================================================== - - public static void InitExt() { - Initialize(); - - // Trickery - when the import hook is installed into an already - // running Python, the standard import machinery is still in - // control for the duration of the import that caused bootstrap. - // - // That is problematic because the std machinery tries to get - // sub-names directly from the module __dict__ rather than going - // through our module object's getattr hook. This workaround is - // evil ;) We essentially climb up the stack looking for the - // import that caused the bootstrap to happen, then re-execute - // the import explicitly after our hook has been installed. By - // doing this, the original outer import should work correctly. - // - // Note that this is only needed during the execution of the - // first import that installs the CLR import hook. This hack - // still doesn't work if you use the interactive interpreter, - // since there is no line info to get the import line ;( - - string code = - - "import traceback\n" + - "for item in traceback.extract_stack():\n" + - " line = item[3]\n" + - " if line is not None:\n" + - " if line.startswith('import CLR') or \\\n" + - " line.startswith('import clr') or \\\n" + - " line.startswith('from clr') or \\\n" + - " line.startswith('from CLR'):\n" + - " exec line\n" + - " break\n"; - - PyObject r = PythonEngine.RunString(code); - if (r != null) { - r.Dispose(); - } - } - - - /// - /// Shutdown Method - /// - /// - /// - /// Shutdown and release resources held by the Python runtime. The - /// Python runtime can no longer be used in the current process - /// after calling the Shutdown method. - /// - - public static void Shutdown() { - if (initialized) { - Runtime.Shutdown(); - initialized = false; - } - } - - - /// - /// AcquireLock Method - /// - /// - /// - /// Acquire the Python global interpreter lock (GIL). Managed code - /// *must* call this method before using any objects or calling any - /// methods on objects in the Python.Runtime namespace. The only - /// exception is PythonEngine.Initialize, which may be called without - /// first calling AcquireLock. - /// - /// Each call to AcquireLock must be matched by a corresponding call - /// to ReleaseLock, passing the token obtained from AcquireLock. - /// - /// For more information, see the "Extending and Embedding" section - /// of the Python documentation on www.python.org. - /// - - public static IntPtr AcquireLock() { - return Runtime.PyGILState_Ensure(); - } - - - /// - /// ReleaseLock Method - /// - /// - /// - /// Release the Python global interpreter lock using a token obtained - /// from a previous call to AcquireLock. - /// - /// For more information, see the "Extending and Embedding" section - /// of the Python documentation on www.python.org. - /// - - public static void ReleaseLock(IntPtr gs) { - Runtime.PyGILState_Release(gs); - } - - - /// - /// BeginAllowThreads Method - /// - /// - /// - /// Release the Python global interpreter lock to allow other threads - /// to run. This is equivalent to the Py_BEGIN_ALLOW_THREADS macro - /// provided by the C Python API. - /// - /// For more information, see the "Extending and Embedding" section - /// of the Python documentation on www.python.org. - /// - - public static IntPtr BeginAllowThreads() { - return Runtime.PyEval_SaveThread(); - } - - - /// - /// EndAllowThreads Method - /// - /// - /// - /// Re-aquire the Python global interpreter lock for the current - /// thread. This is equivalent to the Py_END_ALLOW_THREADS macro - /// provided by the C Python API. - /// - /// For more information, see the "Extending and Embedding" section - /// of the Python documentation on www.python.org. - /// - - public static void EndAllowThreads(IntPtr ts) { - Runtime.PyEval_RestoreThread(ts); - } - - - - /// - /// ImportModule Method - /// - /// - /// - /// Given a fully-qualified module or package name, import the - /// module and return the resulting module object as a PyObject - /// or null if an exception is raised. - /// - - public static PyObject ImportModule(string name) { - IntPtr op = Runtime.PyImport_ImportModule(name); - if (op == IntPtr.Zero) { - return null; - } - return new PyObject(op); - } - - - /// - /// ReloadModule Method - /// - /// - /// - /// Given a PyObject representing a previously loaded module, reload - /// the module. - /// - - public static PyObject ReloadModule(PyObject module) { - IntPtr op = Runtime.PyImport_ReloadModule(module.Handle); - if (op == IntPtr.Zero) { - throw new PythonException(); - } - return new PyObject(op); - } - - - /// - /// ModuleFromString Method - /// - /// - /// - /// Given a string module name and a string containing Python code, - /// execute the code in and return a module of the given name. - /// - - public static PyObject ModuleFromString(string name, string code) { - IntPtr c = Runtime.Py_CompileString(code, "none", (IntPtr)257); - if (c == IntPtr.Zero) { - throw new PythonException(); - } - IntPtr m = Runtime.PyImport_ExecCodeModule(name, c); - if (m == IntPtr.Zero) { - throw new PythonException(); - } - return new PyObject(m); - } - - - /// - /// RunString Method - /// - /// - /// - /// Run a string containing Python code. Returns the result of - /// executing the code string as a PyObject instance, or null if - /// an exception was raised. - /// - - public static PyObject RunString(string code) { - IntPtr globals = Runtime.PyEval_GetGlobals(); - IntPtr locals = Runtime.PyDict_New(); - - IntPtr builtins = Runtime.PyEval_GetBuiltins(); - Runtime.PyDict_SetItemString(locals, "__builtins__", builtins); - - IntPtr flag = (IntPtr)257; /* Py_file_input */ - IntPtr result = Runtime.PyRun_String(code, flag, globals, locals); - Runtime.Decref(locals); - if (result == IntPtr.Zero) { - return null; - } - return new PyObject(result); - } - - - - } - - -} diff --git a/Pythonnet.Runtime/pythonexception.cs b/Pythonnet.Runtime/pythonexception.cs deleted file mode 100644 index 592e9ea371..0000000000 --- a/Pythonnet.Runtime/pythonexception.cs +++ /dev/null @@ -1,150 +0,0 @@ -// ========================================================================== -// This software is subject to the provisions of the Zope Public License, -// Version 2.0 (ZPL). A copy of the ZPL should accompany this distribution. -// THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED -// WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -// WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS -// FOR A PARTICULAR PURPOSE. -// ========================================================================== - -using System; - -namespace Python.Runtime { - - /// - /// Provides a managed interface to exceptions thrown by the Python - /// runtime. - /// - - public class PythonException : System.Exception { - - private IntPtr _pyType = IntPtr.Zero; - private IntPtr _pyValue = IntPtr.Zero; - private IntPtr _pyTB = IntPtr.Zero; - private string _tb = ""; - private string _message = ""; - private bool disposed = false; - - public PythonException() : base() - { - IntPtr gs = PythonEngine.AcquireLock(); - Runtime.PyErr_Fetch(ref _pyType, ref _pyValue, ref _pyTB); - Runtime.Incref(_pyType); - Runtime.Incref(_pyValue); - Runtime.Incref(_pyTB); - if ((_pyType != IntPtr.Zero) && (_pyValue != IntPtr.Zero)) - { - string type = new PyObject(_pyType).GetAttr("__name__").ToString(); - string message = Runtime.GetManagedString(_pyValue); - _message = type + " : " + message; - } - if (_pyTB != IntPtr.Zero) - { - PyObject tb_module = PythonEngine.ImportModule("traceback"); - _tb = tb_module.InvokeMethod("format_tb", new PyObject(_pyTB)).ToString(); - } - PythonEngine.ReleaseLock(gs); - } - - // Ensure that encapsulated Python objects are decref'ed appropriately - // when the managed exception wrapper is garbage-collected. - - ~PythonException() { - Dispose(); - } - - - /// - /// PyType Property - /// - /// - /// - /// Returns the exception type as a Python object. - /// - - public IntPtr PyType - { - get { return _pyType; } - } - - /// - /// PyValue Property - /// - /// - /// - /// Returns the exception value as a Python object. - /// - - public IntPtr PyValue - { - get { return _pyValue; } - } - - /// - /// Message Property - /// - /// - /// - /// A string representing the python exception message. - /// - - public override string Message - { - get { return _message; } - } - - /// - /// StackTrace Property - /// - /// - /// - /// A string representing the python exception stack trace. - /// - - public override string StackTrace - { - get { return _tb; } - } - - - /// - /// Dispose Method - /// - /// - /// - /// The Dispose method provides a way to explicitly release the - /// Python objects represented by a PythonException. - /// - - public void Dispose() { - if (!disposed) { - if (Runtime.Py_IsInitialized() > 0) { - IntPtr gs = PythonEngine.AcquireLock(); - Runtime.Decref(_pyType); - Runtime.Decref(_pyValue); - // XXX Do we ever get TraceBack? // - if (_pyTB != IntPtr.Zero) { - Runtime.Decref(_pyTB); - } - PythonEngine.ReleaseLock(gs); - } - GC.SuppressFinalize(this); - disposed = true; - } - } - - /// - /// Matches Method - /// - /// - /// - /// Returns true if the Python exception type represented by the - /// PythonException instance matches the given exception type. - /// - - public static bool Matches(IntPtr ob) { - return Runtime.PyErr_ExceptionMatches(ob) != 0; - } - - } -} diff --git a/Pythonnet.Runtime/pytuple.cs b/Pythonnet.Runtime/pytuple.cs deleted file mode 100644 index cac41acf44..0000000000 --- a/Pythonnet.Runtime/pytuple.cs +++ /dev/null @@ -1,126 +0,0 @@ -// ========================================================================== -// This software is subject to the provisions of the Zope Public License, -// Version 2.0 (ZPL). A copy of the ZPL should accompany this distribution. -// THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED -// WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -// WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS -// FOR A PARTICULAR PURPOSE. -// ========================================================================== - -using System; - -namespace Python.Runtime { - - /// - /// Represents a Python tuple object. See the documentation at - /// http://www.python.org/doc/current/api/tupleObjects.html for details. - /// - - public class PyTuple : PySequence { - - /// - /// PyTuple Constructor - /// - /// - /// - /// Creates a new PyTuple from an existing object reference. Note - /// that the instance assumes ownership of the object reference. - /// The object reference is not checked for type-correctness. - /// - - public PyTuple(IntPtr ptr) : base(ptr) {} - - - /// - /// PyTuple Constructor - /// - /// - /// - /// Copy constructor - obtain a PyTuple from a generic PyObject. An - /// ArgumentException will be thrown if the given object is not a - /// Python tuple object. - /// - - public PyTuple(PyObject o) : base() { - if (!IsTupleType(o)) { - throw new ArgumentException("object is not a tuple"); - } - Runtime.Incref(o.obj); - obj = o.obj; - } - - - /// - /// PyTuple Constructor - /// - /// - /// - /// Creates a new empty PyTuple. - /// - - public PyTuple() : base() { - obj = Runtime.PyTuple_New(0); - if (obj == IntPtr.Zero) { - throw new PythonException(); - } - } - - - /// - /// PyTuple Constructor - /// - /// - /// - /// Creates a new PyTuple from an array of PyObject instances. - /// - - public PyTuple(PyObject[] items) : base() { - int count = items.Length; - obj = Runtime.PyTuple_New(count); - for (int i = 0; i < count; i++) { - IntPtr ptr = items[i].obj; - Runtime.Incref(ptr); - int r = Runtime.PyTuple_SetItem(obj, i, ptr); - if (r < 0) { - throw new PythonException(); - } - } - } - - - /// - /// IsTupleType Method - /// - /// - /// - /// Returns true if the given object is a Python tuple. - /// - - public static bool IsTupleType(PyObject value) { - return Runtime.PyTuple_Check(value.obj); - } - - - /// - /// AsTuple Method - /// - /// - /// - /// Convert a Python object to a Python tuple if possible, raising - /// a PythonException if the conversion is not possible. This is - /// equivalent to the Python expression "tuple(object)". - /// - - public static PyTuple AsTuple(PyObject value) { - IntPtr op = Runtime.PySequence_Tuple(value.obj); - if (op == IntPtr.Zero) { - throw new PythonException(); - } - return new PyTuple(op); - } - - - } - - -} diff --git a/Pythonnet.Runtime/runtime.cs b/Pythonnet.Runtime/runtime.cs deleted file mode 100644 index 3c516092dd..0000000000 --- a/Pythonnet.Runtime/runtime.cs +++ /dev/null @@ -1,1606 +0,0 @@ -// ========================================================================== -// This software is subject to the provisions of the Zope Public License, -// Version 2.0 (ZPL). A copy of the ZPL should accompany this distribution. -// THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED -// WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -// WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS -// FOR A PARTICULAR PURPOSE. -// ========================================================================== - -using System; -using System.Runtime.InteropServices; -using System.Security; -#if (UCS4) -using System.Text; -using Mono.Unix; -#endif - -namespace Python.Runtime { - - [SuppressUnmanagedCodeSecurityAttribute()] - - public class Runtime { - - /// - /// Encapsulates the low-level Python C API. Note that it is - /// the responsibility of the caller to have acquired the GIL - /// before calling any of these methods. - /// -#if (UCS4) - public const int UCS = 4; -#endif -#if (UCS2) - public const int UCS = 2; -#endif -#if ! (UCS2 || UCS4) -#error You must define either UCS2 or UCS4! -#endif - -#if (PYTHON23) - public const string dll = "python23"; - public const string pyversion = "2.3"; - public const int pyversionnumber = 23; -#endif -#if (PYTHON24) - public const string dll = "python24"; - public const string pyversion = "2.4"; - public const int pyversionnumber = 24; -#endif -#if (PYTHON25) - public const string dll = "python25"; - public const string pyversion = "2.5"; - public const int pyversionnumber = 25; -#endif -#if (PYTHON26) - public const string dll = "python26"; - public const string pyversion = "2.6"; - public const int pyversionnumber = 26; -#endif -#if (PYTHON27) - public const string dll = "python27"; - public const string pyversion = "2.7"; - public const int pyversionnumber = 27; -#endif -#if ! (PYTHON23 || PYTHON24 || PYTHON25 || PYTHON26 || PYTHON27) -#error You must define one of PYTHON23 to PYTHON27 -#endif - - public static bool wrap_exceptions; - public static bool is32bit; - - /// - /// Intitialize the runtime... - /// - public static void Initialize() { - - is32bit = IntPtr.Size == 4; - - Runtime.Py_Initialize(); - Runtime.PyEval_InitThreads(); - - IntPtr dict = Runtime.PyImport_GetModuleDict(); - IntPtr op = Runtime.PyDict_GetItemString(dict, "__builtin__"); - - PyBaseObjectType = Runtime.PyObject_GetAttrString(op, "object"); - - PyModuleType = Runtime.PyObject_Type(op); - PyNone = Runtime.PyObject_GetAttrString(op, "None"); - PyTrue = Runtime.PyObject_GetAttrString(op, "True"); - PyFalse = Runtime.PyObject_GetAttrString(op, "False"); - - PyBoolType = Runtime.PyObject_Type(PyTrue); - - PyNoneType = Runtime.PyObject_Type(PyNone); - PyTypeType = Runtime.PyObject_Type(PyNoneType); - - op = Runtime.PyObject_GetAttrString(dict, "keys"); - PyMethodType = Runtime.PyObject_Type(op); - Runtime.Decref(op); - - op = Runtime.PyString_FromString("string"); - PyStringType = Runtime.PyObject_Type(op); - Runtime.Decref(op); - - op = Runtime.PyUnicode_FromString("unicode"); - PyUnicodeType = Runtime.PyObject_Type(op); - Runtime.Decref(op); - - op = Runtime.PyTuple_New(0); - PyTupleType = Runtime.PyObject_Type(op); - Runtime.Decref(op); - - op = Runtime.PyList_New(0); - PyListType = Runtime.PyObject_Type(op); - Runtime.Decref(op); - - op = Runtime.PyDict_New(); - PyDictType = Runtime.PyObject_Type(op); - Runtime.Decref(op); - - op = Runtime.PyInt_FromInt32(0); - PyIntType = Runtime.PyObject_Type(op); - Runtime.Decref(op); - - op = Runtime.PyLong_FromLong(0); - PyLongType = Runtime.PyObject_Type(op); - Runtime.Decref(op); - - op = Runtime.PyFloat_FromDouble(0); - PyFloatType = Runtime.PyObject_Type(op); - Runtime.Decref(op); - - IntPtr s = Runtime.PyString_FromString("_temp"); - IntPtr d = Runtime.PyDict_New(); - IntPtr c = Runtime.PyClass_New(IntPtr.Zero, d, s); - PyClassType = Runtime.PyObject_Type(c); - - IntPtr i = Runtime.PyInstance_New(c, IntPtr.Zero, IntPtr.Zero); - PyInstanceType = Runtime.PyObject_Type(i); - - Runtime.Decref(s); - Runtime.Decref(i); - Runtime.Decref(c); - Runtime.Decref(d); - - Error = new IntPtr(-1); - - // Determine whether we need to wrap exceptions for versions of - // of the Python runtime that do not allow new-style classes to - // be used as exceptions (Python versions 2.4 and lower). - -#if (PYTHON25 || PYTHON26 || PYTHON27) - wrap_exceptions = false; -#else - IntPtr m = PyImport_ImportModule("exceptions"); - Exceptions.ErrorCheck(m); - op = Runtime.PyObject_GetAttrString(m, "Exception"); - Exceptions.ErrorCheck(op); - if (Runtime.PyObject_TYPE(op) == PyClassType) { - wrap_exceptions = true; - } - Runtime.Decref(op); - Runtime.Decref(m); -#endif - - // Initialize modules that depend on the runtime class. - AssemblyManager.Initialize(); - PyCLRMetaType = MetaType.Initialize(); - Exceptions.Initialize(); - ImportHook.Initialize(); - - // Need to add the runtime directory to sys.path so that we - // can find built-in assemblies like System.Data, et. al. - string rtdir = RuntimeEnvironment.GetRuntimeDirectory(); - IntPtr path = Runtime.PySys_GetObject("path"); - IntPtr item = Runtime.PyString_FromString(rtdir); - Runtime.PyList_Append(path, item); - Runtime.Decref(item); - AssemblyManager.UpdatePath(); - } - - public static void Shutdown() { - AssemblyManager.Shutdown(); - Exceptions.Shutdown(); - ImportHook.Shutdown(); - Py_Finalize(); - } - - public static IntPtr Py_single_input = (IntPtr)256; - public static IntPtr Py_file_input = (IntPtr)257; - public static IntPtr Py_eval_input = (IntPtr)258; - - public static IntPtr PyBaseObjectType; - public static IntPtr PyModuleType; - public static IntPtr PyClassType; - public static IntPtr PyInstanceType; - public static IntPtr PyCLRMetaType; - public static IntPtr PyMethodType; - - public static IntPtr PyUnicodeType; - public static IntPtr PyStringType; - public static IntPtr PyTupleType; - public static IntPtr PyListType; - public static IntPtr PyDictType; - public static IntPtr PyIntType; - public static IntPtr PyLongType; - public static IntPtr PyFloatType; - public static IntPtr PyBoolType; - public static IntPtr PyNoneType; - public static IntPtr PyTypeType; - - public static IntPtr PyTrue; - public static IntPtr PyFalse; - public static IntPtr PyNone; - public static IntPtr Error; - - - - public static IntPtr GetBoundArgTuple(IntPtr obj, IntPtr args) { - if (Runtime.PyObject_TYPE(args) != Runtime.PyTupleType) { - Exceptions.SetError(Exceptions.TypeError, "tuple expected"); - return IntPtr.Zero; - } - int size = Runtime.PyTuple_Size(args); - IntPtr items = Runtime.PyTuple_New(size + 1); - Runtime.PyTuple_SetItem(items, 0, obj); - Runtime.Incref(obj); - - for (int i = 0; i < size; i++) { - IntPtr item = Runtime.PyTuple_GetItem(args, i); - Runtime.Incref(item); - Runtime.PyTuple_SetItem(items, i + 1, item); - } - - return items; - } - - - public static IntPtr ExtendTuple(IntPtr t, params IntPtr[] args) { - int size = Runtime.PyTuple_Size(t); - int add = args.Length; - IntPtr item; - - IntPtr items = Runtime.PyTuple_New(size + add); - for (int i = 0; i < size; i++) { - item = Runtime.PyTuple_GetItem(t, i); - Runtime.Incref(item); - Runtime.PyTuple_SetItem(items, i, item); - } - - for (int n = 0; n < add; n++) { - item = args[n]; - Runtime.Incref(item); - Runtime.PyTuple_SetItem(items, size + n, item); - } - - return items; - } - - public static Type[] PythonArgsToTypeArray(IntPtr arg) { - return PythonArgsToTypeArray(arg, false); - } - - public static Type[] PythonArgsToTypeArray(IntPtr arg, bool mangleObjects) { - // Given a PyObject * that is either a single type object or a - // tuple of (managed or unmanaged) type objects, return a Type[] - // containing the CLR Type objects that map to those types. - IntPtr args = arg; - bool free = false; - - if (!Runtime.PyTuple_Check(arg)) { - args = Runtime.PyTuple_New(1); - Runtime.Incref(arg); - Runtime.PyTuple_SetItem(args, 0, arg); - free = true; - } - - int n = Runtime.PyTuple_Size(args); - Type[] types = new Type[n]; - Type t = null; - - for (int i = 0; i < n; i++) { - IntPtr op = Runtime.PyTuple_GetItem(args, i); - if (mangleObjects && (!Runtime.PyType_Check(op))) { - op = Runtime.PyObject_TYPE(op); - } - ManagedType mt = ManagedType.GetManagedObject(op); - - if (mt is ClassBase) { - t = ((ClassBase)mt).type; - } - else if (mt is CLRObject) { - object inst = ((CLRObject)mt).inst; - if (inst is Type) { - t = inst as Type; - } - } - else { - t = Converter.GetTypeByAlias(op); - } - - if (t == null) { - types = null; - break; - } - types[i] = t; - } - if (free) { - Runtime.Decref(args); - } - return types; - } - - //=================================================================== - // Managed exports of the Python C API. Where appropriate, we do - // some optimization to avoid managed <--> unmanaged transitions - // (mostly for heavily used methods). - //=================================================================== - - public unsafe static void Incref(IntPtr op) { -#if (Py_DEBUG) - Py_IncRef(op); - return; -#else - void* p = (void*)op; - if ((void*)0 != p) { - if (is32bit) { (*(int*)p)++; } - else { (*(long*)p)++; } - } -#endif - } - - public unsafe static void Decref(IntPtr op) { - if (op == IntPtr.Zero) { - DebugUtil.Print("Decref(NULL)"); - } -#if (Py_DEBUG) - // Py_DecRef calls Python's Py_DECREF - Py_DecRef(op); - return; -#else - void* p = (void*)op; - if ((void*)0 != p) { - if (is32bit) { --(*(int*)p); } - else { --(*(long*)p); } - if ((*(int*)p) == 0) { - // PyObject_HEAD: struct _typeobject *ob_type - void* t = is32bit ? (void*)(*((uint*)p + 1)) : - (void*)(*((ulong*)p + 1)); - // PyTypeObject: destructor tp_dealloc - void* f = is32bit ? (void*)(*((uint*)t + 6)) : - (void*)(*((ulong*)t + 6)); - if ((void*)0 == f) { - return; - } - NativeCall.Impl.Void_Call_1(new IntPtr(f), op); - return; - } - } -#endif - } - -#if (Py_DEBUG) - // Py_IncRef and Py_DecRef are taking care of the extra payload - // in Py_DEBUG builds of Python like _Py_RefTotal - [DllImport(Runtime.dll, CallingConvention=CallingConvention.Cdecl, - ExactSpelling=true, CharSet=CharSet.Ansi)] - private unsafe static extern void - Py_IncRef(IntPtr ob); - - [DllImport(Runtime.dll, CallingConvention=CallingConvention.Cdecl, - ExactSpelling=true, CharSet=CharSet.Ansi)] - private unsafe static extern void - Py_DecRef(IntPtr ob); -#endif - - [DllImport(Runtime.dll, CallingConvention = CallingConvention.Cdecl, - ExactSpelling = true, CharSet = CharSet.Ansi)] - public unsafe static extern void - Py_Initialize(); - - [DllImport(Runtime.dll, CallingConvention = CallingConvention.Cdecl, - ExactSpelling = true, CharSet = CharSet.Ansi)] - public unsafe static extern int - Py_IsInitialized(); - - [DllImport(Runtime.dll, CallingConvention = CallingConvention.Cdecl, - ExactSpelling = true, CharSet = CharSet.Ansi)] - public unsafe static extern void - Py_Finalize(); - - [DllImport(Runtime.dll, CallingConvention = CallingConvention.Cdecl, - ExactSpelling = true, CharSet = CharSet.Ansi)] - public unsafe static extern IntPtr - Py_NewInterpreter(); - - [DllImport(Runtime.dll, CallingConvention = CallingConvention.Cdecl, - ExactSpelling = true, CharSet = CharSet.Ansi)] - public unsafe static extern void - Py_EndInterpreter(IntPtr threadState); - - [DllImport(Runtime.dll, CallingConvention = CallingConvention.Cdecl, - ExactSpelling = true, CharSet = CharSet.Ansi)] - public unsafe static extern IntPtr - PyThreadState_New(IntPtr istate); - - [DllImport(Runtime.dll, CallingConvention = CallingConvention.Cdecl, - ExactSpelling = true, CharSet = CharSet.Ansi)] - public unsafe static extern IntPtr - PyThreadState_Get(); - - [DllImport(Runtime.dll, CallingConvention = CallingConvention.Cdecl, - ExactSpelling = true, CharSet = CharSet.Ansi)] - public unsafe static extern IntPtr - PyThread_get_key_value(IntPtr key); - - [DllImport(Runtime.dll, CallingConvention = CallingConvention.Cdecl, - ExactSpelling = true, CharSet = CharSet.Ansi)] - public unsafe static extern int - PyThread_get_thread_ident(); - - [DllImport(Runtime.dll, CallingConvention = CallingConvention.Cdecl, - ExactSpelling = true, CharSet = CharSet.Ansi)] - public unsafe static extern int - PyThread_set_key_value(IntPtr key, IntPtr value); - - [DllImport(Runtime.dll, CallingConvention = CallingConvention.Cdecl, - ExactSpelling = true, CharSet = CharSet.Ansi)] - public unsafe static extern IntPtr - PyThreadState_Swap(IntPtr key); - - - [DllImport(Runtime.dll, CallingConvention = CallingConvention.Cdecl, - ExactSpelling = true, CharSet = CharSet.Ansi)] - public unsafe static extern IntPtr - PyGILState_Ensure(); - - [DllImport(Runtime.dll, CallingConvention = CallingConvention.Cdecl, - ExactSpelling = true, CharSet = CharSet.Ansi)] - public unsafe static extern void - PyGILState_Release(IntPtr gs); - - - [DllImport(Runtime.dll, CallingConvention = CallingConvention.Cdecl, - ExactSpelling = true, CharSet = CharSet.Ansi)] - public unsafe static extern IntPtr - PyGILState_GetThisThreadState(); - - [DllImport(Runtime.dll, CallingConvention = CallingConvention.Cdecl, - ExactSpelling = true, CharSet = CharSet.Ansi)] - public unsafe static extern int - Py_Main(int argc, string[] argv); - - [DllImport(Runtime.dll, CallingConvention = CallingConvention.Cdecl, - ExactSpelling = true, CharSet = CharSet.Ansi)] - public unsafe static extern void - PyEval_InitThreads(); - - [DllImport(Runtime.dll, CallingConvention = CallingConvention.Cdecl, - ExactSpelling = true, CharSet = CharSet.Ansi)] - public unsafe static extern void - PyEval_AcquireLock(); - - [DllImport(Runtime.dll, CallingConvention = CallingConvention.Cdecl, - ExactSpelling = true, CharSet = CharSet.Ansi)] - public unsafe static extern void - PyEval_ReleaseLock(); - - [DllImport(Runtime.dll, CallingConvention = CallingConvention.Cdecl, - ExactSpelling = true, CharSet = CharSet.Ansi)] - public unsafe static extern void - PyEval_AcquireThread(IntPtr tstate); - - [DllImport(Runtime.dll, CallingConvention = CallingConvention.Cdecl, - ExactSpelling = true, CharSet = CharSet.Ansi)] - public unsafe static extern void - PyEval_ReleaseThread(IntPtr tstate); - - [DllImport(Runtime.dll, CallingConvention = CallingConvention.Cdecl, - ExactSpelling = true, CharSet = CharSet.Ansi)] - public unsafe static extern IntPtr - PyEval_SaveThread(); - - [DllImport(Runtime.dll, CallingConvention = CallingConvention.Cdecl, - ExactSpelling = true, CharSet = CharSet.Ansi)] - public unsafe static extern void - PyEval_RestoreThread(IntPtr tstate); - - [DllImport(Runtime.dll, CallingConvention = CallingConvention.Cdecl, - ExactSpelling = true, CharSet = CharSet.Ansi)] - public unsafe static extern IntPtr - PyEval_GetBuiltins(); - - [DllImport(Runtime.dll, CallingConvention = CallingConvention.Cdecl, - ExactSpelling = true, CharSet = CharSet.Ansi)] - public unsafe static extern IntPtr - PyEval_GetGlobals(); - - [DllImport(Runtime.dll, CallingConvention = CallingConvention.Cdecl, - ExactSpelling = true, CharSet = CharSet.Ansi)] - public unsafe static extern IntPtr - PyEval_GetLocals(); - - - [DllImport(Runtime.dll, CallingConvention = CallingConvention.Cdecl, - ExactSpelling = true, CharSet = CharSet.Ansi)] - public unsafe static extern string - Py_GetProgramName(); - - [DllImport(Runtime.dll, CallingConvention = CallingConvention.Cdecl, - ExactSpelling = true, CharSet = CharSet.Ansi)] - public unsafe static extern void - Py_SetProgramName(string name); - - [DllImport(Runtime.dll, CallingConvention = CallingConvention.Cdecl, - ExactSpelling = true, CharSet = CharSet.Ansi)] - public unsafe static extern string - Py_GetPythonHome(); - - [DllImport(Runtime.dll, CallingConvention = CallingConvention.Cdecl, - ExactSpelling = true, CharSet = CharSet.Ansi)] - public unsafe static extern void - Py_SetPythonHome(string home); - - [DllImport(Runtime.dll, CallingConvention = CallingConvention.Cdecl, - ExactSpelling = true, CharSet = CharSet.Ansi)] - public unsafe static extern string - Py_GetVersion(); - - [DllImport(Runtime.dll, CallingConvention = CallingConvention.Cdecl, - ExactSpelling = true, CharSet = CharSet.Ansi)] - public unsafe static extern string - Py_GetPlatform(); - - [DllImport(Runtime.dll, CallingConvention = CallingConvention.Cdecl, - ExactSpelling = true, CharSet = CharSet.Ansi)] - public unsafe static extern string - Py_GetCopyright(); - - [DllImport(Runtime.dll, CallingConvention = CallingConvention.Cdecl, - ExactSpelling = true, CharSet = CharSet.Ansi)] - public unsafe static extern string - Py_GetCompiler(); - - [DllImport(Runtime.dll, CallingConvention = CallingConvention.Cdecl, - ExactSpelling = true, CharSet = CharSet.Ansi)] - public unsafe static extern string - Py_GetBuildInfo(); - - [DllImport(Runtime.dll, CallingConvention = CallingConvention.Cdecl, - ExactSpelling = true, CharSet = CharSet.Ansi)] - public unsafe static extern int - PyRun_SimpleString(string code); - - [DllImport(Runtime.dll, CallingConvention = CallingConvention.Cdecl, - ExactSpelling = true, CharSet = CharSet.Ansi)] - public unsafe static extern IntPtr - PyRun_String(string code, IntPtr st, IntPtr globals, IntPtr locals); - - [DllImport(Runtime.dll, CallingConvention = CallingConvention.Cdecl, - ExactSpelling = true, CharSet = CharSet.Ansi)] - public unsafe static extern IntPtr - Py_CompileString(string code, string file, IntPtr tok); - - [DllImport(Runtime.dll, CallingConvention = CallingConvention.Cdecl, - ExactSpelling = true, CharSet = CharSet.Ansi)] - public unsafe static extern IntPtr - PyImport_ExecCodeModule(string name, IntPtr code); - - [DllImport(Runtime.dll, CallingConvention = CallingConvention.Cdecl, - ExactSpelling = true, CharSet = CharSet.Ansi)] - public unsafe static extern IntPtr - PyCFunction_New(IntPtr ml, IntPtr self); - - [DllImport(Runtime.dll, CallingConvention = CallingConvention.Cdecl, - ExactSpelling = true, CharSet = CharSet.Ansi)] - public unsafe static extern IntPtr - PyCFunction_NewEx(IntPtr ml, IntPtr self, IntPtr mod); - - [DllImport(Runtime.dll, CallingConvention = CallingConvention.Cdecl, - ExactSpelling = true, CharSet = CharSet.Ansi)] - public unsafe static extern IntPtr - PyCFunction_Call(IntPtr func, IntPtr args, IntPtr kw); - - [DllImport(Runtime.dll, CallingConvention = CallingConvention.Cdecl, - ExactSpelling = true, CharSet = CharSet.Ansi)] - public unsafe static extern IntPtr - PyClass_New(IntPtr bases, IntPtr dict, IntPtr name); - - [DllImport(Runtime.dll, CallingConvention = CallingConvention.Cdecl, - ExactSpelling = true, CharSet = CharSet.Ansi)] - public unsafe static extern IntPtr - PyInstance_New(IntPtr cls, IntPtr args, IntPtr kw); - - [DllImport(Runtime.dll, CallingConvention = CallingConvention.Cdecl, - ExactSpelling = true, CharSet = CharSet.Ansi)] - public unsafe static extern IntPtr - PyInstance_NewRaw(IntPtr cls, IntPtr dict); - - [DllImport(Runtime.dll, CallingConvention = CallingConvention.Cdecl, - ExactSpelling = true, CharSet = CharSet.Ansi)] - public unsafe static extern IntPtr - PyMethod_New(IntPtr func, IntPtr self, IntPtr cls); - - - //==================================================================== - // Python abstract object API - //==================================================================== - - // A macro-like method to get the type of a Python object. This is - // designed to be lean and mean in IL & avoid managed <-> unmanaged - // transitions. Note that this does not incref the type object. - - public unsafe static IntPtr - PyObject_TYPE(IntPtr op) { - void* p = (void*)op; - if ((void*)0 == p) { - return IntPtr.Zero; - } -#if (Py_DEBUG) - int n = 3; -#else - int n = 1; -#endif - if (is32bit) { - return new IntPtr((void*)(*((uint*)p + n))); - } - else { - return new IntPtr((void*)(*((ulong*)p + n))); - } - } - - // Managed version of the standard Python C API PyObject_Type call. - // This version avoids a managed <-> unmanaged transition. This one - // does incref the returned type object. - - [CLSCompliant(false)] - public unsafe static IntPtr - PyObject_Type(IntPtr op) { - IntPtr tp = PyObject_TYPE(op); - Runtime.Incref(tp); - return tp; - } - - public static string PyObject_GetTypeName(IntPtr op) { - IntPtr pyType = Marshal.ReadIntPtr(op, ObjectOffset.ob_type); - IntPtr ppName = Marshal.ReadIntPtr(pyType, TypeOffset.tp_name); - return Marshal.PtrToStringAnsi(ppName); - } - - [DllImport(Runtime.dll, CallingConvention = CallingConvention.Cdecl, - ExactSpelling = true, CharSet = CharSet.Ansi)] - public unsafe static extern int - PyObject_HasAttrString(IntPtr pointer, string name); - - [DllImport(Runtime.dll, CallingConvention = CallingConvention.Cdecl, - ExactSpelling = true, CharSet = CharSet.Ansi)] - public unsafe static extern IntPtr - PyObject_GetAttrString(IntPtr pointer, string name); - - [DllImport(Runtime.dll, CallingConvention = CallingConvention.Cdecl, - ExactSpelling = true, CharSet = CharSet.Ansi)] - public unsafe static extern int - PyObject_SetAttrString(IntPtr pointer, string name, IntPtr value); - - [DllImport(Runtime.dll, CallingConvention = CallingConvention.Cdecl, - ExactSpelling = true, CharSet = CharSet.Ansi)] - public unsafe static extern int - PyObject_HasAttr(IntPtr pointer, IntPtr name); - - [DllImport(Runtime.dll, CallingConvention = CallingConvention.Cdecl, - ExactSpelling = true, CharSet = CharSet.Ansi)] - public unsafe static extern IntPtr - PyObject_GetAttr(IntPtr pointer, IntPtr name); - - [DllImport(Runtime.dll, CallingConvention = CallingConvention.Cdecl, - ExactSpelling = true, CharSet = CharSet.Ansi)] - public unsafe static extern int - PyObject_SetAttr(IntPtr pointer, IntPtr name, IntPtr value); - - [DllImport(Runtime.dll, CallingConvention = CallingConvention.Cdecl, - ExactSpelling = true, CharSet = CharSet.Ansi)] - public unsafe static extern IntPtr - PyObject_GetItem(IntPtr pointer, IntPtr key); - - [DllImport(Runtime.dll, CallingConvention = CallingConvention.Cdecl, - ExactSpelling = true, CharSet = CharSet.Ansi)] - public unsafe static extern int - PyObject_SetItem(IntPtr pointer, IntPtr key, IntPtr value); - - [DllImport(Runtime.dll, CallingConvention = CallingConvention.Cdecl, - ExactSpelling = true, CharSet = CharSet.Ansi)] - public unsafe static extern int - PyObject_DelItem(IntPtr pointer, IntPtr key); - - [DllImport(Runtime.dll, CallingConvention = CallingConvention.Cdecl, - ExactSpelling = true, CharSet = CharSet.Ansi)] - public unsafe static extern IntPtr - PyObject_GetIter(IntPtr op); - - [DllImport(Runtime.dll, CallingConvention = CallingConvention.Cdecl, - ExactSpelling = true, CharSet = CharSet.Ansi)] - public unsafe static extern IntPtr - PyObject_Call(IntPtr pointer, IntPtr args, IntPtr kw); - - [DllImport(Runtime.dll, CallingConvention = CallingConvention.Cdecl, - ExactSpelling = true, CharSet = CharSet.Ansi)] - public unsafe static extern IntPtr - PyObject_CallObject(IntPtr pointer, IntPtr args); - - [DllImport(Runtime.dll, CallingConvention = CallingConvention.Cdecl, - ExactSpelling = true, CharSet = CharSet.Ansi)] - public unsafe static extern int - PyObject_Compare(IntPtr value1, IntPtr value2); - - [DllImport(Runtime.dll, CallingConvention = CallingConvention.Cdecl, - ExactSpelling = true, CharSet = CharSet.Ansi)] - public unsafe static extern int - PyObject_IsInstance(IntPtr ob, IntPtr type); - - [DllImport(Runtime.dll, CallingConvention = CallingConvention.Cdecl, - ExactSpelling = true, CharSet = CharSet.Ansi)] - public unsafe static extern int - PyObject_IsSubclass(IntPtr ob, IntPtr type); - - [DllImport(Runtime.dll, CallingConvention = CallingConvention.Cdecl, - ExactSpelling = true, CharSet = CharSet.Ansi)] - public unsafe static extern int - PyCallable_Check(IntPtr pointer); - - [DllImport(Runtime.dll, CallingConvention = CallingConvention.Cdecl, - ExactSpelling = true, CharSet = CharSet.Ansi)] - public unsafe static extern int - PyObject_IsTrue(IntPtr pointer); - - [DllImport(Runtime.dll, CallingConvention = CallingConvention.Cdecl, - ExactSpelling = true, CharSet = CharSet.Ansi)] - public unsafe static extern int - PyObject_Size(IntPtr pointer); - - [DllImport(Runtime.dll, CallingConvention = CallingConvention.Cdecl, - ExactSpelling = true, CharSet = CharSet.Ansi)] - public unsafe static extern IntPtr - PyObject_Hash(IntPtr op); - - [DllImport(Runtime.dll, CallingConvention = CallingConvention.Cdecl, - ExactSpelling = true, CharSet = CharSet.Ansi)] - public unsafe static extern IntPtr - PyObject_Repr(IntPtr pointer); - - [DllImport(Runtime.dll, CallingConvention = CallingConvention.Cdecl, - ExactSpelling = true, CharSet = CharSet.Ansi)] - public unsafe static extern IntPtr - PyObject_Str(IntPtr pointer); - - [DllImport(Runtime.dll, CallingConvention = CallingConvention.Cdecl, - ExactSpelling = true, CharSet = CharSet.Ansi)] - public unsafe static extern IntPtr - PyObject_Unicode(IntPtr pointer); - - [DllImport(Runtime.dll, CallingConvention = CallingConvention.Cdecl, - ExactSpelling = true, CharSet = CharSet.Ansi)] - public unsafe static extern IntPtr - PyObject_Dir(IntPtr pointer); - - - //==================================================================== - // Python number API - //==================================================================== - - [DllImport(Runtime.dll, CallingConvention = CallingConvention.Cdecl, - ExactSpelling = true, CharSet = CharSet.Ansi)] - public unsafe static extern IntPtr - PyNumber_Int(IntPtr ob); - - [DllImport(Runtime.dll, CallingConvention = CallingConvention.Cdecl, - ExactSpelling = true, CharSet = CharSet.Ansi)] - public unsafe static extern IntPtr - PyNumber_Long(IntPtr ob); - - [DllImport(Runtime.dll, CallingConvention = CallingConvention.Cdecl, - ExactSpelling = true, CharSet = CharSet.Ansi)] - public unsafe static extern IntPtr - PyNumber_Float(IntPtr ob); - - - [DllImport(Runtime.dll, CallingConvention = CallingConvention.Cdecl, - ExactSpelling = true, CharSet = CharSet.Ansi)] - public unsafe static extern bool - PyNumber_Check(IntPtr ob); - - - public static bool PyInt_Check(IntPtr ob) { - return PyObject_TypeCheck(ob, Runtime.PyIntType); - } - - public static bool PyBool_Check(IntPtr ob) { - return PyObject_TypeCheck(ob, Runtime.PyBoolType); - } - - - - [DllImport(Runtime.dll, CallingConvention = CallingConvention.Cdecl, - ExactSpelling = true, CharSet = CharSet.Ansi)] - private unsafe static extern IntPtr - PyInt_FromLong(IntPtr value); - - public static IntPtr PyInt_FromInt32(int value) { - IntPtr v = new IntPtr(value); - return PyInt_FromLong(v); - } - - public static IntPtr PyInt_FromInt64(long value) { - IntPtr v = new IntPtr(value); - return PyInt_FromLong(v); - } - - - [DllImport(Runtime.dll, CallingConvention = CallingConvention.Cdecl, - ExactSpelling = true, CharSet = CharSet.Ansi)] - public unsafe static extern int - PyInt_AsLong(IntPtr value); - - [DllImport(Runtime.dll, CallingConvention = CallingConvention.Cdecl, - ExactSpelling = true, CharSet = CharSet.Ansi)] - public unsafe static extern IntPtr - PyInt_FromString(string value, IntPtr end, int radix); - - [DllImport(Runtime.dll, CallingConvention = CallingConvention.Cdecl, - ExactSpelling = true, CharSet = CharSet.Ansi)] - public unsafe static extern int - PyInt_GetMax(); - - - public static bool PyLong_Check(IntPtr ob) { - return PyObject_TYPE(ob) == Runtime.PyLongType; - } - - [DllImport(Runtime.dll, CallingConvention = CallingConvention.Cdecl, - ExactSpelling = true, CharSet = CharSet.Ansi)] - public unsafe static extern IntPtr - PyLong_FromLong(long value); - - [CLSCompliant(false)] - [DllImport(Runtime.dll, CallingConvention = CallingConvention.Cdecl, - ExactSpelling = true, CharSet = CharSet.Ansi)] - public unsafe static extern IntPtr - PyLong_FromUnsignedLong(uint value); - - [DllImport(Runtime.dll, CallingConvention = CallingConvention.Cdecl, - ExactSpelling = true, CharSet = CharSet.Ansi)] - public unsafe static extern IntPtr - PyLong_FromDouble(double value); - - [DllImport(Runtime.dll, CallingConvention = CallingConvention.Cdecl, - ExactSpelling = true, CharSet = CharSet.Ansi)] - public unsafe static extern IntPtr - PyLong_FromLongLong(long value); - - [CLSCompliant(false)] - [DllImport(Runtime.dll, CallingConvention = CallingConvention.Cdecl, - ExactSpelling = true, CharSet = CharSet.Ansi)] - public unsafe static extern IntPtr - PyLong_FromUnsignedLongLong(ulong value); - - [DllImport(Runtime.dll, CallingConvention = CallingConvention.Cdecl, - ExactSpelling = true, CharSet = CharSet.Ansi)] - public unsafe static extern IntPtr - PyLong_FromString(string value, IntPtr end, int radix); - - [DllImport(Runtime.dll, CallingConvention = CallingConvention.Cdecl, - ExactSpelling = true, CharSet = CharSet.Ansi)] - public unsafe static extern int - PyLong_AsLong(IntPtr value); - - [CLSCompliant(false)] - [DllImport(Runtime.dll, CallingConvention = CallingConvention.Cdecl, - ExactSpelling = true, CharSet = CharSet.Ansi)] - public unsafe static extern uint - PyLong_AsUnsignedLong(IntPtr value); - - [DllImport(Runtime.dll, CallingConvention = CallingConvention.Cdecl, - ExactSpelling = true, CharSet = CharSet.Ansi)] - public unsafe static extern long - PyLong_AsLongLong(IntPtr value); - - [CLSCompliant(false)] - [DllImport(Runtime.dll, CallingConvention = CallingConvention.Cdecl, - ExactSpelling = true, CharSet = CharSet.Ansi)] - public unsafe static extern ulong - PyLong_AsUnsignedLongLong(IntPtr value); - - - public static bool PyFloat_Check(IntPtr ob) { - return PyObject_TYPE(ob) == Runtime.PyFloatType; - } - - [DllImport(Runtime.dll, CallingConvention = CallingConvention.Cdecl, - ExactSpelling = true, CharSet = CharSet.Ansi)] - public unsafe static extern IntPtr - PyFloat_FromDouble(double value); - - [DllImport(Runtime.dll, CallingConvention = CallingConvention.Cdecl, - ExactSpelling = true, CharSet = CharSet.Ansi)] - public unsafe static extern IntPtr - PyFloat_FromString(IntPtr value, IntPtr junk); - - [DllImport(Runtime.dll, CallingConvention = CallingConvention.Cdecl, - ExactSpelling = true, CharSet = CharSet.Ansi)] - public unsafe static extern double - PyFloat_AsDouble(IntPtr ob); - - - //==================================================================== - // Python sequence API - //==================================================================== - - [DllImport(Runtime.dll, CallingConvention = CallingConvention.Cdecl, - ExactSpelling = true, CharSet = CharSet.Ansi)] - public unsafe static extern bool - PySequence_Check(IntPtr pointer); - - [DllImport(Runtime.dll, CallingConvention = CallingConvention.Cdecl, - ExactSpelling = true, CharSet = CharSet.Ansi)] - public unsafe static extern IntPtr - PySequence_GetItem(IntPtr pointer, int index); - - [DllImport(Runtime.dll, CallingConvention = CallingConvention.Cdecl, - ExactSpelling = true, CharSet = CharSet.Ansi)] - public unsafe static extern int - PySequence_SetItem(IntPtr pointer, int index, IntPtr value); - - [DllImport(Runtime.dll, CallingConvention = CallingConvention.Cdecl, - ExactSpelling = true, CharSet = CharSet.Ansi)] - public unsafe static extern int - PySequence_DelItem(IntPtr pointer, int index); - - [DllImport(Runtime.dll, CallingConvention = CallingConvention.Cdecl, - ExactSpelling = true, CharSet = CharSet.Ansi)] - public unsafe static extern IntPtr - PySequence_GetSlice(IntPtr pointer, int i1, int i2); - - [DllImport(Runtime.dll, CallingConvention = CallingConvention.Cdecl, - ExactSpelling = true, CharSet = CharSet.Ansi)] - public unsafe static extern int - PySequence_SetSlice(IntPtr pointer, int i1, int i2, IntPtr v); - - [DllImport(Runtime.dll, CallingConvention = CallingConvention.Cdecl, - ExactSpelling = true, CharSet = CharSet.Ansi)] - public unsafe static extern int - PySequence_DelSlice(IntPtr pointer, int i1, int i2); - - [DllImport(Runtime.dll, CallingConvention = CallingConvention.Cdecl, - ExactSpelling = true, CharSet = CharSet.Ansi)] - public unsafe static extern int - PySequence_Size(IntPtr pointer); - - [DllImport(Runtime.dll, CallingConvention = CallingConvention.Cdecl, - ExactSpelling = true, CharSet = CharSet.Ansi)] - public unsafe static extern int - PySequence_Contains(IntPtr pointer, IntPtr item); - - [DllImport(Runtime.dll, CallingConvention = CallingConvention.Cdecl, - ExactSpelling = true, CharSet = CharSet.Ansi)] - public unsafe static extern IntPtr - PySequence_Concat(IntPtr pointer, IntPtr other); - - [DllImport(Runtime.dll, CallingConvention = CallingConvention.Cdecl, - ExactSpelling = true, CharSet = CharSet.Ansi)] - public unsafe static extern IntPtr - PySequence_Repeat(IntPtr pointer, int count); - - [DllImport(Runtime.dll, CallingConvention = CallingConvention.Cdecl, - ExactSpelling = true, CharSet = CharSet.Ansi)] - public unsafe static extern int - PySequence_Index(IntPtr pointer, IntPtr item); - - [DllImport(Runtime.dll, CallingConvention = CallingConvention.Cdecl, - ExactSpelling = true, CharSet = CharSet.Ansi)] - public unsafe static extern int - PySequence_Count(IntPtr pointer, IntPtr value); - - [DllImport(Runtime.dll, CallingConvention = CallingConvention.Cdecl, - ExactSpelling = true, CharSet = CharSet.Ansi)] - public unsafe static extern IntPtr - PySequence_Tuple(IntPtr pointer); - - [DllImport(Runtime.dll, CallingConvention = CallingConvention.Cdecl, - ExactSpelling = true, CharSet = CharSet.Ansi)] - public unsafe static extern IntPtr - PySequence_List(IntPtr pointer); - - - //==================================================================== - // Python string API - //==================================================================== - - public static bool IsStringType(IntPtr op) { - IntPtr t = PyObject_TYPE(op); - return (t == PyStringType) || (t == PyUnicodeType); - } - - public static bool PyString_Check(IntPtr ob) { - return PyObject_TYPE(ob) == Runtime.PyStringType; - } - - public static IntPtr PyString_FromString(string value) { - return PyString_FromStringAndSize(value, value.Length); - } - - [DllImport(Runtime.dll, CallingConvention = CallingConvention.Cdecl, - ExactSpelling = true, CharSet = CharSet.Ansi)] - public unsafe static extern IntPtr - PyString_FromStringAndSize(string value, int size); - - [DllImport(Runtime.dll, CallingConvention = CallingConvention.Cdecl, - EntryPoint = "PyString_AsString", - ExactSpelling = true, CharSet = CharSet.Ansi)] - public unsafe static extern IntPtr - PyString_AS_STRING(IntPtr op); - - [DllImport(Runtime.dll, CallingConvention = CallingConvention.Cdecl, - ExactSpelling = true, CharSet = CharSet.Ansi)] - public unsafe static extern int - PyString_Size(IntPtr pointer); - - public static bool PyUnicode_Check(IntPtr ob) { - return PyObject_TYPE(ob) == Runtime.PyUnicodeType; - } - -#if (UCS2) - [DllImport(Runtime.dll, CallingConvention = CallingConvention.Cdecl, - EntryPoint = "PyUnicodeUCS2_FromObject", - ExactSpelling = true, CharSet = CharSet.Unicode)] - public unsafe static extern IntPtr - PyUnicode_FromObject(IntPtr ob); - - [DllImport(Runtime.dll, CallingConvention = CallingConvention.Cdecl, - EntryPoint = "PyUnicodeUCS2_FromEncodedObject", - ExactSpelling = true, CharSet = CharSet.Unicode)] - public unsafe static extern IntPtr - PyUnicode_FromEncodedObject(IntPtr ob, IntPtr enc, IntPtr err); - - [DllImport(Runtime.dll, CallingConvention = CallingConvention.Cdecl, - EntryPoint = "PyUnicodeUCS2_FromUnicode", - ExactSpelling = true, CharSet = CharSet.Unicode)] - public unsafe static extern IntPtr - PyUnicode_FromUnicode(string s, int size); - - [DllImport(Runtime.dll, CallingConvention = CallingConvention.Cdecl, - EntryPoint = "PyUnicodeUCS2_GetSize", - ExactSpelling = true, CharSet = CharSet.Ansi)] - public unsafe static extern int - PyUnicode_GetSize(IntPtr ob); - - [CLSCompliant(false)] - [DllImport(Runtime.dll, CallingConvention = CallingConvention.Cdecl, - EntryPoint = "PyUnicodeUCS2_AsUnicode", - ExactSpelling = true)] - public unsafe static extern char* - PyUnicode_AsUnicode(IntPtr ob); - - [DllImport(Runtime.dll, CallingConvention = CallingConvention.Cdecl, - EntryPoint = "PyUnicodeUCS2_AsUnicode", - ExactSpelling = true, CharSet = CharSet.Unicode)] - public unsafe static extern IntPtr - PyUnicode_AS_UNICODE(IntPtr op); - - [DllImport(Runtime.dll, CallingConvention = CallingConvention.Cdecl, - EntryPoint = "PyUnicodeUCS2_FromOrdinal", - ExactSpelling = true, CharSet = CharSet.Unicode)] - public unsafe static extern IntPtr - PyUnicode_FromOrdinal(int c); - - public static IntPtr PyUnicode_FromString(string s) { - return PyUnicode_FromUnicode(s, (s.Length)); - } - - public unsafe static string GetManagedString(IntPtr op) { - IntPtr type = PyObject_TYPE(op); - - if (type == Runtime.PyStringType) { - return Marshal.PtrToStringAnsi( - PyString_AS_STRING(op), - Runtime.PyString_Size(op) - ); - } - - if (type == Runtime.PyUnicodeType) { - char* p = Runtime.PyUnicode_AsUnicode(op); - int size = Runtime.PyUnicode_GetSize(op); - return new String(p, 0, size); - } - - return null; - } - -#endif -#if (UCS4) - [DllImport(Runtime.dll, CallingConvention = CallingConvention.Cdecl, - EntryPoint = "PyUnicodeUCS4_FromObject", - ExactSpelling = true, CharSet = CharSet.Unicode)] - public unsafe static extern IntPtr - PyUnicode_FromObject(IntPtr ob); - - [DllImport(Runtime.dll, CallingConvention = CallingConvention.Cdecl, - EntryPoint = "PyUnicodeUCS4_FromEncodedObject", - ExactSpelling = true, CharSet = CharSet.Unicode)] - public unsafe static extern IntPtr - PyUnicode_FromEncodedObject(IntPtr ob, IntPtr enc, IntPtr err); - - [DllImport(Runtime.dll, CallingConvention = CallingConvention.Cdecl, - EntryPoint = "PyUnicodeUCS4_FromUnicode", - ExactSpelling = true)] - public unsafe static extern IntPtr - PyUnicode_FromUnicode( - [MarshalAs (UnmanagedType.CustomMarshaler, - MarshalTypeRef=typeof(Utf32Marshaler))] - string s, int size); - - [DllImport(Runtime.dll, CallingConvention = CallingConvention.Cdecl, - EntryPoint = "PyUnicodeUCS4_GetSize", - ExactSpelling = true, CharSet = CharSet.Ansi)] - public unsafe static extern int - PyUnicode_GetSize(IntPtr ob); - - [DllImport(Runtime.dll, CallingConvention = CallingConvention.Cdecl, - EntryPoint = "PyUnicodeUCS4_AsUnicode", - ExactSpelling = true)] - public unsafe static extern IntPtr - PyUnicode_AsUnicode(IntPtr ob); - - [DllImport(Runtime.dll, CallingConvention = CallingConvention.Cdecl, - EntryPoint = "PyUnicodeUCS4_AsUnicode", - ExactSpelling = true, CharSet = CharSet.Unicode)] - public unsafe static extern IntPtr - PyUnicode_AS_UNICODE(IntPtr op); - - [DllImport(Runtime.dll, CallingConvention = CallingConvention.Cdecl, - EntryPoint = "PyUnicodeUCS4_FromOrdinal", - ExactSpelling = true, CharSet = CharSet.Unicode)] - public unsafe static extern IntPtr - PyUnicode_FromOrdinal(int c); - - public static IntPtr PyUnicode_FromString(string s) - { - return PyUnicode_FromUnicode(s, (s.Length)); - } - - public unsafe static string GetManagedString(IntPtr op) - { - IntPtr type = PyObject_TYPE(op); - - if (type == Runtime.PyStringType) - { - return Marshal.PtrToStringAnsi( - PyString_AS_STRING(op), - Runtime.PyString_Size(op) - ); - } - - if (type == Runtime.PyUnicodeType) - { - IntPtr p = Runtime.PyUnicode_AsUnicode(op); - return UnixMarshal.PtrToString(p, Encoding.UTF32); - } - - return null; - } -#endif - - //==================================================================== - // Python dictionary API - //==================================================================== - - public static bool PyDict_Check(IntPtr ob) { - return PyObject_TYPE(ob) == Runtime.PyDictType; - } - - [DllImport(Runtime.dll, CallingConvention = CallingConvention.Cdecl, - ExactSpelling = true, CharSet = CharSet.Ansi)] - public unsafe static extern IntPtr - PyDict_New(); - - [DllImport(Runtime.dll, CallingConvention = CallingConvention.Cdecl, - ExactSpelling = true, CharSet = CharSet.Ansi)] - public unsafe static extern IntPtr - PyDictProxy_New(IntPtr dict); - - [DllImport(Runtime.dll, CallingConvention = CallingConvention.Cdecl, - ExactSpelling = true, CharSet = CharSet.Ansi)] - public unsafe static extern IntPtr - PyDict_GetItem(IntPtr pointer, IntPtr key); - - [DllImport(Runtime.dll, CallingConvention = CallingConvention.Cdecl, - ExactSpelling = true, CharSet = CharSet.Ansi)] - public unsafe static extern IntPtr - PyDict_GetItemString(IntPtr pointer, string key); - - [DllImport(Runtime.dll, CallingConvention = CallingConvention.Cdecl, - ExactSpelling = true, CharSet = CharSet.Ansi)] - public unsafe static extern int - PyDict_SetItem(IntPtr pointer, IntPtr key, IntPtr value); - - [DllImport(Runtime.dll, CallingConvention = CallingConvention.Cdecl, - ExactSpelling = true, CharSet = CharSet.Ansi)] - public unsafe static extern int - PyDict_SetItemString(IntPtr pointer, string key, IntPtr value); - - [DllImport(Runtime.dll, CallingConvention = CallingConvention.Cdecl, - ExactSpelling = true, CharSet = CharSet.Ansi)] - public unsafe static extern int - PyDict_DelItem(IntPtr pointer, IntPtr key); - - [DllImport(Runtime.dll, CallingConvention = CallingConvention.Cdecl, - ExactSpelling = true, CharSet = CharSet.Ansi)] - public unsafe static extern int - PyMapping_HasKey(IntPtr pointer, IntPtr key); - - [DllImport(Runtime.dll, CallingConvention = CallingConvention.Cdecl, - ExactSpelling = true, CharSet = CharSet.Ansi)] - public unsafe static extern IntPtr - PyDict_Keys(IntPtr pointer); - - [DllImport(Runtime.dll, CallingConvention = CallingConvention.Cdecl, - ExactSpelling = true, CharSet = CharSet.Ansi)] - public unsafe static extern IntPtr - PyDict_Values(IntPtr pointer); - - [DllImport(Runtime.dll, CallingConvention = CallingConvention.Cdecl, - ExactSpelling = true, CharSet = CharSet.Ansi)] - public unsafe static extern IntPtr - PyDict_Items(IntPtr pointer); - - [DllImport(Runtime.dll, CallingConvention = CallingConvention.Cdecl, - ExactSpelling = true, CharSet = CharSet.Ansi)] - public unsafe static extern IntPtr - PyDict_Copy(IntPtr pointer); - - [DllImport(Runtime.dll, CallingConvention = CallingConvention.Cdecl, - ExactSpelling = true, CharSet = CharSet.Ansi)] - public unsafe static extern int - PyDict_Update(IntPtr pointer, IntPtr other); - - [DllImport(Runtime.dll, CallingConvention = CallingConvention.Cdecl, - ExactSpelling = true, CharSet = CharSet.Ansi)] - public unsafe static extern void - PyDict_Clear(IntPtr pointer); - - [DllImport(Runtime.dll, CallingConvention = CallingConvention.Cdecl, - ExactSpelling = true, CharSet = CharSet.Ansi)] - public unsafe static extern int - PyDict_Size(IntPtr pointer); - - - //==================================================================== - // Python list API - //==================================================================== - - public static bool PyList_Check(IntPtr ob) { - return PyObject_TYPE(ob) == Runtime.PyListType; - } - - [DllImport(Runtime.dll, CallingConvention = CallingConvention.Cdecl, - ExactSpelling = true, CharSet = CharSet.Ansi)] - public unsafe static extern IntPtr - PyList_New(int size); - - [DllImport(Runtime.dll, CallingConvention = CallingConvention.Cdecl, - ExactSpelling = true, CharSet = CharSet.Ansi)] - public unsafe static extern IntPtr - PyList_AsTuple(IntPtr pointer); - - [DllImport(Runtime.dll, CallingConvention = CallingConvention.Cdecl, - ExactSpelling = true, CharSet = CharSet.Ansi)] - public unsafe static extern IntPtr - PyList_GetItem(IntPtr pointer, int index); - - [DllImport(Runtime.dll, CallingConvention = CallingConvention.Cdecl, - ExactSpelling = true, CharSet = CharSet.Ansi)] - public unsafe static extern int - PyList_SetItem(IntPtr pointer, int index, IntPtr value); - - [DllImport(Runtime.dll, CallingConvention = CallingConvention.Cdecl, - ExactSpelling = true, CharSet = CharSet.Ansi)] - public unsafe static extern int - PyList_Insert(IntPtr pointer, int index, IntPtr value); - - [DllImport(Runtime.dll, CallingConvention = CallingConvention.Cdecl, - ExactSpelling = true, CharSet = CharSet.Ansi)] - public unsafe static extern int - PyList_Append(IntPtr pointer, IntPtr value); - - [DllImport(Runtime.dll, CallingConvention = CallingConvention.Cdecl, - ExactSpelling = true, CharSet = CharSet.Ansi)] - public unsafe static extern int - PyList_Reverse(IntPtr pointer); - - [DllImport(Runtime.dll, CallingConvention = CallingConvention.Cdecl, - ExactSpelling = true, CharSet = CharSet.Ansi)] - public unsafe static extern int - PyList_Sort(IntPtr pointer); - - [DllImport(Runtime.dll, CallingConvention = CallingConvention.Cdecl, - ExactSpelling = true, CharSet = CharSet.Ansi)] - public unsafe static extern IntPtr - PyList_GetSlice(IntPtr pointer, int start, int end); - - [DllImport(Runtime.dll, CallingConvention = CallingConvention.Cdecl, - ExactSpelling = true, CharSet = CharSet.Ansi)] - public unsafe static extern int - PyList_SetSlice(IntPtr pointer, int start, int end, IntPtr value); - - [DllImport(Runtime.dll, CallingConvention = CallingConvention.Cdecl, - ExactSpelling = true, CharSet = CharSet.Ansi)] - public unsafe static extern int - PyList_Size(IntPtr pointer); - - - //==================================================================== - // Python tuple API - //==================================================================== - - public static bool PyTuple_Check(IntPtr ob) { - return PyObject_TYPE(ob) == Runtime.PyTupleType; - } - - [DllImport(Runtime.dll, CallingConvention = CallingConvention.Cdecl, - ExactSpelling = true, CharSet = CharSet.Ansi)] - public unsafe static extern IntPtr - PyTuple_New(int size); - - [DllImport(Runtime.dll, CallingConvention = CallingConvention.Cdecl, - ExactSpelling = true, CharSet = CharSet.Ansi)] - public unsafe static extern IntPtr - PyTuple_GetItem(IntPtr pointer, int index); - - [DllImport(Runtime.dll, CallingConvention = CallingConvention.Cdecl, - ExactSpelling = true, CharSet = CharSet.Ansi)] - public unsafe static extern int - PyTuple_SetItem(IntPtr pointer, int index, IntPtr value); - - [DllImport(Runtime.dll, CallingConvention = CallingConvention.Cdecl, - ExactSpelling = true, CharSet = CharSet.Ansi)] - public unsafe static extern IntPtr - PyTuple_GetSlice(IntPtr pointer, int start, int end); - - [DllImport(Runtime.dll, CallingConvention = CallingConvention.Cdecl, - ExactSpelling = true, CharSet = CharSet.Ansi)] - public unsafe static extern int - PyTuple_Size(IntPtr pointer); - - - //==================================================================== - // Python iterator API - //==================================================================== - - [DllImport(Runtime.dll, CallingConvention = CallingConvention.Cdecl, - ExactSpelling = true, CharSet = CharSet.Ansi)] - public unsafe static extern bool - PyIter_Check(IntPtr pointer); - - [DllImport(Runtime.dll, CallingConvention = CallingConvention.Cdecl, - ExactSpelling = true, CharSet = CharSet.Ansi)] - public unsafe static extern IntPtr - PyIter_Next(IntPtr pointer); - - //==================================================================== - // Python module API - //==================================================================== - - [DllImport(Runtime.dll, CallingConvention = CallingConvention.Cdecl, - ExactSpelling = true, CharSet = CharSet.Ansi)] - public unsafe static extern string - PyModule_GetName(IntPtr module); - - [DllImport(Runtime.dll, CallingConvention = CallingConvention.Cdecl, - ExactSpelling = true, CharSet = CharSet.Ansi)] - public unsafe static extern IntPtr - PyModule_GetDict(IntPtr module); - - [DllImport(Runtime.dll, CallingConvention = CallingConvention.Cdecl, - ExactSpelling = true, CharSet = CharSet.Ansi)] - public unsafe static extern string - PyModule_GetFilename(IntPtr module); - - [DllImport(Runtime.dll, CallingConvention = CallingConvention.Cdecl, - ExactSpelling = true, CharSet = CharSet.Ansi)] - public unsafe static extern IntPtr - PyImport_Import(IntPtr name); - - [DllImport(Runtime.dll, CallingConvention = CallingConvention.Cdecl, - ExactSpelling = true, CharSet = CharSet.Ansi)] - public unsafe static extern IntPtr - PyImport_ImportModule(string name); - - [DllImport(Runtime.dll, CallingConvention = CallingConvention.Cdecl, - ExactSpelling = true, CharSet = CharSet.Ansi)] - public unsafe static extern IntPtr - PyImport_ReloadModule(IntPtr module); - - [DllImport(Runtime.dll, CallingConvention = CallingConvention.Cdecl, - ExactSpelling = true, CharSet = CharSet.Ansi)] - public unsafe static extern IntPtr - PyImport_AddModule(string name); - - [DllImport(Runtime.dll, CallingConvention = CallingConvention.Cdecl, - ExactSpelling = true, CharSet = CharSet.Ansi)] - public unsafe static extern IntPtr - PyImport_GetModuleDict(); - - - [DllImport(Runtime.dll, CallingConvention = CallingConvention.Cdecl, - ExactSpelling = true, CharSet = CharSet.Ansi)] - public unsafe static extern void - PySys_SetArgv(int argc, IntPtr argv); - - [DllImport(Runtime.dll, CallingConvention = CallingConvention.Cdecl, - ExactSpelling = true, CharSet = CharSet.Ansi)] - public unsafe static extern IntPtr - PySys_GetObject(string name); - - [DllImport(Runtime.dll, CallingConvention = CallingConvention.Cdecl, - ExactSpelling = true, CharSet = CharSet.Ansi)] - public unsafe static extern int - PySys_SetObject(string name, IntPtr ob); - - - //==================================================================== - // Python type object API - //==================================================================== - - public static bool PyType_Check(IntPtr ob) { - return PyObject_TypeCheck(ob, Runtime.PyTypeType); - } - - [DllImport(Runtime.dll, CallingConvention = CallingConvention.Cdecl, - ExactSpelling = true, CharSet = CharSet.Ansi)] - public unsafe static extern bool - PyType_IsSubtype(IntPtr t1, IntPtr t2); - - public static bool PyObject_TypeCheck(IntPtr ob, IntPtr tp) { - IntPtr t = PyObject_TYPE(ob); - return (t == tp) || PyType_IsSubtype(t, tp); - } - - [DllImport(Runtime.dll, CallingConvention = CallingConvention.Cdecl, - ExactSpelling = true, CharSet = CharSet.Ansi)] - public unsafe static extern IntPtr - PyType_GenericNew(IntPtr type, IntPtr args, IntPtr kw); - - [DllImport(Runtime.dll, CallingConvention = CallingConvention.Cdecl, - ExactSpelling = true, CharSet = CharSet.Ansi)] - public unsafe static extern IntPtr - PyType_GenericAlloc(IntPtr type, int n); - - [DllImport(Runtime.dll, CallingConvention = CallingConvention.Cdecl, - ExactSpelling = true, CharSet = CharSet.Ansi)] - public unsafe static extern int - PyType_Ready(IntPtr type); - - [CLSCompliant(false)] - [DllImport(Runtime.dll, CallingConvention = CallingConvention.Cdecl, - ExactSpelling = true, CharSet = CharSet.Ansi)] - public unsafe static extern IntPtr - _PyType_Lookup(IntPtr type, IntPtr name); - - [DllImport(Runtime.dll, CallingConvention = CallingConvention.Cdecl, - ExactSpelling = true, CharSet = CharSet.Ansi)] - public unsafe static extern IntPtr - PyObject_GenericGetAttr(IntPtr obj, IntPtr name); - - [DllImport(Runtime.dll, CallingConvention = CallingConvention.Cdecl, - ExactSpelling = true, CharSet = CharSet.Ansi)] - public unsafe static extern int - PyObject_GenericSetAttr(IntPtr obj, IntPtr name, IntPtr value); - - [CLSCompliant(false)] - [DllImport(Runtime.dll, CallingConvention = CallingConvention.Cdecl, - ExactSpelling = true, CharSet = CharSet.Ansi)] - public unsafe static extern IntPtr - _PyObject_GetDictPtr(IntPtr obj); - - [DllImport(Runtime.dll, CallingConvention = CallingConvention.Cdecl, - ExactSpelling = true, CharSet = CharSet.Ansi)] - public unsafe static extern IntPtr - PyObject_GC_New(IntPtr tp); - - [DllImport(Runtime.dll, CallingConvention = CallingConvention.Cdecl, - ExactSpelling = true, CharSet = CharSet.Ansi)] - public unsafe static extern void - PyObject_GC_Del(IntPtr tp); - - [DllImport(Runtime.dll, CallingConvention = CallingConvention.Cdecl, - ExactSpelling = true, CharSet = CharSet.Ansi)] - public unsafe static extern void - PyObject_GC_Track(IntPtr tp); - - [DllImport(Runtime.dll, CallingConvention = CallingConvention.Cdecl, - ExactSpelling = true, CharSet = CharSet.Ansi)] - public unsafe static extern void - PyObject_GC_UnTrack(IntPtr tp); - - - //==================================================================== - // Python memory API - //==================================================================== - - [DllImport(Runtime.dll, CallingConvention = CallingConvention.Cdecl, - ExactSpelling = true, CharSet = CharSet.Ansi)] - public unsafe static extern IntPtr - PyMem_Malloc(int size); - - [DllImport(Runtime.dll, CallingConvention = CallingConvention.Cdecl, - ExactSpelling = true, CharSet = CharSet.Ansi)] - public unsafe static extern IntPtr - PyMem_Realloc(IntPtr ptr, int size); - - [DllImport(Runtime.dll, CallingConvention = CallingConvention.Cdecl, - ExactSpelling = true, CharSet = CharSet.Ansi)] - public unsafe static extern void - PyMem_Free(IntPtr ptr); - - - //==================================================================== - // Python exception API - //==================================================================== - - [DllImport(Runtime.dll, CallingConvention = CallingConvention.Cdecl, - ExactSpelling = true, CharSet = CharSet.Ansi)] - public unsafe static extern void - PyErr_SetString(IntPtr ob, string message); - - [DllImport(Runtime.dll, CallingConvention = CallingConvention.Cdecl, - ExactSpelling = true, CharSet = CharSet.Ansi)] - public unsafe static extern void - PyErr_SetObject(IntPtr ob, IntPtr message); - - [DllImport(Runtime.dll, CallingConvention = CallingConvention.Cdecl, - ExactSpelling = true, CharSet = CharSet.Ansi)] - public unsafe static extern IntPtr - PyErr_SetFromErrno(IntPtr ob); - - [DllImport(Runtime.dll, CallingConvention = CallingConvention.Cdecl, - ExactSpelling = true, CharSet = CharSet.Ansi)] - public unsafe static extern void - PyErr_SetNone(IntPtr ob); - - [DllImport(Runtime.dll, CallingConvention = CallingConvention.Cdecl, - ExactSpelling = true, CharSet = CharSet.Ansi)] - public unsafe static extern int - PyErr_ExceptionMatches(IntPtr exception); - - [DllImport(Runtime.dll, CallingConvention = CallingConvention.Cdecl, - ExactSpelling = true, CharSet = CharSet.Ansi)] - public unsafe static extern int - PyErr_GivenExceptionMatches(IntPtr ob, IntPtr val); - - [DllImport(Runtime.dll, CallingConvention = CallingConvention.Cdecl, - ExactSpelling = true, CharSet = CharSet.Ansi)] - public unsafe static extern void - PyErr_NormalizeException(IntPtr ob, IntPtr val, IntPtr tb); - - [DllImport(Runtime.dll, CallingConvention = CallingConvention.Cdecl, - ExactSpelling = true, CharSet = CharSet.Ansi)] - public unsafe static extern int - PyErr_Occurred(); - - [DllImport(Runtime.dll, CallingConvention = CallingConvention.Cdecl, - ExactSpelling = true, CharSet = CharSet.Ansi)] - public unsafe static extern void - PyErr_Fetch(ref IntPtr ob, ref IntPtr val, ref IntPtr tb); - - [DllImport(Runtime.dll, CallingConvention = CallingConvention.Cdecl, - ExactSpelling = true, CharSet = CharSet.Ansi)] - public unsafe static extern void - PyErr_Restore(IntPtr ob, IntPtr val, IntPtr tb); - - [DllImport(Runtime.dll, CallingConvention = CallingConvention.Cdecl, - ExactSpelling = true, CharSet = CharSet.Ansi)] - public unsafe static extern void - PyErr_Clear(); - - [DllImport(Runtime.dll, CallingConvention = CallingConvention.Cdecl, - ExactSpelling = true, CharSet = CharSet.Ansi)] - public unsafe static extern void - PyErr_Print(); - - - //==================================================================== - // Miscellaneous - //==================================================================== - - [DllImport(Runtime.dll, CallingConvention = CallingConvention.Cdecl, - ExactSpelling = true, CharSet = CharSet.Ansi)] - public unsafe static extern IntPtr - PyMethod_Self(IntPtr ob); - - [DllImport(Runtime.dll, CallingConvention = CallingConvention.Cdecl, - ExactSpelling = true, CharSet = CharSet.Ansi)] - public unsafe static extern IntPtr - PyMethod_Function(IntPtr ob); - - } - - -} diff --git a/Pythonnet.Runtime/typemanager.cs b/Pythonnet.Runtime/typemanager.cs deleted file mode 100644 index 41b845737c..0000000000 --- a/Pythonnet.Runtime/typemanager.cs +++ /dev/null @@ -1,452 +0,0 @@ -// ========================================================================== -// This software is subject to the provisions of the Zope Public License, -// Version 2.0 (ZPL). A copy of the ZPL should accompany this distribution. -// THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED -// WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -// WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS -// FOR A PARTICULAR PURPOSE. -// ========================================================================== - -using System; -using System.Runtime.InteropServices; -using System.Reflection.Emit; -using System.Collections.Generic; -using System.Collections; -using System.Reflection; -using System.Threading; - -namespace Python.Runtime { - - //======================================================================= - // The TypeManager class is responsible for building binary-compatible - // Python type objects that are implemented in managed code. - //======================================================================= - - internal class TypeManager { - - static BindingFlags tbFlags; - static Dictionary cache; - static int obSize; - - static TypeManager() { - tbFlags = BindingFlags.Public | BindingFlags.Static; - obSize = 5 * IntPtr.Size; - cache = new Dictionary(128); - } - - - //==================================================================== - // Given a managed Type derived from ExtensionType, get the handle to - // a Python type object that delegates its implementation to the Type - // object. These Python type instances are used to implement internal - // descriptor and utility types like ModuleObject, PropertyObject, etc. - //==================================================================== - - internal static IntPtr GetTypeHandle(Type type) { - // Note that these types are cached with a refcount of 1, so they - // effectively exist until the CPython runtime is finalized. - IntPtr handle = IntPtr.Zero; - cache.TryGetValue(type, out handle); - if (handle != IntPtr.Zero) { - return handle; - } - handle = CreateType(type); - cache[type] = handle; - return handle; - } - - - //==================================================================== - // Get the handle of a Python type that reflects the given CLR type. - // The given ManagedType instance is a managed object that implements - // the appropriate semantics in Python for the reflected managed type. - //==================================================================== - - internal static IntPtr GetTypeHandle(ManagedType obj, Type type) { - IntPtr handle = IntPtr.Zero; - cache.TryGetValue(type, out handle); - if (handle != IntPtr.Zero) { - return handle; - } - handle = CreateType(obj, type); - cache[type] = handle; - return handle; - } - - - //==================================================================== - // The following CreateType implementations do the necessary work to - // create Python types to represent managed extension types, reflected - // types, subclasses of reflected types and the managed metatype. The - // dance is slightly different for each kind of type due to different - // behavior needed and the desire to have the existing Python runtime - // do as much of the allocation and initialization work as possible. - //==================================================================== - - internal static IntPtr CreateType(Type impl) { - - IntPtr type = AllocateTypeObject(impl.Name); - - // Set tp_basicsize to the size of our managed instance objects. - Marshal.WriteIntPtr(type, TypeOffset.tp_basicsize, (IntPtr)obSize); - - IntPtr offset = (IntPtr)ObjectOffset.ob_dict; - Marshal.WriteIntPtr(type, TypeOffset.tp_dictoffset, offset); - - InitializeSlots(type, impl); - - int flags = TypeFlags.Default | TypeFlags.Managed | - TypeFlags.HeapType | TypeFlags.HaveGC; - Marshal.WriteIntPtr(type, TypeOffset.tp_flags, (IntPtr)flags); - - Runtime.PyType_Ready(type); - - IntPtr dict = Marshal.ReadIntPtr(type, TypeOffset.tp_dict); - IntPtr mod = Runtime.PyString_FromString("CLR"); - Runtime.PyDict_SetItemString(dict, "__module__", mod); - - InitMethods(type, impl); - - return type; - } - - - internal static IntPtr CreateType(ManagedType impl, Type clrType) { - // Cleanup the type name to get rid of funny nested type names. - string name = "CLR." + clrType.FullName; - int i = name.LastIndexOf('+'); - if (i > -1) { - name = name.Substring(i + 1); - } - i = name.LastIndexOf('.'); - if (i > -1) { - name = name.Substring(i + 1); - } - - IntPtr base_ = IntPtr.Zero; - // XXX Hack, use a different base class for System.Exception - // Python 2.5+ allows new style class exceptions but they *must* - // subclass BaseException (or better Exception). -#if (PYTHON25 || PYTHON26 || PYTHON27) - if (clrType == typeof(System.Exception)) { - base_ = Exceptions.Exception; - Runtime.Incref(base_); - } else -#endif - if (clrType.BaseType != null) { - ClassBase bc = ClassManager.GetClass(clrType.BaseType); - base_ = bc.pyHandle; - } - - IntPtr type = AllocateTypeObject(name); - - Marshal.WriteIntPtr(type,TypeOffset.ob_type,Runtime.PyCLRMetaType); - Runtime.Incref(Runtime.PyCLRMetaType); - - Marshal.WriteIntPtr(type, TypeOffset.tp_basicsize, (IntPtr)obSize); - Marshal.WriteIntPtr(type, TypeOffset.tp_itemsize, IntPtr.Zero); - - IntPtr offset = (IntPtr)ObjectOffset.ob_dict; - Marshal.WriteIntPtr(type, TypeOffset.tp_dictoffset, offset); - - InitializeSlots(type, impl.GetType()); - - if (base_ != IntPtr.Zero) { - Marshal.WriteIntPtr(type, TypeOffset.tp_base, base_); - Runtime.Incref(base_); - } - - int flags = TypeFlags.Default; - flags |= TypeFlags.Managed; - flags |= TypeFlags.HeapType; - flags |= TypeFlags.BaseType; - flags |= TypeFlags.HaveGC; - Marshal.WriteIntPtr(type, TypeOffset.tp_flags, (IntPtr)flags); - - // Leverage followup initialization from the Python runtime. Note - // that the type of the new type must PyType_Type at the time we - // call this, else PyType_Ready will skip some slot initialization. - - Runtime.PyType_Ready(type); - - IntPtr dict = Marshal.ReadIntPtr(type, TypeOffset.tp_dict); - string mn = clrType.Namespace != null ? clrType.Namespace : ""; - IntPtr mod = Runtime.PyString_FromString(mn); - Runtime.PyDict_SetItemString(dict, "__module__", mod); - - // Hide the gchandle of the implementation in a magic type slot. - GCHandle gc = GCHandle.Alloc(impl); - Marshal.WriteIntPtr(type, TypeOffset.magic(), (IntPtr)gc); - - // Set the handle attributes on the implementing instance. - impl.tpHandle = Runtime.PyCLRMetaType; - impl.gcHandle = gc; - impl.pyHandle = type; - - //DebugUtil.DumpType(type); - - return type; - } - - internal static IntPtr CreateSubType(IntPtr args) { - - IntPtr py_name = Runtime.PyTuple_GetItem(args, 0); - IntPtr bases = Runtime.PyTuple_GetItem(args, 1); - IntPtr dict = Runtime.PyTuple_GetItem(args, 2); - IntPtr base_ = Runtime.PyTuple_GetItem(bases, 0); - - string name = Runtime.GetManagedString(py_name); - IntPtr type = AllocateTypeObject(name); - - Marshal.WriteIntPtr(type,TypeOffset.ob_type,Runtime.PyCLRMetaType); - Runtime.Incref(Runtime.PyCLRMetaType); - - Marshal.WriteIntPtr(type, TypeOffset.tp_basicsize, (IntPtr)obSize); - Marshal.WriteIntPtr(type, TypeOffset.tp_itemsize, IntPtr.Zero); - - IntPtr offset = (IntPtr)ObjectOffset.ob_dict; - Marshal.WriteIntPtr(type, TypeOffset.tp_dictoffset, offset); - - IntPtr dc = Runtime.PyDict_Copy(dict); - Marshal.WriteIntPtr(type, TypeOffset.tp_dict, dc); - - Marshal.WriteIntPtr(type, TypeOffset.tp_base, base_); - Runtime.Incref(base_); - - int flags = TypeFlags.Default; - flags |= TypeFlags.Managed; - flags |= TypeFlags.HeapType; - flags |= TypeFlags.BaseType; - flags |= TypeFlags.Subclass; - flags |= TypeFlags.HaveGC; - Marshal.WriteIntPtr(type, TypeOffset.tp_flags, (IntPtr)flags); - - CopySlot(base_, type, TypeOffset.tp_traverse); - CopySlot(base_, type, TypeOffset.tp_clear); - CopySlot(base_, type, TypeOffset.tp_is_gc); - - Runtime.PyType_Ready(type); - - - IntPtr tp_dict = Marshal.ReadIntPtr(type, TypeOffset.tp_dict); - IntPtr mod = Runtime.PyString_FromString("CLR"); - Runtime.PyDict_SetItemString(tp_dict, "__module__", mod); - - // for now, move up hidden handle... - IntPtr gc = Marshal.ReadIntPtr(base_, TypeOffset.magic()); - Marshal.WriteIntPtr(type, TypeOffset.magic(), gc); - - return type; - } - - - internal static IntPtr CreateMetaType(Type impl) { - - // The managed metatype is functionally little different than the - // standard Python metatype (PyType_Type). It overrides certain of - // the standard type slots, and has to subclass PyType_Type for - // certain functions in the C runtime to work correctly with it. - - IntPtr type = AllocateTypeObject("CLR Metatype"); - IntPtr py_type = Runtime.PyTypeType; - - Marshal.WriteIntPtr(type, TypeOffset.tp_base, py_type); - Runtime.Incref(py_type); - - // Copy gc and other type slots from the base Python metatype. - - CopySlot(py_type, type, TypeOffset.tp_basicsize); - CopySlot(py_type, type, TypeOffset.tp_itemsize); - - CopySlot(py_type, type, TypeOffset.tp_dictoffset); - CopySlot(py_type, type, TypeOffset.tp_weaklistoffset); - - CopySlot(py_type, type, TypeOffset.tp_traverse); - CopySlot(py_type, type, TypeOffset.tp_clear); - CopySlot(py_type, type, TypeOffset.tp_is_gc); - - // Override type slots with those of the managed implementation. - - InitializeSlots(type, impl); - - int flags = TypeFlags.Default; - flags |= TypeFlags.Managed; - flags |= TypeFlags.HeapType; - flags |= TypeFlags.HaveGC; - Marshal.WriteIntPtr(type, TypeOffset.tp_flags, (IntPtr)flags); - - Runtime.PyType_Ready(type); - - IntPtr dict = Marshal.ReadIntPtr(type, TypeOffset.tp_dict); - IntPtr mod = Runtime.PyString_FromString("CLR"); - Runtime.PyDict_SetItemString(dict, "__module__", mod); - - //DebugUtil.DumpType(type); - - return type; - } - - - internal static IntPtr BasicSubType(string name, IntPtr base_, - Type impl) { - - // Utility to create a subtype of a std Python type, but with - // a managed type able to override implementation - - IntPtr type = AllocateTypeObject(name); - //Marshal.WriteIntPtr(type, TypeOffset.tp_basicsize, (IntPtr)obSize); - //Marshal.WriteIntPtr(type, TypeOffset.tp_itemsize, IntPtr.Zero); - - //IntPtr offset = (IntPtr)ObjectOffset.ob_dict; - //Marshal.WriteIntPtr(type, TypeOffset.tp_dictoffset, offset); - - //IntPtr dc = Runtime.PyDict_Copy(dict); - //Marshal.WriteIntPtr(type, TypeOffset.tp_dict, dc); - - Marshal.WriteIntPtr(type, TypeOffset.tp_base, base_); - Runtime.Incref(base_); - - int flags = TypeFlags.Default; - flags |= TypeFlags.Managed; - flags |= TypeFlags.HeapType; - flags |= TypeFlags.HaveGC; - Marshal.WriteIntPtr(type, TypeOffset.tp_flags, (IntPtr)flags); - - CopySlot(base_, type, TypeOffset.tp_traverse); - CopySlot(base_, type, TypeOffset.tp_clear); - CopySlot(base_, type, TypeOffset.tp_is_gc); - - InitializeSlots(type, impl); - - Runtime.PyType_Ready(type); - - IntPtr tp_dict = Marshal.ReadIntPtr(type, TypeOffset.tp_dict); - IntPtr mod = Runtime.PyString_FromString("CLR"); - Runtime.PyDict_SetItemString(tp_dict, "__module__", mod); - - return type; - } - - - //==================================================================== - // Utility method to allocate a type object & do basic initialization. - //==================================================================== - - internal static IntPtr AllocateTypeObject(string name) { - IntPtr type = Runtime.PyType_GenericAlloc(Runtime.PyTypeType, 0); - - // Cheat a little: we'll set tp_name to the internal char * of - // the Python version of the type name - otherwise we'd have to - // allocate the tp_name and would have no way to free it. - - IntPtr temp = Runtime.PyString_FromString(name); - IntPtr raw = Runtime.PyString_AS_STRING(temp); - Marshal.WriteIntPtr(type, TypeOffset.tp_name, raw); - Marshal.WriteIntPtr(type, TypeOffset.name, temp); - - long ptr = type.ToInt64(); // 64-bit safe - - temp = new IntPtr(ptr + TypeOffset.nb_add); - Marshal.WriteIntPtr(type, TypeOffset.tp_as_number, temp); - - temp = new IntPtr(ptr + TypeOffset.sq_length); - Marshal.WriteIntPtr(type, TypeOffset.tp_as_sequence, temp); - - temp = new IntPtr(ptr + TypeOffset.mp_length); - Marshal.WriteIntPtr(type, TypeOffset.tp_as_mapping, temp); - - temp = new IntPtr(ptr + TypeOffset.bf_getreadbuffer); - Marshal.WriteIntPtr(type, TypeOffset.tp_as_buffer, temp); - - return type; - } - - - //==================================================================== - // Given a newly allocated Python type object and a managed Type that - // provides the implementation for the type, connect the type slots of - // the Python object to the managed methods of the implementing Type. - //==================================================================== - - internal static void InitializeSlots(IntPtr type, Type impl) { - Hashtable seen = new Hashtable(8); - Type offsetType = typeof(TypeOffset); - - while (impl != null) { - MethodInfo[] methods = impl.GetMethods(tbFlags); - for (int i = 0; i < methods.Length; i++) { - MethodInfo method = methods[i]; - string name = method.Name; - if (! (name.StartsWith("tp_") || - name.StartsWith("nb_") || - name.StartsWith("sq_") || - name.StartsWith("mp_") || - name.StartsWith("bf_") - ) ) { - continue; - } - - if (seen[name] != null) { - continue; - } - - FieldInfo fi = offsetType.GetField(name); - int offset = (int)fi.GetValue(offsetType); - - IntPtr slot = Interop.GetThunk(method); - Marshal.WriteIntPtr(type, offset, slot); - - seen[name] = 1; - } - - impl = impl.BaseType; - } - - } - - - //==================================================================== - // Given a newly allocated Python type object and a managed Type that - // implements it, initialize any methods defined by the Type that need - // to appear in the Python type __dict__ (based on custom attribute). - //==================================================================== - - private static void InitMethods(IntPtr pytype, Type type) { - IntPtr dict = Marshal.ReadIntPtr(pytype, TypeOffset.tp_dict); - Type marker = typeof(PythonMethodAttribute); - - BindingFlags flags = BindingFlags.Public | BindingFlags.Static; - - while (type != null) { - MethodInfo[] methods = type.GetMethods(flags); - for (int i = 0; i < methods.Length; i++) { - MethodInfo method = methods[i]; - object[] attrs = method.GetCustomAttributes(marker, false); - if (attrs.Length > 0) { - string method_name = method.Name; - MethodInfo[] mi = new MethodInfo[1]; - mi[0] = method; - MethodObject m = new TypeMethod(method_name, mi); - Runtime.PyDict_SetItemString(dict, method_name, - m.pyHandle); - } - } - type = type.BaseType; - } - } - - - //==================================================================== - // Utility method to copy slots from a given type to another type. - //==================================================================== - - internal static void CopySlot(IntPtr from, IntPtr to, int offset) { - IntPtr fp = Marshal.ReadIntPtr(from, offset); - Marshal.WriteIntPtr(to, offset, fp); - } - - - } - - -} diff --git a/Pythonnet.Runtime/typemethod.cs b/Pythonnet.Runtime/typemethod.cs deleted file mode 100644 index ab95f28ed0..0000000000 --- a/Pythonnet.Runtime/typemethod.cs +++ /dev/null @@ -1,54 +0,0 @@ -// ========================================================================== -// This software is subject to the provisions of the Zope Public License, -// Version 2.0 (ZPL). A copy of the ZPL should accompany this distribution. -// THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED -// WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -// WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS -// FOR A PARTICULAR PURPOSE. -// ========================================================================== - -using System; -using System.Collections; -using System.Reflection; - -namespace Python.Runtime { - - //======================================================================== - // Implements a Python type that provides access to CLR object methods. - //======================================================================== - - internal class TypeMethod : MethodObject { - - public TypeMethod(string name, MethodInfo[] info) : - base(name, info) {} - - public TypeMethod(string name, MethodInfo[] info, bool allow_threads) : - base(name, info, allow_threads) { } - - public override IntPtr Invoke(IntPtr ob, IntPtr args, IntPtr kw) { - MethodInfo mi = this.info[0]; - Object[] arglist = new Object[3]; - arglist[0] = ob; - arglist[1] = args; - arglist[2] = kw; - - try { - Object inst = null; - if (ob != IntPtr.Zero) { - inst = GetManagedObject(ob); - } - return (IntPtr)mi.Invoke(inst, BindingFlags.Default, null, arglist, - null); - } - catch (Exception e) { - Exceptions.SetError(e); - return IntPtr.Zero; - } - } - - - - } - - -} diff --git a/Pythonnet.Runtime/x64/clrmodule-platform.il b/Pythonnet.Runtime/x64/clrmodule-platform.il deleted file mode 100644 index d04f746038..0000000000 --- a/Pythonnet.Runtime/x64/clrmodule-platform.il +++ /dev/null @@ -1,11 +0,0 @@ -// ========================================================================== -// This software is subject to the provisions of the Zope Public License, -// Version 2.0 (ZPL). A copy of the ZPL should accompany this distribution. -// THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED -// WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -// WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS -// FOR A PARTICULAR PURPOSE. -// ========================================================================== - -.vtfixup [1] int64 fromunmanaged at VT_01 -.data VT_01 = int64(0) diff --git a/Pythonnet.Runtime/x86/clrmodule-platform.il b/Pythonnet.Runtime/x86/clrmodule-platform.il deleted file mode 100644 index aeac29658c..0000000000 --- a/Pythonnet.Runtime/x86/clrmodule-platform.il +++ /dev/null @@ -1,11 +0,0 @@ -// ========================================================================== -// This software is subject to the provisions of the Zope Public License, -// Version 2.0 (ZPL). A copy of the ZPL should accompany this distribution. -// THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED -// WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -// WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS -// FOR A PARTICULAR PURPOSE. -// ========================================================================== - -.vtfixup [1] int32 fromunmanaged at VT_01 -.data VT_01 = int32(0) diff --git a/Wox.sln b/Wox.sln index 1b7a9f6859..24814d1260 100644 --- a/Wox.sln +++ b/Wox.sln @@ -19,8 +19,6 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Wox.Plugin.PluginManagement EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Wox.Plugin.BrowserBookmark", "Plugins\Wox.Plugin.BrowserBookmark\Wox.Plugin.BrowserBookmark.csproj", "{9B130CC5-14FB-41FF-B310-0A95B6894C37}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Python.Runtime", "Pythonnet.Runtime\Python.Runtime.csproj", "{097B4AC0-74E9-4C58-BCF8-C69746EC8271}" -EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -55,10 +53,6 @@ Global {9B130CC5-14FB-41FF-B310-0A95B6894C37}.Debug|Any CPU.Build.0 = Debug|Any CPU {9B130CC5-14FB-41FF-B310-0A95B6894C37}.Release|Any CPU.ActiveCfg = Release|Any CPU {9B130CC5-14FB-41FF-B310-0A95B6894C37}.Release|Any CPU.Build.0 = Release|Any CPU - {097B4AC0-74E9-4C58-BCF8-C69746EC8271}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {097B4AC0-74E9-4C58-BCF8-C69746EC8271}.Debug|Any CPU.Build.0 = Debug|Any CPU - {097B4AC0-74E9-4C58-BCF8-C69746EC8271}.Release|Any CPU.ActiveCfg = Release|Any CPU - {097B4AC0-74E9-4C58-BCF8-C69746EC8271}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/Wox/Commands/PluginCommand.cs b/Wox/Commands/PluginCommand.cs index 388db8ecb0..ec3a8edbb6 100644 --- a/Wox/Commands/PluginCommand.cs +++ b/Wox/Commands/PluginCommand.cs @@ -2,7 +2,6 @@ using System.Collections.Generic; using System.Linq; using System.Threading; -using Python.Runtime; using Wox.Helper; using Wox.Infrastructure.Storage.UserSettings; using Wox.Plugin; @@ -12,9 +11,6 @@ namespace Wox.Commands { public class PluginCommand : BaseCommand { - private string currentPythonModulePath = string.Empty; - private IntPtr GIL; - public override void Dispatch(Query query) { PluginPair thirdPlugin = Plugins.AllPlugins.FirstOrDefault(o => o.Metadata.ActionKeyword == query.ActionName); @@ -28,10 +24,6 @@ namespace Wox.Commands return; } - //if (thirdPlugin.Metadata.Language == AllowedLanguage.Python) - //{ - // SwitchPythonEnv(thirdPlugin); - //} ThreadPool.QueueUserWorkItem(t => { try @@ -52,24 +44,5 @@ namespace Wox.Commands }); } } - - private void SwitchPythonEnv(PluginPair thirdPlugin) - { - if (currentPythonModulePath != thirdPlugin.Metadata.PluginDirecotry) - { - currentPythonModulePath = thirdPlugin.Metadata.PluginDirecotry; - - if (GIL != IntPtr.Zero) - { - Runtime.PyEval_RestoreThread(GIL); - PythonEngine.Shutdown(); - } - PythonEngine.Initialize(); - IntPtr pyStrPtr = Runtime.PyString_FromString(thirdPlugin.Metadata.PluginDirecotry); - IntPtr sysDotPath = Runtime.PySys_GetObject("path"); - Runtime.PyList_Append(sysDotPath, pyStrPtr); - GIL = PythonEngine.BeginAllowThreads(); - } - } } } diff --git a/Wox/PluginLoader/BasePluginLoader.cs b/Wox/PluginLoader/BasePluginLoader.cs index 98b8e7b63f..df83b8c07d 100644 --- a/Wox/PluginLoader/BasePluginLoader.cs +++ b/Wox/PluginLoader/BasePluginLoader.cs @@ -7,9 +7,9 @@ using Wox.RPC; namespace Wox.PluginLoader { - public class BasePluginLoader where T :BasePluginWrapper,new() + public class BasePluginLoader : IPluginLoader where T : BasePluginWrapper, new() { - public List LoadPlugin(List pluginMetadatas) + public virtual List LoadPlugin(List pluginMetadatas) { List plugins = new List(); diff --git a/Wox/PluginLoader/BasePluginWrapper.cs b/Wox/PluginLoader/BasePluginWrapper.cs index ff450f8fb7..75be34fdd0 100644 --- a/Wox/PluginLoader/BasePluginWrapper.cs +++ b/Wox/PluginLoader/BasePluginWrapper.cs @@ -15,33 +15,27 @@ namespace Wox.PluginLoader protected PluginInitContext context; public abstract List GetAllowedLanguages(); - protected abstract string GetFileName(); - protected abstract string GetQueryArguments(Query query); - - protected abstract string GetActionJsonRPCArguments(ActionJsonRPCResult result); + protected abstract string ExecuteQuery(Query query); + protected abstract string ExecuteAction(string rpcRequest); public List Query(Query query) { - string fileName = GetFileName(); - string arguments = GetQueryArguments(query); - string output = Execute(fileName, arguments); + string output = ExecuteQuery(query); if (!string.IsNullOrEmpty(output)) { try { - JsonPRCModel rpc = JsonConvert.DeserializeObject(output); - List rpcresults = - JsonConvert.DeserializeObject>(rpc.result); List results = new List(); - foreach (ActionJsonRPCResult result in rpcresults) + + JsonRPCQueryResponseModel queryResponseModel = JsonConvert.DeserializeObject(output); + foreach (JsonRPCResult result in queryResponseModel.QueryResults) { - if (!string.IsNullOrEmpty(result.ActionJSONRPC)) + if (result.JSONRPCActionModel != null) { - ActionJsonRPCResult resultCopy = result; result.Action = (c) => { - Execute(fileName, GetActionJsonRPCArguments(resultCopy)); + ExecuteAction(result.JSONRPCAction); return true; }; } @@ -56,7 +50,13 @@ namespace Wox.PluginLoader return null; } - private string Execute(string fileName, string arguments) + /// + /// Execute external program and return the output + /// + /// + /// + /// + protected string Execute(string fileName, string arguments) { try { diff --git a/Wox/PluginLoader/CSharpPluginConfigLoader.cs b/Wox/PluginLoader/CSharpPluginConfigLoader.cs index 088817792f..53421b36a4 100644 --- a/Wox/PluginLoader/CSharpPluginConfigLoader.cs +++ b/Wox/PluginLoader/CSharpPluginConfigLoader.cs @@ -8,7 +8,7 @@ using Wox.Plugin.SystemPlugins; namespace Wox.PluginLoader { - public class CSharpPluginConfigLoader + public class CSharpPluginConfigLoader : IPluginLoader { public List LoadPlugin(List pluginMetadatas) { diff --git a/Wox/PluginLoader/IPluginLoader.cs b/Wox/PluginLoader/IPluginLoader.cs new file mode 100644 index 0000000000..6eecec4d8c --- /dev/null +++ b/Wox/PluginLoader/IPluginLoader.cs @@ -0,0 +1,13 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using Wox.Plugin; + +namespace Wox.PluginLoader +{ + public interface IPluginLoader + { + List LoadPlugin(List pluginMetadatas); + } +} diff --git a/Wox/PluginLoader/PythonPluginWrapper.cs b/Wox/PluginLoader/PythonPluginWrapper.cs index f6c1f39667..884d3e31f0 100644 --- a/Wox/PluginLoader/PythonPluginWrapper.cs +++ b/Wox/PluginLoader/PythonPluginWrapper.cs @@ -1,11 +1,6 @@ -using System; -using System.Collections.Generic; +using System.Collections.Generic; using System.IO; -using System.Linq; -using System.Threading; -using Python.Runtime; using Wox.Plugin; -using Wox.Helper; using Wox.RPC; namespace Wox.PluginLoader @@ -22,22 +17,20 @@ namespace Wox.PluginLoader }; } - protected override string GetFileName() + protected override string ExecuteQuery(Query query) { - return Path.Combine(woxDirectory, "PYTHONTHOME\\Scripts\\python.exe"); + string fileName = Path.Combine(woxDirectory, "PYTHONTHOME\\Scripts\\python.exe"); + string parameters = string.Format("{0} \"{1}\"", context.CurrentPluginMetadata.ExecuteFilePath, + JsonRPC.Send("query", query.GetAllRemainingParameter())); + return Execute(fileName, parameters); } - protected override string GetQueryArguments(Query query) + protected override string ExecuteAction(string rpcRequest) { - return string.Format("{0} \"{1}\"", - context.CurrentPluginMetadata.ExecuteFilePath, - JsonRPC.GetRPC("query", query.GetAllRemainingParameter())); - } - - protected override string GetActionJsonRPCArguments(ActionJsonRPCResult result) - { - return string.Format("{0} \"{1}\"", context.CurrentPluginMetadata.ExecuteFilePath, - result.ActionJSONRPC); + string fileName = Path.Combine(woxDirectory, "PYTHONTHOME\\Scripts\\python.exe"); + string parameters = string.Format("{0} \"{1}\"", context.CurrentPluginMetadata.ExecuteFilePath, + rpcRequest); + return Execute(fileName, parameters); } } -} +} \ No newline at end of file diff --git a/Wox/RPC/JsonPRCModel.cs b/Wox/RPC/JsonPRCModel.cs index 79d133b535..01f2a9be13 100644 --- a/Wox/RPC/JsonPRCModel.cs +++ b/Wox/RPC/JsonPRCModel.cs @@ -1,17 +1,62 @@ -using Wox.Plugin; +using System.Collections.Generic; +using System.Windows.Documents; +using Newtonsoft.Json; +using Wox.Plugin; namespace Wox.RPC { - public class JsonPRCModel + public class JsonRPCErrorModel { - public int id { get; set; } - public string jsonrpc { get; set; } + public int Code { get; set; } - public string result { get; set; } + public string Message { get; set; } + + public string Data { get; set; } } - public class ActionJsonRPCResult : Result + public class JsonRPCModelBase { - public string ActionJSONRPC { get; set; } + public int Id { get; set; } + + public string JsonRPC { get; set; } + } + + public class JsonRPCResponseModel : JsonRPCModelBase + { + public string Result { get; set; } + + public JsonRPCErrorModel Error { get; set; } + } + + public class JsonRPCQueryResponseModel : JsonRPCResponseModel + { + public List QueryResults + { + get + { + return JsonConvert.DeserializeObject>(Result); + } + } + } + + public class JsonRPCRequestModel : JsonRPCModelBase + { + public string Method { get; set; } + + /* + * 1. c# can't use params as the variable name + * 2. all prarmeter should be string type + */ + public List Parameters { get; set; } + } + + public class JsonRPCResult : Result + { + public string JSONRPCAction { get; set; } + + public JsonRPCRequestModel JSONRPCActionModel + { + get { return null; } + } } } diff --git a/Wox/RPC/JsonRPC.cs b/Wox/RPC/JsonRPC.cs index 3ce2cb5725..1c4dd08145 100644 --- a/Wox/RPC/JsonRPC.cs +++ b/Wox/RPC/JsonRPC.cs @@ -5,16 +5,16 @@ namespace Wox.RPC { public class JsonRPC { - public static string GetRPC(string method, List paras) + public static string Send(string method, List paras) { var list = paras.Select(s => string.Format(@"\""{0}\""", s)); return string.Format(@"{{\""jsonrpc\"": \""2.0\"",\""method\"": \""{0}\"", \""params\"": [{1}], \""id\"": 1}}", method, string.Join(",", list.ToArray())); } - public static string GetRPC(string method, string para) + public static string Send(string method, string para) { - return GetRPC(method, new List() { para }); + return Send(method, new List() { para }); } } } diff --git a/Wox/Wox.csproj b/Wox/Wox.csproj index 384a3bc2bc..4a03802ba9 100644 --- a/Wox/Wox.csproj +++ b/Wox/Wox.csproj @@ -138,6 +138,7 @@ HotkeyControl.xaml + Msg.xaml @@ -263,10 +264,6 @@ - - {097b4ac0-74e9-4c58-bcf8-c69746ec8271} - Python.Runtime - {4fd29318-a8ab-4d8f-aa47-60bc241b8da3} Wox.Infrastructure From 53cb4189d877c4cc53942911f52aef20bacef3f3 Mon Sep 17 00:00:00 2001 From: qianlifeng Date: Wed, 9 Jul 2014 18:15:23 +0800 Subject: [PATCH 04/10] Add portable python environment --- PythonHome/DLLs/py.ico | Bin 0 -> 19790 bytes PythonHome/DLLs/pyc.ico | Bin 0 -> 19790 bytes PythonHome/Lib/BaseHTTPServer.pyc | Bin 0 -> 21389 bytes PythonHome/Lib/Bastion.pyc | Bin 0 -> 6435 bytes PythonHome/Lib/CGIHTTPServer.pyc | Bin 0 -> 10868 bytes PythonHome/Lib/ConfigParser.pyc | Bin 0 -> 24918 bytes PythonHome/Lib/Cookie.pyc | Bin 0 -> 22230 bytes PythonHome/Lib/DocXMLRPCServer.pyc | Bin 0 -> 9564 bytes PythonHome/Lib/HTMLParser.pyc | Bin 0 -> 13574 bytes PythonHome/Lib/MimeWriter.pyc | Bin 0 -> 7229 bytes PythonHome/Lib/Queue.pyc | Bin 0 -> 9284 bytes PythonHome/Lib/SimpleHTTPServer.pyc | Bin 0 -> 7701 bytes PythonHome/Lib/SimpleXMLRPCServer.pyc | Bin 0 -> 22322 bytes PythonHome/Lib/SocketServer.pyc | Bin 0 -> 23733 bytes PythonHome/Lib/StringIO.pyc | Bin 0 -> 11385 bytes PythonHome/Lib/UserDict.pyc | Bin 0 -> 8595 bytes PythonHome/Lib/UserList.pyc | Bin 0 -> 6067 bytes PythonHome/Lib/UserString.pyc | Bin 0 -> 13844 bytes PythonHome/Lib/_LWPCookieJar.pyc | Bin 0 -> 5504 bytes PythonHome/Lib/_MozillaCookieJar.pyc | Bin 0 -> 4440 bytes PythonHome/Lib/__future__.pyc | Bin 0 -> 4262 bytes PythonHome/Lib/__phello__.foo.pyc | Bin 0 -> 110 bytes PythonHome/Lib/_abcoll.pyc | Bin 0 -> 25060 bytes PythonHome/Lib/_osx_support.pyc | Bin 0 -> 11527 bytes PythonHome/Lib/_pyio.pyc | Bin 0 -> 61784 bytes PythonHome/Lib/_strptime.pyc | Bin 0 -> 14575 bytes PythonHome/Lib/_threading_local.pyc | Bin 0 -> 6469 bytes PythonHome/Lib/_weakrefset.pyc | Bin 0 -> 9438 bytes PythonHome/Lib/abc.pyc | Bin 0 -> 6088 bytes PythonHome/Lib/aifc.pyc | Bin 0 -> 29358 bytes PythonHome/Lib/antigravity.pyc | Bin 0 -> 188 bytes PythonHome/Lib/anydbm.pyc | Bin 0 -> 2755 bytes PythonHome/Lib/argparse.pyc | Bin 0 -> 61934 bytes PythonHome/Lib/ast.pyc | Bin 0 -> 12834 bytes PythonHome/Lib/asynchat.pyc | Bin 0 -> 8190 bytes PythonHome/Lib/asyncore.pyc | Bin 0 -> 17953 bytes PythonHome/Lib/atexit.pyc | Bin 0 -> 2173 bytes PythonHome/Lib/audiodev.pyc | Bin 0 -> 8063 bytes PythonHome/Lib/base64.pyc | Bin 0 -> 10798 bytes PythonHome/Lib/bdb.pyc | Bin 0 -> 18186 bytes PythonHome/Lib/binhex.pyc | Bin 0 -> 14635 bytes PythonHome/Lib/bisect.pyc | Bin 0 -> 3046 bytes PythonHome/Lib/bsddb/__init__.pyc | Bin 0 -> 11893 bytes PythonHome/Lib/bsddb/db.pyc | Bin 0 -> 577 bytes PythonHome/Lib/bsddb/dbobj.pyc | Bin 0 -> 17218 bytes PythonHome/Lib/bsddb/dbrecio.pyc | Bin 0 -> 5121 bytes PythonHome/Lib/bsddb/dbshelve.pyc | Bin 0 -> 12242 bytes PythonHome/Lib/bsddb/dbtables.pyc | Bin 0 -> 23627 bytes PythonHome/Lib/bsddb/dbutils.pyc | Bin 0 -> 1597 bytes PythonHome/Lib/cProfile.pyc | Bin 0 -> 6098 bytes PythonHome/Lib/calendar.pyc | Bin 0 -> 27394 bytes PythonHome/Lib/cgi.pyc | Bin 0 -> 32214 bytes PythonHome/Lib/cgitb.pyc | Bin 0 -> 11914 bytes PythonHome/Lib/chunk.pyc | Bin 0 -> 5426 bytes PythonHome/Lib/cmd.pyc | Bin 0 -> 13724 bytes PythonHome/Lib/code.pyc | Bin 0 -> 10093 bytes PythonHome/Lib/codecs.pyc | Bin 0 -> 36115 bytes PythonHome/Lib/codeop.pyc | Bin 0 -> 6447 bytes PythonHome/Lib/collections.pyc | Bin 0 -> 24547 bytes PythonHome/Lib/colorsys.pyc | Bin 0 -> 3871 bytes PythonHome/Lib/commands.pyc | Bin 0 -> 2379 bytes PythonHome/Lib/compileall.pyc | Bin 0 -> 6986 bytes PythonHome/Lib/compiler/__init__.pyc | Bin 0 -> 1282 bytes PythonHome/Lib/compiler/ast.pyc | Bin 0 -> 66290 bytes PythonHome/Lib/compiler/consts.pyc | Bin 0 -> 722 bytes PythonHome/Lib/compiler/future.pyc | Bin 0 -> 2806 bytes PythonHome/Lib/compiler/misc.pyc | Bin 0 -> 3448 bytes PythonHome/Lib/compiler/pyassem.pyc | Bin 0 -> 24734 bytes PythonHome/Lib/compiler/pycodegen.pyc | Bin 0 -> 53920 bytes PythonHome/Lib/compiler/symbols.pyc | Bin 0 -> 16837 bytes PythonHome/Lib/compiler/syntax.pyc | Bin 0 -> 1792 bytes PythonHome/Lib/compiler/transformer.pyc | Bin 0 -> 45754 bytes PythonHome/Lib/compiler/visitor.pyc | Bin 0 -> 4037 bytes PythonHome/Lib/contextlib.pyc | Bin 0 -> 4394 bytes PythonHome/Lib/cookielib.pyc | Bin 0 -> 54236 bytes PythonHome/Lib/copy.pyc | Bin 0 -> 12064 bytes PythonHome/Lib/copy_reg.pyc | Bin 0 -> 5058 bytes PythonHome/Lib/csv.pyc | Bin 0 -> 13375 bytes PythonHome/Lib/ctypes/__init__.pyc | Bin 0 -> 20021 bytes PythonHome/Lib/ctypes/_endian.pyc | Bin 0 -> 2277 bytes PythonHome/Lib/ctypes/macholib/__init__.pyc | Bin 0 -> 301 bytes PythonHome/Lib/ctypes/macholib/dyld.pyc | Bin 0 -> 5547 bytes PythonHome/Lib/ctypes/macholib/dylib.pyc | Bin 0 -> 2255 bytes PythonHome/Lib/ctypes/macholib/framework.pyc | Bin 0 -> 2565 bytes PythonHome/Lib/ctypes/util.pyc | Bin 0 -> 7914 bytes PythonHome/Lib/ctypes/wintypes.pyc | Bin 0 -> 5890 bytes PythonHome/Lib/curses/__init__.pyc | Bin 0 -> 1508 bytes PythonHome/Lib/curses/ascii.pyc | Bin 0 -> 4775 bytes PythonHome/Lib/curses/has_key.pyc | Bin 0 -> 5907 bytes PythonHome/Lib/curses/panel.pyc | Bin 0 -> 262 bytes PythonHome/Lib/curses/textpad.pyc | Bin 0 -> 6719 bytes PythonHome/Lib/curses/wrapper.pyc | Bin 0 -> 1188 bytes PythonHome/Lib/dbhash.pyc | Bin 0 -> 688 bytes PythonHome/Lib/decimal.pyc | Bin 0 -> 167489 bytes PythonHome/Lib/difflib.pyc | Bin 0 -> 61139 bytes PythonHome/Lib/dircache.pyc | Bin 0 -> 1516 bytes PythonHome/Lib/dis.pyc | Bin 0 -> 6108 bytes PythonHome/Lib/distutils/__init__.pyc | Bin 0 -> 380 bytes PythonHome/Lib/distutils/archive_util.pyc | Bin 0 -> 7416 bytes PythonHome/Lib/distutils/bcppcompiler.pyc | Bin 0 -> 7747 bytes PythonHome/Lib/distutils/ccompiler.pyc | Bin 0 -> 36549 bytes PythonHome/Lib/distutils/cmd.pyc | Bin 0 -> 16619 bytes PythonHome/Lib/distutils/command/__init__.pyc | Bin 0 -> 660 bytes PythonHome/Lib/distutils/command/bdist.pyc | Bin 0 -> 5129 bytes .../Lib/distutils/command/bdist_dumb.pyc | Bin 0 -> 4968 bytes .../Lib/distutils/command/bdist_msi.pyc | Bin 0 -> 23758 bytes .../Lib/distutils/command/bdist_rpm.pyc | Bin 0 -> 17601 bytes .../Lib/distutils/command/bdist_wininst.pyc | Bin 0 -> 10650 bytes PythonHome/Lib/distutils/command/build.pyc | Bin 0 -> 5097 bytes .../Lib/distutils/command/build_clib.pyc | Bin 0 -> 6283 bytes .../Lib/distutils/command/build_ext.pyc | Bin 0 -> 19280 bytes PythonHome/Lib/distutils/command/build_py.pyc | Bin 0 -> 11218 bytes .../Lib/distutils/command/build_scripts.pyc | Bin 0 -> 4429 bytes PythonHome/Lib/distutils/command/check.pyc | Bin 0 -> 6045 bytes PythonHome/Lib/distutils/command/clean.pyc | Bin 0 -> 3101 bytes PythonHome/Lib/distutils/command/config.pyc | Bin 0 -> 12389 bytes PythonHome/Lib/distutils/command/install.pyc | Bin 0 -> 16755 bytes .../Lib/distutils/command/install_data.pyc | Bin 0 -> 3059 bytes .../distutils/command/install_egg_info.pyc | Bin 0 -> 3631 bytes .../Lib/distutils/command/install_headers.pyc | Bin 0 -> 2191 bytes .../Lib/distutils/command/install_lib.pyc | Bin 0 -> 6604 bytes .../Lib/distutils/command/install_scripts.pyc | Bin 0 -> 2893 bytes PythonHome/Lib/distutils/command/register.pyc | Bin 0 -> 10027 bytes PythonHome/Lib/distutils/command/sdist.pyc | Bin 0 -> 16430 bytes PythonHome/Lib/distutils/command/upload.pyc | Bin 0 -> 6238 bytes PythonHome/Lib/distutils/config.pyc | Bin 0 -> 3535 bytes PythonHome/Lib/distutils/core.pyc | Bin 0 -> 7638 bytes PythonHome/Lib/distutils/cygwinccompiler.pyc | Bin 0 -> 9645 bytes PythonHome/Lib/distutils/debug.pyc | Bin 0 -> 249 bytes PythonHome/Lib/distutils/dep_util.pyc | Bin 0 -> 3160 bytes PythonHome/Lib/distutils/dir_util.pyc | Bin 0 -> 6753 bytes PythonHome/Lib/distutils/dist.pyc | Bin 0 -> 39231 bytes PythonHome/Lib/distutils/emxccompiler.pyc | Bin 0 -> 7332 bytes PythonHome/Lib/distutils/errors.pyc | Bin 0 -> 6185 bytes PythonHome/Lib/distutils/extension.pyc | Bin 0 -> 7391 bytes PythonHome/Lib/distutils/fancy_getopt.pyc | Bin 0 -> 11853 bytes PythonHome/Lib/distutils/file_util.pyc | Bin 0 -> 6601 bytes PythonHome/Lib/distutils/filelist.pyc | Bin 0 -> 10508 bytes PythonHome/Lib/distutils/log.pyc | Bin 0 -> 2726 bytes PythonHome/Lib/distutils/msvc9compiler.pyc | Bin 0 -> 21387 bytes PythonHome/Lib/distutils/msvccompiler.pyc | Bin 0 -> 17393 bytes PythonHome/Lib/distutils/spawn.pyc | Bin 0 -> 6363 bytes PythonHome/Lib/distutils/sysconfig.pyc | Bin 0 -> 13137 bytes PythonHome/Lib/distutils/text_file.pyc | Bin 0 -> 9079 bytes PythonHome/Lib/distutils/unixccompiler.pyc | Bin 0 -> 7433 bytes PythonHome/Lib/distutils/util.pyc | Bin 0 -> 14295 bytes PythonHome/Lib/distutils/version.pyc | Bin 0 -> 7133 bytes PythonHome/Lib/distutils/versionpredicate.pyc | Bin 0 -> 5437 bytes PythonHome/Lib/doctest.pyc | Bin 0 -> 81866 bytes PythonHome/Lib/dumbdbm.pyc | Bin 0 -> 6242 bytes PythonHome/Lib/dummy_thread.pyc | Bin 0 -> 5169 bytes PythonHome/Lib/dummy_threading.pyc | Bin 0 -> 1270 bytes PythonHome/Lib/email/__init__.pyc | Bin 0 -> 2842 bytes PythonHome/Lib/email/_parseaddr.pyc | Bin 0 -> 13690 bytes PythonHome/Lib/email/base64mime.pyc | Bin 0 -> 5298 bytes PythonHome/Lib/email/charset.pyc | Bin 0 -> 13456 bytes PythonHome/Lib/email/encoders.pyc | Bin 0 -> 2197 bytes PythonHome/Lib/email/errors.pyc | Bin 0 -> 3454 bytes PythonHome/Lib/email/feedparser.pyc | Bin 0 -> 11027 bytes PythonHome/Lib/email/generator.pyc | Bin 0 -> 10095 bytes PythonHome/Lib/email/header.pyc | Bin 0 -> 13422 bytes PythonHome/Lib/email/iterators.pyc | Bin 0 -> 2341 bytes PythonHome/Lib/email/message.pyc | Bin 0 -> 28454 bytes PythonHome/Lib/email/mime/__init__.pyc | Bin 0 -> 125 bytes PythonHome/Lib/email/mime/application.pyc | Bin 0 -> 1539 bytes PythonHome/Lib/email/mime/audio.pyc | Bin 0 -> 2849 bytes PythonHome/Lib/email/mime/base.pyc | Bin 0 -> 1071 bytes PythonHome/Lib/email/mime/image.pyc | Bin 0 -> 2004 bytes PythonHome/Lib/email/mime/message.pyc | Bin 0 -> 1403 bytes PythonHome/Lib/email/mime/multipart.pyc | Bin 0 -> 1624 bytes PythonHome/Lib/email/mime/nonmultipart.pyc | Bin 0 -> 841 bytes PythonHome/Lib/email/mime/text.pyc | Bin 0 -> 1263 bytes PythonHome/Lib/email/parser.pyc | Bin 0 -> 3789 bytes PythonHome/Lib/email/quoprimime.pyc | Bin 0 -> 8785 bytes PythonHome/Lib/email/utils.pyc | Bin 0 -> 9083 bytes PythonHome/Lib/encodings/__init__.pyc | Bin 0 -> 4358 bytes PythonHome/Lib/encodings/aliases.pyc | Bin 0 -> 8765 bytes PythonHome/Lib/encodings/ascii.pyc | Bin 0 -> 2231 bytes PythonHome/Lib/encodings/base64_codec.pyc | Bin 0 -> 3633 bytes PythonHome/Lib/encodings/big5.pyc | Bin 0 -> 1665 bytes PythonHome/Lib/encodings/big5hkscs.pyc | Bin 0 -> 1705 bytes PythonHome/Lib/encodings/bz2_codec.pyc | Bin 0 -> 4473 bytes PythonHome/Lib/encodings/charmap.pyc | Bin 0 -> 3278 bytes PythonHome/Lib/encodings/cp037.pyc | Bin 0 -> 2694 bytes PythonHome/Lib/encodings/cp1006.pyc | Bin 0 -> 2780 bytes PythonHome/Lib/encodings/cp1026.pyc | Bin 0 -> 2708 bytes PythonHome/Lib/encodings/cp1140.pyc | Bin 0 -> 2694 bytes PythonHome/Lib/encodings/cp1250.pyc | Bin 0 -> 2731 bytes PythonHome/Lib/encodings/cp1251.pyc | Bin 0 -> 2728 bytes PythonHome/Lib/encodings/cp1252.pyc | Bin 0 -> 2731 bytes PythonHome/Lib/encodings/cp1253.pyc | Bin 0 -> 2744 bytes PythonHome/Lib/encodings/cp1254.pyc | Bin 0 -> 2733 bytes PythonHome/Lib/encodings/cp1255.pyc | Bin 0 -> 2752 bytes PythonHome/Lib/encodings/cp1256.pyc | Bin 0 -> 2730 bytes PythonHome/Lib/encodings/cp1257.pyc | Bin 0 -> 2738 bytes PythonHome/Lib/encodings/cp1258.pyc | Bin 0 -> 2736 bytes PythonHome/Lib/encodings/cp424.pyc | Bin 0 -> 2724 bytes PythonHome/Lib/encodings/cp437.pyc | Bin 0 -> 7929 bytes PythonHome/Lib/encodings/cp500.pyc | Bin 0 -> 2694 bytes PythonHome/Lib/encodings/cp720.pyc | Bin 0 -> 2791 bytes PythonHome/Lib/encodings/cp737.pyc | Bin 0 -> 8157 bytes PythonHome/Lib/encodings/cp775.pyc | Bin 0 -> 7943 bytes PythonHome/Lib/encodings/cp850.pyc | Bin 0 -> 7676 bytes PythonHome/Lib/encodings/cp852.pyc | Bin 0 -> 7945 bytes PythonHome/Lib/encodings/cp855.pyc | Bin 0 -> 8126 bytes PythonHome/Lib/encodings/cp856.pyc | Bin 0 -> 2756 bytes PythonHome/Lib/encodings/cp857.pyc | Bin 0 -> 7666 bytes PythonHome/Lib/encodings/cp858.pyc | Bin 0 -> 7646 bytes PythonHome/Lib/encodings/cp860.pyc | Bin 0 -> 7912 bytes PythonHome/Lib/encodings/cp861.pyc | Bin 0 -> 7923 bytes PythonHome/Lib/encodings/cp862.pyc | Bin 0 -> 8058 bytes PythonHome/Lib/encodings/cp863.pyc | Bin 0 -> 7923 bytes PythonHome/Lib/encodings/cp864.pyc | Bin 0 -> 8054 bytes PythonHome/Lib/encodings/cp865.pyc | Bin 0 -> 7923 bytes PythonHome/Lib/encodings/cp866.pyc | Bin 0 -> 8158 bytes PythonHome/Lib/encodings/cp869.pyc | Bin 0 -> 7970 bytes PythonHome/Lib/encodings/cp874.pyc | Bin 0 -> 2822 bytes PythonHome/Lib/encodings/cp875.pyc | Bin 0 -> 2691 bytes PythonHome/Lib/encodings/cp932.pyc | Bin 0 -> 1673 bytes PythonHome/Lib/encodings/cp949.pyc | Bin 0 -> 1673 bytes PythonHome/Lib/encodings/cp950.pyc | Bin 0 -> 1673 bytes PythonHome/Lib/encodings/euc_jis_2004.pyc | Bin 0 -> 1729 bytes PythonHome/Lib/encodings/euc_jisx0213.pyc | Bin 0 -> 1729 bytes PythonHome/Lib/encodings/euc_jp.pyc | Bin 0 -> 1681 bytes PythonHome/Lib/encodings/euc_kr.pyc | Bin 0 -> 1681 bytes PythonHome/Lib/encodings/gb18030.pyc | Bin 0 -> 1689 bytes PythonHome/Lib/encodings/gb2312.pyc | Bin 0 -> 1681 bytes PythonHome/Lib/encodings/gbk.pyc | Bin 0 -> 1727 bytes PythonHome/Lib/encodings/hex_codec.pyc | Bin 0 -> 3715 bytes PythonHome/Lib/encodings/hp_roman8.pyc | Bin 0 -> 3977 bytes PythonHome/Lib/encodings/hz.pyc | Bin 0 -> 1649 bytes PythonHome/Lib/encodings/idna.pyc | Bin 0 -> 6334 bytes PythonHome/Lib/encodings/iso2022_jp.pyc | Bin 0 -> 1718 bytes PythonHome/Lib/encodings/iso2022_jp_1.pyc | Bin 0 -> 1734 bytes PythonHome/Lib/encodings/iso2022_jp_2.pyc | Bin 0 -> 1734 bytes PythonHome/Lib/encodings/iso2022_jp_2004.pyc | Bin 0 -> 1758 bytes PythonHome/Lib/encodings/iso2022_jp_3.pyc | Bin 0 -> 1734 bytes PythonHome/Lib/encodings/iso2022_jp_ext.pyc | Bin 0 -> 1750 bytes PythonHome/Lib/encodings/iso2022_kr.pyc | Bin 0 -> 1718 bytes PythonHome/Lib/encodings/iso8859_1.pyc | Bin 0 -> 2733 bytes PythonHome/Lib/encodings/iso8859_10.pyc | Bin 0 -> 2748 bytes PythonHome/Lib/encodings/iso8859_11.pyc | Bin 0 -> 2842 bytes PythonHome/Lib/encodings/iso8859_13.pyc | Bin 0 -> 2751 bytes PythonHome/Lib/encodings/iso8859_14.pyc | Bin 0 -> 2769 bytes PythonHome/Lib/encodings/iso8859_15.pyc | Bin 0 -> 2748 bytes PythonHome/Lib/encodings/iso8859_16.pyc | Bin 0 -> 2750 bytes PythonHome/Lib/encodings/iso8859_2.pyc | Bin 0 -> 2733 bytes PythonHome/Lib/encodings/iso8859_3.pyc | Bin 0 -> 2740 bytes PythonHome/Lib/encodings/iso8859_4.pyc | Bin 0 -> 2733 bytes PythonHome/Lib/encodings/iso8859_5.pyc | Bin 0 -> 2734 bytes PythonHome/Lib/encodings/iso8859_6.pyc | Bin 0 -> 2778 bytes PythonHome/Lib/encodings/iso8859_7.pyc | Bin 0 -> 2741 bytes PythonHome/Lib/encodings/iso8859_8.pyc | Bin 0 -> 2772 bytes PythonHome/Lib/encodings/iso8859_9.pyc | Bin 0 -> 2733 bytes PythonHome/Lib/encodings/johab.pyc | Bin 0 -> 1673 bytes PythonHome/Lib/encodings/koi8_r.pyc | Bin 0 -> 2755 bytes PythonHome/Lib/encodings/koi8_u.pyc | Bin 0 -> 2741 bytes PythonHome/Lib/encodings/latin_1.pyc | Bin 0 -> 2261 bytes PythonHome/Lib/encodings/mac_arabic.pyc | Bin 0 -> 7879 bytes PythonHome/Lib/encodings/mac_centeuro.pyc | Bin 0 -> 2802 bytes PythonHome/Lib/encodings/mac_croatian.pyc | Bin 0 -> 2810 bytes PythonHome/Lib/encodings/mac_cyrillic.pyc | Bin 0 -> 2800 bytes PythonHome/Lib/encodings/mac_farsi.pyc | Bin 0 -> 2714 bytes PythonHome/Lib/encodings/mac_greek.pyc | Bin 0 -> 2754 bytes PythonHome/Lib/encodings/mac_iceland.pyc | Bin 0 -> 2793 bytes PythonHome/Lib/encodings/mac_latin2.pyc | Bin 0 -> 4772 bytes PythonHome/Lib/encodings/mac_roman.pyc | Bin 0 -> 2771 bytes PythonHome/Lib/encodings/mac_romanian.pyc | Bin 0 -> 2811 bytes PythonHome/Lib/encodings/mac_turkish.pyc | Bin 0 -> 2794 bytes PythonHome/Lib/encodings/mbcs.pyc | Bin 0 -> 2003 bytes PythonHome/Lib/encodings/palmos.pyc | Bin 0 -> 2931 bytes PythonHome/Lib/encodings/ptcp154.pyc | Bin 0 -> 4755 bytes PythonHome/Lib/encodings/punycode.pyc | Bin 0 -> 7685 bytes PythonHome/Lib/encodings/quopri_codec.pyc | Bin 0 -> 3430 bytes .../Lib/encodings/raw_unicode_escape.pyc | Bin 0 -> 2093 bytes PythonHome/Lib/encodings/rot_13.pyc | Bin 0 -> 3473 bytes PythonHome/Lib/encodings/shift_jis.pyc | Bin 0 -> 1705 bytes PythonHome/Lib/encodings/shift_jis_2004.pyc | Bin 0 -> 1745 bytes PythonHome/Lib/encodings/shift_jisx0213.pyc | Bin 0 -> 1745 bytes PythonHome/Lib/encodings/string_escape.pyc | Bin 0 -> 1952 bytes PythonHome/Lib/encodings/tis_620.pyc | Bin 0 -> 2803 bytes PythonHome/Lib/encodings/undefined.pyc | Bin 0 -> 2454 bytes PythonHome/Lib/encodings/unicode_escape.pyc | Bin 0 -> 2041 bytes PythonHome/Lib/encodings/unicode_internal.pyc | Bin 0 -> 2067 bytes PythonHome/Lib/encodings/utf_16.pyc | Bin 0 -> 4908 bytes PythonHome/Lib/encodings/utf_16_be.pyc | Bin 0 -> 1894 bytes PythonHome/Lib/encodings/utf_16_le.pyc | Bin 0 -> 1894 bytes PythonHome/Lib/encodings/utf_32.pyc | Bin 0 -> 5446 bytes PythonHome/Lib/encodings/utf_32_be.pyc | Bin 0 -> 1787 bytes PythonHome/Lib/encodings/utf_32_le.pyc | Bin 0 -> 1787 bytes PythonHome/Lib/encodings/utf_7.pyc | Bin 0 -> 1787 bytes PythonHome/Lib/encodings/utf_8.pyc | Bin 0 -> 1926 bytes PythonHome/Lib/encodings/utf_8_sig.pyc | Bin 0 -> 4725 bytes PythonHome/Lib/encodings/uu_codec.pyc | Bin 0 -> 4711 bytes PythonHome/Lib/encodings/zlib_codec.pyc | Bin 0 -> 4393 bytes PythonHome/Lib/filecmp.pyc | Bin 0 -> 9322 bytes PythonHome/Lib/fileinput.pyc | Bin 0 -> 14415 bytes PythonHome/Lib/fnmatch.pyc | Bin 0 -> 3504 bytes PythonHome/Lib/formatter.pyc | Bin 0 -> 18023 bytes PythonHome/Lib/fpformat.pyc | Bin 0 -> 4551 bytes PythonHome/Lib/fractions.pyc | Bin 0 -> 19148 bytes PythonHome/Lib/ftplib.pyc | Bin 0 -> 33147 bytes PythonHome/Lib/functools.pyc | Bin 0 -> 5959 bytes PythonHome/Lib/genericpath.pyc | Bin 0 -> 3213 bytes PythonHome/Lib/getopt.pyc | Bin 0 -> 6604 bytes PythonHome/Lib/getpass.pyc | Bin 0 -> 4708 bytes PythonHome/Lib/gettext.pyc | Bin 0 -> 15309 bytes PythonHome/Lib/glob.pyc | Bin 0 -> 2857 bytes PythonHome/Lib/gzip.pyc | Bin 0 -> 14921 bytes PythonHome/Lib/hashlib.pyc | Bin 0 -> 6650 bytes PythonHome/Lib/heapq.pyc | Bin 0 -> 14474 bytes PythonHome/Lib/hmac.pyc | Bin 0 -> 4392 bytes PythonHome/Lib/hotshot/__init__.pyc | Bin 0 -> 3319 bytes PythonHome/Lib/hotshot/log.pyc | Bin 0 -> 5332 bytes PythonHome/Lib/hotshot/stats.pyc | Bin 0 -> 3083 bytes PythonHome/Lib/hotshot/stones.pyc | Bin 0 -> 1126 bytes PythonHome/Lib/htmlentitydefs.pyc | Bin 0 -> 6362 bytes PythonHome/Lib/htmllib.pyc | Bin 0 -> 18944 bytes PythonHome/Lib/httplib.pyc | Bin 0 -> 35522 bytes PythonHome/Lib/idlelib/AutoComplete.pyc | Bin 0 -> 7818 bytes PythonHome/Lib/idlelib/AutoCompleteWindow.pyc | Bin 0 -> 12198 bytes PythonHome/Lib/idlelib/AutoExpand.pyc | Bin 0 -> 3412 bytes PythonHome/Lib/idlelib/Bindings.pyc | Bin 0 -> 4565 bytes PythonHome/Lib/idlelib/CREDITS.txt | 37 + PythonHome/Lib/idlelib/CallTipWindow.pyc | Bin 0 -> 6200 bytes PythonHome/Lib/idlelib/CallTips.pyc | Bin 0 -> 7888 bytes PythonHome/Lib/idlelib/ClassBrowser.pyc | Bin 0 -> 9054 bytes PythonHome/Lib/idlelib/CodeContext.pyc | Bin 0 -> 6522 bytes PythonHome/Lib/idlelib/ColorDelegator.pyc | Bin 0 -> 9036 bytes PythonHome/Lib/idlelib/Debugger.pyc | Bin 0 -> 16270 bytes PythonHome/Lib/idlelib/Delegator.pyc | Bin 0 -> 1178 bytes PythonHome/Lib/idlelib/EditorWindow.pyc | Bin 0 -> 55973 bytes PythonHome/Lib/idlelib/FileList.pyc | Bin 0 -> 3783 bytes PythonHome/Lib/idlelib/FormatParagraph.pyc | Bin 0 -> 6912 bytes PythonHome/Lib/idlelib/GrepDialog.pyc | Bin 0 -> 6126 bytes PythonHome/Lib/idlelib/HISTORY.txt | 296 + PythonHome/Lib/idlelib/HyperParser.pyc | Bin 0 -> 6520 bytes PythonHome/Lib/idlelib/IOBinding.pyc | Bin 0 -> 16827 bytes PythonHome/Lib/idlelib/Icons/folder.gif | Bin 0 -> 120 bytes PythonHome/Lib/idlelib/Icons/idle.icns | Bin 0 -> 57435 bytes PythonHome/Lib/idlelib/Icons/idle.ico | Bin 0 -> 19790 bytes PythonHome/Lib/idlelib/Icons/idle_16.gif | Bin 0 -> 1034 bytes PythonHome/Lib/idlelib/Icons/idle_32.gif | Bin 0 -> 1435 bytes PythonHome/Lib/idlelib/Icons/idle_48.gif | Bin 0 -> 1388 bytes PythonHome/Lib/idlelib/Icons/minusnode.gif | Bin 0 -> 96 bytes PythonHome/Lib/idlelib/Icons/openfolder.gif | Bin 0 -> 125 bytes PythonHome/Lib/idlelib/Icons/plusnode.gif | Bin 0 -> 79 bytes PythonHome/Lib/idlelib/Icons/python.gif | Bin 0 -> 585 bytes PythonHome/Lib/idlelib/Icons/tk.gif | Bin 0 -> 85 bytes PythonHome/Lib/idlelib/IdleHistory.pyc | Bin 0 -> 3954 bytes PythonHome/Lib/idlelib/MultiCall.pyc | Bin 0 -> 15859 bytes PythonHome/Lib/idlelib/MultiStatusBar.pyc | Bin 0 -> 2120 bytes PythonHome/Lib/idlelib/NEWS.txt | 780 +++ PythonHome/Lib/idlelib/ObjectBrowser.pyc | Bin 0 -> 6647 bytes PythonHome/Lib/idlelib/OutputWindow.pyc | Bin 0 -> 5007 bytes PythonHome/Lib/idlelib/ParenMatch.pyc | Bin 0 -> 6874 bytes PythonHome/Lib/idlelib/PathBrowser.pyc | Bin 0 -> 4238 bytes PythonHome/Lib/idlelib/Percolator.pyc | Bin 0 -> 4383 bytes PythonHome/Lib/idlelib/PyParse.pyc | Bin 0 -> 9749 bytes PythonHome/Lib/idlelib/PyShell.pyc | Bin 0 -> 50039 bytes PythonHome/Lib/idlelib/README.txt | 63 + PythonHome/Lib/idlelib/RemoteDebugger.pyc | Bin 0 -> 15420 bytes .../Lib/idlelib/RemoteObjectBrowser.pyc | Bin 0 -> 2000 bytes PythonHome/Lib/idlelib/ReplaceDialog.pyc | Bin 0 -> 7446 bytes PythonHome/Lib/idlelib/RstripExtension.pyc | Bin 0 -> 1553 bytes PythonHome/Lib/idlelib/ScriptBinding.pyc | Bin 0 -> 7973 bytes PythonHome/Lib/idlelib/ScrolledList.pyc | Bin 0 -> 5974 bytes PythonHome/Lib/idlelib/SearchDialog.pyc | Bin 0 -> 3811 bytes PythonHome/Lib/idlelib/SearchDialogBase.pyc | Bin 0 -> 7626 bytes PythonHome/Lib/idlelib/SearchEngine.pyc | Bin 0 -> 7992 bytes PythonHome/Lib/idlelib/StackViewer.pyc | Bin 0 -> 6076 bytes PythonHome/Lib/idlelib/TODO.txt | 210 + PythonHome/Lib/idlelib/ToolTip.pyc | Bin 0 -> 4414 bytes PythonHome/Lib/idlelib/TreeWidget.pyc | Bin 0 -> 16916 bytes PythonHome/Lib/idlelib/UndoDelegator.pyc | Bin 0 -> 12790 bytes PythonHome/Lib/idlelib/WidgetRedirector.pyc | Bin 0 -> 5341 bytes PythonHome/Lib/idlelib/WindowList.pyc | Bin 0 -> 3411 bytes PythonHome/Lib/idlelib/ZoomHeight.pyc | Bin 0 -> 1571 bytes PythonHome/Lib/idlelib/__init__.pyc | Bin 0 -> 112 bytes PythonHome/Lib/idlelib/aboutDialog.pyc | Bin 0 -> 6448 bytes PythonHome/Lib/idlelib/config-extensions.def | 96 + PythonHome/Lib/idlelib/config-highlight.def | 64 + PythonHome/Lib/idlelib/config-keys.def | 214 + PythonHome/Lib/idlelib/config-main.def | 79 + PythonHome/Lib/idlelib/configDialog.pyc | Bin 0 -> 43516 bytes PythonHome/Lib/idlelib/configHandler.pyc | Bin 0 -> 26737 bytes .../Lib/idlelib/configHelpSourceEdit.pyc | Bin 0 -> 6414 bytes .../Lib/idlelib/configSectionNameDialog.pyc | Bin 0 -> 4268 bytes .../Lib/idlelib/dynOptionMenuWidget.pyc | Bin 0 -> 2761 bytes PythonHome/Lib/idlelib/extend.txt | 83 + PythonHome/Lib/idlelib/help.txt | 302 + PythonHome/Lib/idlelib/idle.bat | 4 + PythonHome/Lib/idlelib/idle.pyc | Bin 0 -> 391 bytes PythonHome/Lib/idlelib/idle.pyw | 21 + PythonHome/Lib/idlelib/idlever.pyc | Bin 0 -> 144 bytes PythonHome/Lib/idlelib/keybindingDialog.pyc | Bin 0 -> 11901 bytes PythonHome/Lib/idlelib/macosxSupport.pyc | Bin 0 -> 8284 bytes PythonHome/Lib/idlelib/rpc.pyc | Bin 0 -> 20887 bytes PythonHome/Lib/idlelib/run.pyc | Bin 0 -> 12421 bytes PythonHome/Lib/idlelib/tabbedpages.pyc | Bin 0 -> 17961 bytes PythonHome/Lib/idlelib/testcode.pyc | Bin 0 -> 1289 bytes PythonHome/Lib/idlelib/textView.pyc | Bin 0 -> 3724 bytes PythonHome/Lib/ihooks.pyc | Bin 0 -> 20337 bytes PythonHome/Lib/imaplib.pyc | Bin 0 -> 43871 bytes PythonHome/Lib/imghdr.pyc | Bin 0 -> 4598 bytes PythonHome/Lib/importlib/__init__.pyc | Bin 0 -> 1457 bytes PythonHome/Lib/imputil.pyc | Bin 0 -> 15053 bytes PythonHome/Lib/inspect.pyc | Bin 0 -> 38962 bytes PythonHome/Lib/io.pyc | Bin 0 -> 3563 bytes PythonHome/Lib/json/__init__.pyc | Bin 0 -> 13930 bytes PythonHome/Lib/json/decoder.pyc | Bin 0 -> 12034 bytes PythonHome/Lib/json/encoder.pyc | Bin 0 -> 13625 bytes PythonHome/Lib/json/scanner.pyc | Bin 0 -> 2214 bytes PythonHome/Lib/json/tool.pyc | Bin 0 -> 1264 bytes PythonHome/Lib/keyword.pyc | Bin 0 -> 2095 bytes PythonHome/Lib/lib-tk/Canvas.pyc | Bin 0 -> 14364 bytes PythonHome/Lib/lib-tk/Dialog.pyc | Bin 0 -> 1845 bytes PythonHome/Lib/lib-tk/FileDialog.pyc | Bin 0 -> 9394 bytes PythonHome/Lib/lib-tk/FixTk.pyc | Bin 0 -> 1956 bytes PythonHome/Lib/lib-tk/ScrolledText.pyc | Bin 0 -> 2589 bytes PythonHome/Lib/lib-tk/SimpleDialog.pyc | Bin 0 -> 4174 bytes PythonHome/Lib/lib-tk/Tix.pyc | Bin 0 -> 91067 bytes PythonHome/Lib/lib-tk/Tkconstants.pyc | Bin 0 -> 2231 bytes PythonHome/Lib/lib-tk/Tkdnd.pyc | Bin 0 -> 12435 bytes PythonHome/Lib/lib-tk/Tkinter.pyc | Bin 0 -> 189968 bytes PythonHome/Lib/lib-tk/tkColorChooser.pyc | Bin 0 -> 1345 bytes PythonHome/Lib/lib-tk/tkCommonDialog.pyc | Bin 0 -> 1426 bytes PythonHome/Lib/lib-tk/tkFileDialog.pyc | Bin 0 -> 4921 bytes PythonHome/Lib/lib-tk/tkFont.pyc | Bin 0 -> 6815 bytes PythonHome/Lib/lib-tk/tkMessageBox.pyc | Bin 0 -> 3729 bytes PythonHome/Lib/lib-tk/tkSimpleDialog.pyc | Bin 0 -> 8723 bytes PythonHome/Lib/lib-tk/ttk.pyc | Bin 0 -> 60597 bytes PythonHome/Lib/lib-tk/turtle.pyc | Bin 0 -> 135965 bytes PythonHome/Lib/lib2to3/Grammar.txt | 159 + PythonHome/Lib/lib2to3/PatternGrammar.txt | 28 + PythonHome/Lib/lib2to3/__init__.pyc | Bin 0 -> 112 bytes PythonHome/Lib/lib2to3/__main__.pyc | Bin 0 -> 227 bytes PythonHome/Lib/lib2to3/btm_matcher.pyc | Bin 0 -> 5665 bytes PythonHome/Lib/lib2to3/btm_utils.pyc | Bin 0 -> 7368 bytes PythonHome/Lib/lib2to3/fixer_base.pyc | Bin 0 -> 7017 bytes PythonHome/Lib/lib2to3/fixer_util.pyc | Bin 0 -> 14173 bytes PythonHome/Lib/lib2to3/fixes/__init__.pyc | Bin 0 -> 118 bytes PythonHome/Lib/lib2to3/fixes/fix_apply.pyc | Bin 0 -> 1838 bytes .../Lib/lib2to3/fixes/fix_basestring.pyc | Bin 0 -> 762 bytes PythonHome/Lib/lib2to3/fixes/fix_buffer.pyc | Bin 0 -> 919 bytes PythonHome/Lib/lib2to3/fixes/fix_callable.pyc | Bin 0 -> 1462 bytes PythonHome/Lib/lib2to3/fixes/fix_dict.pyc | Bin 0 -> 3709 bytes PythonHome/Lib/lib2to3/fixes/fix_except.pyc | Bin 0 -> 2949 bytes PythonHome/Lib/lib2to3/fixes/fix_exec.pyc | Bin 0 -> 1387 bytes PythonHome/Lib/lib2to3/fixes/fix_execfile.pyc | Bin 0 -> 2028 bytes PythonHome/Lib/lib2to3/fixes/fix_exitfunc.pyc | Bin 0 -> 2682 bytes PythonHome/Lib/lib2to3/fixes/fix_filter.pyc | Bin 0 -> 2225 bytes .../Lib/lib2to3/fixes/fix_funcattrs.pyc | Bin 0 -> 1083 bytes PythonHome/Lib/lib2to3/fixes/fix_future.pyc | Bin 0 -> 888 bytes PythonHome/Lib/lib2to3/fixes/fix_getcwdu.pyc | Bin 0 -> 895 bytes PythonHome/Lib/lib2to3/fixes/fix_has_key.pyc | Bin 0 -> 3153 bytes PythonHome/Lib/lib2to3/fixes/fix_idioms.pyc | Bin 0 -> 4432 bytes PythonHome/Lib/lib2to3/fixes/fix_import.pyc | Bin 0 -> 3163 bytes PythonHome/Lib/lib2to3/fixes/fix_imports.pyc | Bin 0 -> 5230 bytes PythonHome/Lib/lib2to3/fixes/fix_imports2.pyc | Bin 0 -> 604 bytes PythonHome/Lib/lib2to3/fixes/fix_input.pyc | Bin 0 -> 1103 bytes PythonHome/Lib/lib2to3/fixes/fix_intern.pyc | Bin 0 -> 1574 bytes .../Lib/lib2to3/fixes/fix_isinstance.pyc | Bin 0 -> 1807 bytes .../Lib/lib2to3/fixes/fix_itertools.pyc | Bin 0 -> 1760 bytes .../lib2to3/fixes/fix_itertools_imports.pyc | Bin 0 -> 1985 bytes PythonHome/Lib/lib2to3/fixes/fix_long.pyc | Bin 0 -> 810 bytes PythonHome/Lib/lib2to3/fixes/fix_map.pyc | Bin 0 -> 3009 bytes .../Lib/lib2to3/fixes/fix_metaclass.pyc | Bin 0 -> 6469 bytes .../Lib/lib2to3/fixes/fix_methodattrs.pyc | Bin 0 -> 1107 bytes PythonHome/Lib/lib2to3/fixes/fix_ne.pyc | Bin 0 -> 941 bytes PythonHome/Lib/lib2to3/fixes/fix_next.pyc | Bin 0 -> 3435 bytes PythonHome/Lib/lib2to3/fixes/fix_nonzero.pyc | Bin 0 -> 1055 bytes .../Lib/lib2to3/fixes/fix_numliterals.pyc | Bin 0 -> 1205 bytes PythonHome/Lib/lib2to3/fixes/fix_operator.pyc | Bin 0 -> 4925 bytes PythonHome/Lib/lib2to3/fixes/fix_paren.pyc | Bin 0 -> 1512 bytes PythonHome/Lib/lib2to3/fixes/fix_print.pyc | Bin 0 -> 2683 bytes PythonHome/Lib/lib2to3/fixes/fix_raise.pyc | Bin 0 -> 2467 bytes .../Lib/lib2to3/fixes/fix_raw_input.pyc | Bin 0 -> 905 bytes PythonHome/Lib/lib2to3/fixes/fix_reduce.pyc | Bin 0 -> 1231 bytes PythonHome/Lib/lib2to3/fixes/fix_renames.pyc | Bin 0 -> 2366 bytes PythonHome/Lib/lib2to3/fixes/fix_repr.pyc | Bin 0 -> 985 bytes .../Lib/lib2to3/fixes/fix_set_literal.pyc | Bin 0 -> 1944 bytes .../Lib/lib2to3/fixes/fix_standarderror.pyc | Bin 0 -> 822 bytes PythonHome/Lib/lib2to3/fixes/fix_sys_exc.pyc | Bin 0 -> 1661 bytes PythonHome/Lib/lib2to3/fixes/fix_throw.pyc | Bin 0 -> 1965 bytes .../Lib/lib2to3/fixes/fix_tuple_params.pyc | Bin 0 -> 5308 bytes PythonHome/Lib/lib2to3/fixes/fix_types.pyc | Bin 0 -> 2154 bytes PythonHome/Lib/lib2to3/fixes/fix_unicode.pyc | Bin 0 -> 1672 bytes PythonHome/Lib/lib2to3/fixes/fix_urllib.pyc | Bin 0 -> 7025 bytes PythonHome/Lib/lib2to3/fixes/fix_ws_comma.pyc | Bin 0 -> 1351 bytes PythonHome/Lib/lib2to3/fixes/fix_xrange.pyc | Bin 0 -> 2967 bytes .../Lib/lib2to3/fixes/fix_xreadlines.pyc | Bin 0 -> 1121 bytes PythonHome/Lib/lib2to3/fixes/fix_zip.pyc | Bin 0 -> 1315 bytes PythonHome/Lib/lib2to3/main.pyc | Bin 0 -> 9681 bytes PythonHome/Lib/lib2to3/patcomp.pyc | Bin 0 -> 6486 bytes PythonHome/Lib/lib2to3/pgen2/__init__.pyc | Bin 0 -> 159 bytes PythonHome/Lib/lib2to3/pgen2/conv.pyc | Bin 0 -> 8099 bytes PythonHome/Lib/lib2to3/pgen2/driver.pyc | Bin 0 -> 5223 bytes PythonHome/Lib/lib2to3/pgen2/grammar.pyc | Bin 0 -> 5921 bytes PythonHome/Lib/lib2to3/pgen2/literals.pyc | Bin 0 -> 1958 bytes PythonHome/Lib/lib2to3/pgen2/parse.pyc | Bin 0 -> 7056 bytes PythonHome/Lib/lib2to3/pgen2/pgen.pyc | Bin 0 -> 11693 bytes PythonHome/Lib/lib2to3/pgen2/token.pyc | Bin 0 -> 2243 bytes PythonHome/Lib/lib2to3/pgen2/tokenize.pyc | Bin 0 -> 16570 bytes PythonHome/Lib/lib2to3/pygram.pyc | Bin 0 -> 1369 bytes PythonHome/Lib/lib2to3/pytree.pyc | Bin 0 -> 29163 bytes PythonHome/Lib/lib2to3/refactor.pyc | Bin 0 -> 23342 bytes PythonHome/Lib/linecache.pyc | Bin 0 -> 3181 bytes PythonHome/Lib/locale.pyc | Bin 0 -> 50811 bytes PythonHome/Lib/logging/__init__.pyc | Bin 0 -> 56945 bytes PythonHome/Lib/logging/config.pyc | Bin 0 -> 25686 bytes PythonHome/Lib/logging/handlers.pyc | Bin 0 -> 38918 bytes PythonHome/Lib/macpath.pyc | Bin 0 -> 7362 bytes PythonHome/Lib/macurl2path.pyc | Bin 0 -> 2184 bytes PythonHome/Lib/mailbox.pyc | Bin 0 -> 73406 bytes PythonHome/Lib/mailcap.pyc | Bin 0 -> 6883 bytes PythonHome/Lib/markupbase.pyc | Bin 0 -> 9226 bytes PythonHome/Lib/md5.pyc | Bin 0 -> 363 bytes PythonHome/Lib/mhlib.pyc | Bin 0 -> 32633 bytes PythonHome/Lib/mimetools.pyc | Bin 0 -> 8122 bytes PythonHome/Lib/mimetypes.pyc | Bin 0 -> 18162 bytes PythonHome/Lib/mimify.pyc | Bin 0 -> 11765 bytes PythonHome/Lib/modulefinder.pyc | Bin 0 -> 18201 bytes PythonHome/Lib/msilib/__init__.pyc | Bin 0 -> 18635 bytes PythonHome/Lib/msilib/schema.pyc | Bin 0 -> 59836 bytes PythonHome/Lib/msilib/sequence.pyc | Bin 0 -> 6262 bytes PythonHome/Lib/msilib/text.pyc | Bin 0 -> 18475 bytes PythonHome/Lib/multifile.pyc | Bin 0 -> 5194 bytes PythonHome/Lib/multiprocessing/__init__.pyc | Bin 0 -> 8075 bytes PythonHome/Lib/multiprocessing/connection.pyc | Bin 0 -> 13915 bytes .../Lib/multiprocessing/dummy/__init__.pyc | Bin 0 -> 5160 bytes .../Lib/multiprocessing/dummy/connection.pyc | Bin 0 -> 2584 bytes PythonHome/Lib/multiprocessing/forking.pyc | Bin 0 -> 13866 bytes PythonHome/Lib/multiprocessing/heap.pyc | Bin 0 -> 6609 bytes PythonHome/Lib/multiprocessing/managers.pyc | Bin 0 -> 36869 bytes PythonHome/Lib/multiprocessing/pool.pyc | Bin 0 -> 21436 bytes PythonHome/Lib/multiprocessing/process.pyc | Bin 0 -> 9105 bytes PythonHome/Lib/multiprocessing/queues.pyc | Bin 0 -> 11070 bytes PythonHome/Lib/multiprocessing/reduction.pyc | Bin 0 -> 5758 bytes .../Lib/multiprocessing/sharedctypes.pyc | Bin 0 -> 8202 bytes .../Lib/multiprocessing/synchronize.pyc | Bin 0 -> 10489 bytes PythonHome/Lib/multiprocessing/util.pyc | Bin 0 -> 9710 bytes PythonHome/Lib/mutex.pyc | Bin 0 -> 2410 bytes PythonHome/Lib/netrc.pyc | Bin 0 -> 4534 bytes PythonHome/Lib/new.pyc | Bin 0 -> 847 bytes PythonHome/Lib/nntplib.pyc | Bin 0 -> 20381 bytes PythonHome/Lib/ntpath.pyc | Bin 0 -> 12974 bytes PythonHome/Lib/nturl2path.pyc | Bin 0 -> 1800 bytes PythonHome/Lib/numbers.pyc | Bin 0 -> 13082 bytes PythonHome/Lib/opcode.pyc | Bin 0 -> 6124 bytes PythonHome/Lib/optparse.pyc | Bin 0 -> 53424 bytes PythonHome/Lib/os.pyc | Bin 0 -> 25437 bytes PythonHome/Lib/os2emxpath.pyc | Bin 0 -> 4357 bytes PythonHome/Lib/pdb.pyc | Bin 0 -> 41897 bytes PythonHome/Lib/pickle.pyc | Bin 0 -> 36909 bytes PythonHome/Lib/pickletools.pyc | Bin 0 -> 56630 bytes PythonHome/Lib/pipes.pyc | Bin 0 -> 9068 bytes PythonHome/Lib/pkgutil.pyc | Bin 0 -> 18768 bytes PythonHome/Lib/platform.pyc | Bin 0 -> 36867 bytes PythonHome/Lib/plistlib.pyc | Bin 0 -> 18384 bytes PythonHome/Lib/popen2.pyc | Bin 0 -> 8785 bytes PythonHome/Lib/poplib.pyc | Bin 0 -> 12688 bytes PythonHome/Lib/posixfile.pyc | Bin 0 -> 7472 bytes PythonHome/Lib/posixpath.pyc | Bin 0 -> 11495 bytes PythonHome/Lib/pprint.pyc | Bin 0 -> 9909 bytes PythonHome/Lib/profile.pyc | Bin 0 -> 15873 bytes PythonHome/Lib/pstats.pyc | Bin 0 -> 24113 bytes PythonHome/Lib/pty.pyc | Bin 0 -> 4816 bytes PythonHome/Lib/py_compile.pyc | Bin 0 -> 6389 bytes PythonHome/Lib/pyclbr.pyc | Bin 0 -> 9456 bytes PythonHome/Lib/pydoc.pyc | Bin 0 -> 88903 bytes PythonHome/Lib/pydoc_data/__init__.pyc | Bin 0 -> 115 bytes PythonHome/Lib/pydoc_data/topics.pyc | Bin 0 -> 400488 bytes PythonHome/Lib/quopri.pyc | Bin 0 -> 6517 bytes PythonHome/Lib/random.pyc | Bin 0 -> 25353 bytes PythonHome/Lib/re.pyc | Bin 0 -> 13045 bytes PythonHome/Lib/repr.pyc | Bin 0 -> 5130 bytes PythonHome/Lib/rexec.pyc | Bin 0 -> 23253 bytes PythonHome/Lib/rfc822.pyc | Bin 0 -> 31491 bytes PythonHome/Lib/rlcompleter.pyc | Bin 0 -> 5858 bytes PythonHome/Lib/robotparser.pyc | Bin 0 -> 7600 bytes PythonHome/Lib/runpy.pyc | Bin 0 -> 8308 bytes PythonHome/Lib/sched.pyc | Bin 0 -> 4859 bytes PythonHome/Lib/sets.pyc | Bin 0 -> 16055 bytes PythonHome/Lib/sgmllib.pyc | Bin 0 -> 14731 bytes PythonHome/Lib/sha.pyc | Bin 0 -> 406 bytes PythonHome/Lib/shelve.pyc | Bin 0 -> 9862 bytes PythonHome/Lib/shlex.pyc | Bin 0 -> 7347 bytes PythonHome/Lib/shutil.pyc | Bin 0 -> 18236 bytes PythonHome/Lib/site-packages/README.txt | 2 + .../Lib/site-packages/_markerlib/__init__.pyc | Bin 0 -> 1032 bytes .../Lib/site-packages/_markerlib/markers.pyc | Bin 0 -> 4894 bytes PythonHome/Lib/site-packages/easy_install.pyc | Bin 0 -> 302 bytes .../pip-1.5.6.dist-info/DESCRIPTION.rst | 71 + .../pip-1.5.6.dist-info/METADATA | 98 + .../site-packages/pip-1.5.6.dist-info/RECORD | 374 ++ .../site-packages/pip-1.5.6.dist-info/WHEEL | 6 + .../pip-1.5.6.dist-info/entry_points.txt | 5 + .../pip-1.5.6.dist-info/metadata.json | 1 + .../pip-1.5.6.dist-info/top_level.txt | 1 + PythonHome/Lib/site-packages/pip/__init__.pyc | Bin 0 -> 8946 bytes PythonHome/Lib/site-packages/pip/__main__.pyc | Bin 0 -> 288 bytes .../site-packages/pip/_vendor/__init__.pyc | Bin 0 -> 473 bytes .../pip/_vendor/_markerlib/__init__.pyc | Bin 0 -> 1264 bytes .../pip/_vendor/_markerlib/markers.pyc | Bin 0 -> 5466 bytes .../pip/_vendor/colorama/__init__.pyc | Bin 0 -> 451 bytes .../pip/_vendor/colorama/ansi.pyc | Bin 0 -> 2317 bytes .../pip/_vendor/colorama/ansitowin32.pyc | Bin 0 -> 7700 bytes .../pip/_vendor/colorama/initialise.pyc | Bin 0 -> 2007 bytes .../pip/_vendor/colorama/win32.pyc | Bin 0 -> 4352 bytes .../pip/_vendor/colorama/winterm.pyc | Bin 0 -> 5164 bytes .../pip/_vendor/distlib/__init__.pyc | Bin 0 -> 1455 bytes .../_vendor/distlib/_backport/__init__.pyc | Bin 0 -> 470 bytes .../pip/_vendor/distlib/_backport/misc.pyc | Bin 0 -> 1376 bytes .../pip/_vendor/distlib/_backport/shutil.pyc | Bin 0 -> 27281 bytes .../_vendor/distlib/_backport/sysconfig.cfg | 84 + .../_vendor/distlib/_backport/sysconfig.pyc | Bin 0 -> 20509 bytes .../pip/_vendor/distlib/_backport/tarfile.pyc | Bin 0 -> 82723 bytes .../pip/_vendor/distlib/compat.pyc | Bin 0 -> 40799 bytes .../pip/_vendor/distlib/database.pyc | Bin 0 -> 47938 bytes .../pip/_vendor/distlib/index.pyc | Bin 0 -> 18609 bytes .../pip/_vendor/distlib/locators.pyc | Bin 0 -> 42636 bytes .../pip/_vendor/distlib/manifest.pyc | Bin 0 -> 11644 bytes .../pip/_vendor/distlib/markers.pyc | Bin 0 -> 7863 bytes .../pip/_vendor/distlib/metadata.pyc | Bin 0 -> 33141 bytes .../pip/_vendor/distlib/resources.pyc | Bin 0 -> 13903 bytes .../pip/_vendor/distlib/scripts.pyc | Bin 0 -> 10967 bytes .../pip/_vendor/distlib/util.pyc | Bin 0 -> 58360 bytes .../pip/_vendor/distlib/version.pyc | Bin 0 -> 27211 bytes .../pip/_vendor/distlib/wheel.pyc | Bin 0 -> 30135 bytes .../pip/_vendor/html5lib/__init__.pyc | Bin 0 -> 1116 bytes .../pip/_vendor/html5lib/constants.pyc | Bin 0 -> 86932 bytes .../pip/_vendor/html5lib/filters/__init__.pyc | Bin 0 -> 147 bytes .../pip/_vendor/html5lib/filters/_base.pyc | Bin 0 -> 1046 bytes .../filters/alphabeticalattributes.pyc | Bin 0 -> 1343 bytes .../html5lib/filters/inject_meta_charset.pyc | Bin 0 -> 2202 bytes .../pip/_vendor/html5lib/filters/lint.pyc | Bin 0 -> 3668 bytes .../_vendor/html5lib/filters/optionaltags.pyc | Bin 0 -> 4310 bytes .../_vendor/html5lib/filters/sanitizer.pyc | Bin 0 -> 872 bytes .../_vendor/html5lib/filters/whitespace.pyc | Bin 0 -> 1612 bytes .../pip/_vendor/html5lib/html5parser.pyc | Bin 0 -> 127539 bytes .../pip/_vendor/html5lib/ihatexml.pyc | Bin 0 -> 15797 bytes .../pip/_vendor/html5lib/inputstream.pyc | Bin 0 -> 28518 bytes .../pip/_vendor/html5lib/sanitizer.pyc | Bin 0 -> 14121 bytes .../_vendor/html5lib/serializer/__init__.pyc | Bin 0 -> 904 bytes .../html5lib/serializer/htmlserializer.pyc | Bin 0 -> 11481 bytes .../pip/_vendor/html5lib/tokenizer.pyc | Bin 0 -> 55403 bytes .../html5lib/treeadapters/__init__.pyc | Bin 0 -> 152 bytes .../pip/_vendor/html5lib/treeadapters/sax.pyc | Bin 0 -> 1735 bytes .../html5lib/treebuilders/__init__.pyc | Bin 0 -> 3419 bytes .../_vendor/html5lib/treebuilders/_base.pyc | Bin 0 -> 14889 bytes .../pip/_vendor/html5lib/treebuilders/dom.pyc | Bin 0 -> 11062 bytes .../_vendor/html5lib/treebuilders/etree.pyc | Bin 0 -> 15563 bytes .../html5lib/treebuilders/etree_lxml.pyc | Bin 0 -> 14788 bytes .../_vendor/html5lib/treewalkers/__init__.pyc | Bin 0 -> 2510 bytes .../_vendor/html5lib/treewalkers/_base.pyc | Bin 0 -> 8349 bytes .../pip/_vendor/html5lib/treewalkers/dom.pyc | Bin 0 -> 2201 bytes .../_vendor/html5lib/treewalkers/etree.pyc | Bin 0 -> 4461 bytes .../html5lib/treewalkers/genshistream.pyc | Bin 0 -> 2397 bytes .../html5lib/treewalkers/lxmletree.pyc | Bin 0 -> 8870 bytes .../_vendor/html5lib/treewalkers/pulldom.pyc | Bin 0 -> 2316 bytes .../pip/_vendor/html5lib/trie/__init__.pyc | Bin 0 -> 460 bytes .../pip/_vendor/html5lib/trie/_base.pyc | Bin 0 -> 1859 bytes .../pip/_vendor/html5lib/trie/datrie.pyc | Bin 0 -> 2977 bytes .../pip/_vendor/html5lib/trie/py.pyc | Bin 0 -> 3199 bytes .../pip/_vendor/html5lib/utils.pyc | Bin 0 -> 3432 bytes .../pip/_vendor/pkg_resources.pyc | Bin 0 -> 114459 bytes .../site-packages/pip/_vendor/re-vendor.pyc | Bin 0 -> 1396 bytes .../pip/_vendor/requests/__init__.pyc | Bin 0 -> 2603 bytes .../pip/_vendor/requests/adapters.pyc | Bin 0 -> 14350 bytes .../pip/_vendor/requests/api.pyc | Bin 0 -> 5551 bytes .../pip/_vendor/requests/auth.pyc | Bin 0 -> 7663 bytes .../pip/_vendor/requests/cacert.pem | 5026 +++++++++++++++++ .../pip/_vendor/requests/certs.pyc | Bin 0 -> 849 bytes .../pip/_vendor/requests/compat.pyc | Bin 0 -> 2608 bytes .../pip/_vendor/requests/cookies.pyc | Bin 0 -> 21748 bytes .../pip/_vendor/requests/exceptions.pyc | Bin 0 -> 4491 bytes .../pip/_vendor/requests/hooks.pyc | Bin 0 -> 1148 bytes .../pip/_vendor/requests/models.pyc | Bin 0 -> 25332 bytes .../pip/_vendor/requests/sessions.pyc | Bin 0 -> 19371 bytes .../pip/_vendor/requests/status_codes.pyc | Bin 0 -> 4556 bytes .../pip/_vendor/requests/structures.pyc | Bin 0 -> 7071 bytes .../pip/_vendor/requests/utils.pyc | Bin 0 -> 20475 bytes .../Lib/site-packages/pip/_vendor/six.pyc | Bin 0 -> 24370 bytes .../pip/backwardcompat/__init__.pyc | Bin 0 -> 5504 bytes .../Lib/site-packages/pip/basecommand.pyc | Bin 0 -> 6383 bytes .../Lib/site-packages/pip/baseparser.pyc | Bin 0 -> 10265 bytes .../Lib/site-packages/pip/cmdoptions.pyc | Bin 0 -> 8216 bytes .../site-packages/pip/commands/__init__.pyc | Bin 0 -> 2708 bytes .../Lib/site-packages/pip/commands/bundle.pyc | Bin 0 -> 2302 bytes .../site-packages/pip/commands/completion.pyc | Bin 0 -> 2457 bytes .../Lib/site-packages/pip/commands/freeze.pyc | Bin 0 -> 4615 bytes .../Lib/site-packages/pip/commands/help.pyc | Bin 0 -> 1346 bytes .../site-packages/pip/commands/install.pyc | Bin 0 -> 9923 bytes .../Lib/site-packages/pip/commands/list.pyc | Bin 0 -> 6653 bytes .../Lib/site-packages/pip/commands/search.pyc | Bin 0 -> 5536 bytes .../Lib/site-packages/pip/commands/show.pyc | Bin 0 -> 3457 bytes .../site-packages/pip/commands/uninstall.pyc | Bin 0 -> 2732 bytes .../Lib/site-packages/pip/commands/unzip.pyc | Bin 0 -> 589 bytes .../Lib/site-packages/pip/commands/wheel.pyc | Bin 0 -> 6130 bytes .../Lib/site-packages/pip/commands/zip.pyc | Bin 0 -> 12014 bytes PythonHome/Lib/site-packages/pip/download.pyc | Bin 0 -> 20848 bytes .../Lib/site-packages/pip/exceptions.pyc | Bin 0 -> 3167 bytes PythonHome/Lib/site-packages/pip/index.pyc | Bin 0 -> 33949 bytes .../Lib/site-packages/pip/locations.pyc | Bin 0 -> 5595 bytes PythonHome/Lib/site-packages/pip/log.pyc | Bin 0 -> 10140 bytes .../Lib/site-packages/pip/pep425tags.pyc | Bin 0 -> 3246 bytes PythonHome/Lib/site-packages/pip/req.pyc | Bin 0 -> 62014 bytes PythonHome/Lib/site-packages/pip/runner.pyc | Bin 0 -> 573 bytes .../Lib/site-packages/pip/status_codes.pyc | Bin 0 -> 349 bytes PythonHome/Lib/site-packages/pip/util.pyc | Bin 0 -> 26477 bytes .../Lib/site-packages/pip/vcs/__init__.pyc | Bin 0 -> 11238 bytes .../Lib/site-packages/pip/vcs/bazaar.pyc | Bin 0 -> 6081 bytes PythonHome/Lib/site-packages/pip/vcs/git.pyc | Bin 0 -> 8417 bytes .../Lib/site-packages/pip/vcs/mercurial.pyc | Bin 0 -> 6836 bytes .../Lib/site-packages/pip/vcs/subversion.pyc | Bin 0 -> 10370 bytes PythonHome/Lib/site-packages/pip/wheel.pyc | Bin 0 -> 18465 bytes .../Lib/site-packages/pkg_resources.pyc | Bin 0 -> 104832 bytes .../requests-2.3.0.dist-info/DESCRIPTION.rst | 889 +++ .../requests-2.3.0.dist-info/METADATA | 908 +++ .../requests-2.3.0.dist-info/RECORD | 163 + .../requests-2.3.0.dist-info/WHEEL | 6 + .../requests-2.3.0.dist-info/pydist.json | 1 + .../requests-2.3.0.dist-info/top_level.txt | 1 + .../Lib/site-packages/requests/__init__.pyc | Bin 0 -> 2600 bytes .../Lib/site-packages/requests/adapters.pyc | Bin 0 -> 14331 bytes PythonHome/Lib/site-packages/requests/api.pyc | Bin 0 -> 5542 bytes .../Lib/site-packages/requests/auth.pyc | Bin 0 -> 7646 bytes .../Lib/site-packages/requests/cacert.pem | 5026 +++++++++++++++++ .../Lib/site-packages/requests/certs.pyc | Bin 0 -> 847 bytes .../Lib/site-packages/requests/compat.pyc | Bin 0 -> 2607 bytes .../Lib/site-packages/requests/cookies.pyc | Bin 0 -> 21697 bytes .../Lib/site-packages/requests/exceptions.pyc | Bin 0 -> 4476 bytes .../Lib/site-packages/requests/hooks.pyc | Bin 0 -> 1145 bytes .../Lib/site-packages/requests/models.pyc | Bin 0 -> 25284 bytes .../Lib/site-packages/requests/sessions.pyc | Bin 0 -> 19342 bytes .../site-packages/requests/status_codes.pyc | Bin 0 -> 5954 bytes .../Lib/site-packages/requests/structures.pyc | Bin 0 -> 7047 bytes .../Lib/site-packages/requests/utils.pyc | Bin 0 -> 20442 bytes .../DESCRIPTION.rst | 2018 +++++++ .../setuptools-5.4.1.dist-info/METADATA | 2049 +++++++ .../setuptools-5.4.1.dist-info/RECORD | 150 + .../setuptools-5.4.1.dist-info/WHEEL | 6 + .../dependency_links.txt | 2 + .../entry_points.txt | 63 + .../setuptools-5.4.1.dist-info/pydist.json | 1 + .../setuptools-5.4.1.dist-info/top_level.txt | 4 + .../setuptools-5.4.1.dist-info/zip-safe | 1 + .../Lib/site-packages/setuptools/__init__.pyc | Bin 0 -> 7123 bytes .../site-packages/setuptools/archive_util.pyc | Bin 0 -> 6077 bytes .../setuptools/command/__init__.pyc | Bin 0 -> 818 bytes .../setuptools/command/alias.pyc | Bin 0 -> 2948 bytes .../setuptools/command/bdist_egg.pyc | Bin 0 -> 17465 bytes .../setuptools/command/bdist_rpm.pyc | Bin 0 -> 1862 bytes .../setuptools/command/bdist_wininst.pyc | Bin 0 -> 1150 bytes .../setuptools/command/build_ext.pyc | Bin 0 -> 10130 bytes .../setuptools/command/build_py.pyc | Bin 0 -> 8996 bytes .../setuptools/command/develop.pyc | Bin 0 -> 5739 bytes .../setuptools/command/easy_install.pyc | Bin 0 -> 70984 bytes .../setuptools/command/egg_info.pyc | Bin 0 -> 17590 bytes .../setuptools/command/install.pyc | Bin 0 -> 4823 bytes .../setuptools/command/install_egg_info.pyc | Bin 0 -> 5313 bytes .../setuptools/command/install_lib.pyc | Bin 0 -> 2744 bytes .../setuptools/command/install_scripts.pyc | Bin 0 -> 2547 bytes .../setuptools/command/launcher manifest.xml | 15 + .../setuptools/command/register.pyc | Bin 0 -> 671 bytes .../setuptools/command/rotate.pyc | Bin 0 -> 2885 bytes .../setuptools/command/saveopts.pyc | Bin 0 -> 1090 bytes .../setuptools/command/sdist.pyc | Bin 0 -> 8560 bytes .../setuptools/command/setopt.pyc | Bin 0 -> 5921 bytes .../site-packages/setuptools/command/test.pyc | Bin 0 -> 6399 bytes .../setuptools/command/upload_docs.pyc | Bin 0 -> 6898 bytes .../Lib/site-packages/setuptools/compat.pyc | Bin 0 -> 3411 bytes .../Lib/site-packages/setuptools/depends.pyc | Bin 0 -> 7019 bytes .../Lib/site-packages/setuptools/dist.pyc | Bin 0 -> 32446 bytes .../site-packages/setuptools/extension.pyc | Bin 0 -> 2442 bytes .../site-packages/setuptools/lib2to3_ex.pyc | Bin 0 -> 2887 bytes .../setuptools/package_index.pyc | Bin 0 -> 37678 bytes .../site-packages/setuptools/py26compat.pyc | Bin 0 -> 877 bytes .../site-packages/setuptools/py27compat.pyc | Bin 0 -> 704 bytes .../site-packages/setuptools/py31compat.pyc | Bin 0 -> 2299 bytes .../Lib/site-packages/setuptools/sandbox.pyc | Bin 0 -> 12603 bytes .../setuptools/script (dev).tmpl | 5 + .../Lib/site-packages/setuptools/script.tmpl | 3 + .../site-packages/setuptools/site-patch.pyc | Bin 0 -> 1713 bytes .../site-packages/setuptools/ssl_support.pyc | Bin 0 -> 7472 bytes .../site-packages/setuptools/svn_utils.pyc | Bin 0 -> 19506 bytes .../setuptools/unicode_utils.pyc | Bin 0 -> 1389 bytes .../Lib/site-packages/setuptools/version.pyc | Bin 0 -> 160 bytes PythonHome/Lib/site.pyc | Bin 0 -> 19035 bytes PythonHome/Lib/smtpd.pyc | Bin 0 -> 15426 bytes PythonHome/Lib/smtplib.pyc | Bin 0 -> 29134 bytes PythonHome/Lib/sndhdr.pyc | Bin 0 -> 7102 bytes PythonHome/Lib/socket.pyc | Bin 0 -> 15956 bytes PythonHome/Lib/sqlite3/__init__.pyc | Bin 0 -> 149 bytes PythonHome/Lib/sqlite3/dbapi2.pyc | Bin 0 -> 2573 bytes PythonHome/Lib/sqlite3/dump.pyc | Bin 0 -> 2026 bytes PythonHome/Lib/sre.pyc | Bin 0 -> 504 bytes PythonHome/Lib/sre_compile.pyc | Bin 0 -> 10909 bytes PythonHome/Lib/sre_constants.pyc | Bin 0 -> 6170 bytes PythonHome/Lib/sre_parse.pyc | Bin 0 -> 19314 bytes PythonHome/Lib/ssl.pyc | Bin 0 -> 14734 bytes PythonHome/Lib/stat.pyc | Bin 0 -> 2701 bytes PythonHome/Lib/statvfs.pyc | Bin 0 -> 605 bytes PythonHome/Lib/string.pyc | Bin 0 -> 19753 bytes PythonHome/Lib/stringold.pyc | Bin 0 -> 12144 bytes PythonHome/Lib/stringprep.pyc | Bin 0 -> 14387 bytes PythonHome/Lib/struct.pyc | Bin 0 -> 234 bytes PythonHome/Lib/subprocess.pyc | Bin 0 -> 41615 bytes PythonHome/Lib/sunau.pyc | Bin 0 -> 17685 bytes PythonHome/Lib/sunaudio.pyc | Bin 0 -> 1912 bytes PythonHome/Lib/symbol.pyc | Bin 0 -> 3016 bytes PythonHome/Lib/symtable.pyc | Bin 0 -> 11036 bytes PythonHome/Lib/sysconfig.pyc | Bin 0 -> 17350 bytes PythonHome/Lib/tabnanny.pyc | Bin 0 -> 7943 bytes PythonHome/Lib/tarfile.pyc | Bin 0 -> 74351 bytes PythonHome/Lib/telnetlib.pyc | Bin 0 -> 22638 bytes PythonHome/Lib/tempfile.pyc | Bin 0 -> 19647 bytes PythonHome/Lib/textwrap.pyc | Bin 0 -> 11829 bytes PythonHome/Lib/this.pyc | Bin 0 -> 1205 bytes PythonHome/Lib/threading.pyc | Bin 0 -> 42118 bytes PythonHome/Lib/timeit.pyc | Bin 0 -> 11578 bytes PythonHome/Lib/toaiff.pyc | Bin 0 -> 3046 bytes PythonHome/Lib/token.pyc | Bin 0 -> 3791 bytes PythonHome/Lib/tokenize.pyc | Bin 0 -> 14142 bytes PythonHome/Lib/trace.pyc | Bin 0 -> 22282 bytes PythonHome/Lib/traceback.pyc | Bin 0 -> 11579 bytes PythonHome/Lib/tty.pyc | Bin 0 -> 1272 bytes PythonHome/Lib/types.pyc | Bin 0 -> 2476 bytes PythonHome/Lib/unittest/__init__.pyc | Bin 0 -> 2949 bytes PythonHome/Lib/unittest/__main__.pyc | Bin 0 -> 473 bytes PythonHome/Lib/unittest/case.pyc | Bin 0 -> 38986 bytes PythonHome/Lib/unittest/loader.pyc | Bin 0 -> 11050 bytes PythonHome/Lib/unittest/main.pyc | Bin 0 -> 7876 bytes PythonHome/Lib/unittest/result.pyc | Bin 0 -> 7564 bytes PythonHome/Lib/unittest/runner.pyc | Bin 0 -> 7334 bytes PythonHome/Lib/unittest/signals.pyc | Bin 0 -> 2616 bytes PythonHome/Lib/unittest/suite.pyc | Bin 0 -> 10013 bytes PythonHome/Lib/unittest/util.pyc | Bin 0 -> 4398 bytes PythonHome/Lib/urllib.pyc | Bin 0 -> 49747 bytes PythonHome/Lib/urllib2.pyc | Bin 0 -> 46168 bytes PythonHome/Lib/urlparse.pyc | Bin 0 -> 14386 bytes PythonHome/Lib/user.pyc | Bin 0 -> 1709 bytes PythonHome/Lib/uu.pyc | Bin 0 -> 4287 bytes PythonHome/Lib/uuid.pyc | Bin 0 -> 21299 bytes PythonHome/Lib/warnings.pyc | Bin 0 -> 13025 bytes PythonHome/Lib/wave.pyc | Bin 0 -> 19235 bytes PythonHome/Lib/weakref.pyc | Bin 0 -> 15095 bytes PythonHome/Lib/webbrowser.pyc | Bin 0 -> 19104 bytes PythonHome/Lib/whichdb.pyc | Bin 0 -> 2211 bytes PythonHome/Lib/wsgiref/__init__.pyc | Bin 0 -> 714 bytes PythonHome/Lib/wsgiref/handlers.pyc | Bin 0 -> 15699 bytes PythonHome/Lib/wsgiref/headers.pyc | Bin 0 -> 7203 bytes PythonHome/Lib/wsgiref/simple_server.pyc | Bin 0 -> 5876 bytes PythonHome/Lib/wsgiref/util.pyc | Bin 0 -> 5813 bytes PythonHome/Lib/wsgiref/validate.pyc | Bin 0 -> 16252 bytes PythonHome/Lib/xdrlib.pyc | Bin 0 -> 8688 bytes PythonHome/Lib/xml/__init__.pyc | Bin 0 -> 1073 bytes PythonHome/Lib/xml/dom/NodeFilter.pyc | Bin 0 -> 1081 bytes PythonHome/Lib/xml/dom/__init__.pyc | Bin 0 -> 6149 bytes PythonHome/Lib/xml/dom/domreg.pyc | Bin 0 -> 3236 bytes PythonHome/Lib/xml/dom/expatbuilder.pyc | Bin 0 -> 31853 bytes PythonHome/Lib/xml/dom/minicompat.pyc | Bin 0 -> 3334 bytes PythonHome/Lib/xml/dom/minidom.pyc | Bin 0 -> 62271 bytes PythonHome/Lib/xml/dom/pulldom.pyc | Bin 0 -> 12448 bytes PythonHome/Lib/xml/dom/xmlbuilder.pyc | Bin 0 -> 15689 bytes PythonHome/Lib/xml/etree/ElementInclude.pyc | Bin 0 -> 1907 bytes PythonHome/Lib/xml/etree/ElementPath.pyc | Bin 0 -> 7491 bytes PythonHome/Lib/xml/etree/ElementTree.pyc | Bin 0 -> 34357 bytes PythonHome/Lib/xml/etree/__init__.pyc | Bin 0 -> 124 bytes PythonHome/Lib/xml/etree/cElementTree.pyc | Bin 0 -> 171 bytes PythonHome/Lib/xml/parsers/__init__.pyc | Bin 0 -> 309 bytes PythonHome/Lib/xml/parsers/expat.pyc | Bin 0 -> 282 bytes PythonHome/Lib/xml/sax/__init__.pyc | Bin 0 -> 3669 bytes PythonHome/Lib/xml/sax/_exceptions.pyc | Bin 0 -> 6084 bytes PythonHome/Lib/xml/sax/expatreader.pyc | Bin 0 -> 13861 bytes PythonHome/Lib/xml/sax/handler.pyc | Bin 0 -> 12903 bytes PythonHome/Lib/xml/sax/saxutils.pyc | Bin 0 -> 14542 bytes PythonHome/Lib/xml/sax/xmlreader.pyc | Bin 0 -> 18882 bytes PythonHome/Lib/xmllib.pyc | Bin 0 -> 26037 bytes PythonHome/Lib/xmlrpclib.pyc | Bin 0 -> 42804 bytes PythonHome/Lib/zipfile.pyc | Bin 0 -> 41193 bytes Wox.Plugin/AllowedLanguage.cs | 10 +- .../{BasePluginWrapper.cs => BasePlugin.cs} | 10 +- Wox/PluginLoader/BasePluginLoader.cs | 2 +- ...nConfigLoader.cs => CSharpPluginLoader.cs} | 2 +- Wox/PluginLoader/Plugins.cs | 4 +- ...PythonPluginWrapper.cs => PythonPlugin.cs} | 10 +- Wox/RPC/2obywmlm.f50 | 21 + Wox/RPC/JsonPRCModel.cs | 34 +- Wox/RPC/JsonRPC.cs | 5 +- Wox/RPC/tr3fzfc4.och | 56 + Wox/Wox.csproj | 6 +- 893 files changed, 19533 insertions(+), 42 deletions(-) create mode 100644 PythonHome/DLLs/py.ico create mode 100644 PythonHome/DLLs/pyc.ico create mode 100644 PythonHome/Lib/BaseHTTPServer.pyc create mode 100644 PythonHome/Lib/Bastion.pyc create mode 100644 PythonHome/Lib/CGIHTTPServer.pyc create mode 100644 PythonHome/Lib/ConfigParser.pyc create mode 100644 PythonHome/Lib/Cookie.pyc create mode 100644 PythonHome/Lib/DocXMLRPCServer.pyc create mode 100644 PythonHome/Lib/HTMLParser.pyc create mode 100644 PythonHome/Lib/MimeWriter.pyc create mode 100644 PythonHome/Lib/Queue.pyc create mode 100644 PythonHome/Lib/SimpleHTTPServer.pyc create mode 100644 PythonHome/Lib/SimpleXMLRPCServer.pyc create mode 100644 PythonHome/Lib/SocketServer.pyc create mode 100644 PythonHome/Lib/StringIO.pyc create mode 100644 PythonHome/Lib/UserDict.pyc create mode 100644 PythonHome/Lib/UserList.pyc create mode 100644 PythonHome/Lib/UserString.pyc create mode 100644 PythonHome/Lib/_LWPCookieJar.pyc create mode 100644 PythonHome/Lib/_MozillaCookieJar.pyc create mode 100644 PythonHome/Lib/__future__.pyc create mode 100644 PythonHome/Lib/__phello__.foo.pyc create mode 100644 PythonHome/Lib/_abcoll.pyc create mode 100644 PythonHome/Lib/_osx_support.pyc create mode 100644 PythonHome/Lib/_pyio.pyc create mode 100644 PythonHome/Lib/_strptime.pyc create mode 100644 PythonHome/Lib/_threading_local.pyc create mode 100644 PythonHome/Lib/_weakrefset.pyc create mode 100644 PythonHome/Lib/abc.pyc create mode 100644 PythonHome/Lib/aifc.pyc create mode 100644 PythonHome/Lib/antigravity.pyc create mode 100644 PythonHome/Lib/anydbm.pyc create mode 100644 PythonHome/Lib/argparse.pyc create mode 100644 PythonHome/Lib/ast.pyc create mode 100644 PythonHome/Lib/asynchat.pyc create mode 100644 PythonHome/Lib/asyncore.pyc create mode 100644 PythonHome/Lib/atexit.pyc create mode 100644 PythonHome/Lib/audiodev.pyc create mode 100644 PythonHome/Lib/base64.pyc create mode 100644 PythonHome/Lib/bdb.pyc create mode 100644 PythonHome/Lib/binhex.pyc create mode 100644 PythonHome/Lib/bisect.pyc create mode 100644 PythonHome/Lib/bsddb/__init__.pyc create mode 100644 PythonHome/Lib/bsddb/db.pyc create mode 100644 PythonHome/Lib/bsddb/dbobj.pyc create mode 100644 PythonHome/Lib/bsddb/dbrecio.pyc create mode 100644 PythonHome/Lib/bsddb/dbshelve.pyc create mode 100644 PythonHome/Lib/bsddb/dbtables.pyc create mode 100644 PythonHome/Lib/bsddb/dbutils.pyc create mode 100644 PythonHome/Lib/cProfile.pyc create mode 100644 PythonHome/Lib/calendar.pyc create mode 100644 PythonHome/Lib/cgi.pyc create mode 100644 PythonHome/Lib/cgitb.pyc create mode 100644 PythonHome/Lib/chunk.pyc create mode 100644 PythonHome/Lib/cmd.pyc create mode 100644 PythonHome/Lib/code.pyc create mode 100644 PythonHome/Lib/codecs.pyc create mode 100644 PythonHome/Lib/codeop.pyc create mode 100644 PythonHome/Lib/collections.pyc create mode 100644 PythonHome/Lib/colorsys.pyc create mode 100644 PythonHome/Lib/commands.pyc create mode 100644 PythonHome/Lib/compileall.pyc create mode 100644 PythonHome/Lib/compiler/__init__.pyc create mode 100644 PythonHome/Lib/compiler/ast.pyc create mode 100644 PythonHome/Lib/compiler/consts.pyc create mode 100644 PythonHome/Lib/compiler/future.pyc create mode 100644 PythonHome/Lib/compiler/misc.pyc create mode 100644 PythonHome/Lib/compiler/pyassem.pyc create mode 100644 PythonHome/Lib/compiler/pycodegen.pyc create mode 100644 PythonHome/Lib/compiler/symbols.pyc create mode 100644 PythonHome/Lib/compiler/syntax.pyc create mode 100644 PythonHome/Lib/compiler/transformer.pyc create mode 100644 PythonHome/Lib/compiler/visitor.pyc create mode 100644 PythonHome/Lib/contextlib.pyc create mode 100644 PythonHome/Lib/cookielib.pyc create mode 100644 PythonHome/Lib/copy.pyc create mode 100644 PythonHome/Lib/copy_reg.pyc create mode 100644 PythonHome/Lib/csv.pyc create mode 100644 PythonHome/Lib/ctypes/__init__.pyc create mode 100644 PythonHome/Lib/ctypes/_endian.pyc create mode 100644 PythonHome/Lib/ctypes/macholib/__init__.pyc create mode 100644 PythonHome/Lib/ctypes/macholib/dyld.pyc create mode 100644 PythonHome/Lib/ctypes/macholib/dylib.pyc create mode 100644 PythonHome/Lib/ctypes/macholib/framework.pyc create mode 100644 PythonHome/Lib/ctypes/util.pyc create mode 100644 PythonHome/Lib/ctypes/wintypes.pyc create mode 100644 PythonHome/Lib/curses/__init__.pyc create mode 100644 PythonHome/Lib/curses/ascii.pyc create mode 100644 PythonHome/Lib/curses/has_key.pyc create mode 100644 PythonHome/Lib/curses/panel.pyc create mode 100644 PythonHome/Lib/curses/textpad.pyc create mode 100644 PythonHome/Lib/curses/wrapper.pyc create mode 100644 PythonHome/Lib/dbhash.pyc create mode 100644 PythonHome/Lib/decimal.pyc create mode 100644 PythonHome/Lib/difflib.pyc create mode 100644 PythonHome/Lib/dircache.pyc create mode 100644 PythonHome/Lib/dis.pyc create mode 100644 PythonHome/Lib/distutils/__init__.pyc create mode 100644 PythonHome/Lib/distutils/archive_util.pyc create mode 100644 PythonHome/Lib/distutils/bcppcompiler.pyc create mode 100644 PythonHome/Lib/distutils/ccompiler.pyc create mode 100644 PythonHome/Lib/distutils/cmd.pyc create mode 100644 PythonHome/Lib/distutils/command/__init__.pyc create mode 100644 PythonHome/Lib/distutils/command/bdist.pyc create mode 100644 PythonHome/Lib/distutils/command/bdist_dumb.pyc create mode 100644 PythonHome/Lib/distutils/command/bdist_msi.pyc create mode 100644 PythonHome/Lib/distutils/command/bdist_rpm.pyc create mode 100644 PythonHome/Lib/distutils/command/bdist_wininst.pyc create mode 100644 PythonHome/Lib/distutils/command/build.pyc create mode 100644 PythonHome/Lib/distutils/command/build_clib.pyc create mode 100644 PythonHome/Lib/distutils/command/build_ext.pyc create mode 100644 PythonHome/Lib/distutils/command/build_py.pyc create mode 100644 PythonHome/Lib/distutils/command/build_scripts.pyc create mode 100644 PythonHome/Lib/distutils/command/check.pyc create mode 100644 PythonHome/Lib/distutils/command/clean.pyc create mode 100644 PythonHome/Lib/distutils/command/config.pyc create mode 100644 PythonHome/Lib/distutils/command/install.pyc create mode 100644 PythonHome/Lib/distutils/command/install_data.pyc create mode 100644 PythonHome/Lib/distutils/command/install_egg_info.pyc create mode 100644 PythonHome/Lib/distutils/command/install_headers.pyc create mode 100644 PythonHome/Lib/distutils/command/install_lib.pyc create mode 100644 PythonHome/Lib/distutils/command/install_scripts.pyc create mode 100644 PythonHome/Lib/distutils/command/register.pyc create mode 100644 PythonHome/Lib/distutils/command/sdist.pyc create mode 100644 PythonHome/Lib/distutils/command/upload.pyc create mode 100644 PythonHome/Lib/distutils/config.pyc create mode 100644 PythonHome/Lib/distutils/core.pyc create mode 100644 PythonHome/Lib/distutils/cygwinccompiler.pyc create mode 100644 PythonHome/Lib/distutils/debug.pyc create mode 100644 PythonHome/Lib/distutils/dep_util.pyc create mode 100644 PythonHome/Lib/distutils/dir_util.pyc create mode 100644 PythonHome/Lib/distutils/dist.pyc create mode 100644 PythonHome/Lib/distutils/emxccompiler.pyc create mode 100644 PythonHome/Lib/distutils/errors.pyc create mode 100644 PythonHome/Lib/distutils/extension.pyc create mode 100644 PythonHome/Lib/distutils/fancy_getopt.pyc create mode 100644 PythonHome/Lib/distutils/file_util.pyc create mode 100644 PythonHome/Lib/distutils/filelist.pyc create mode 100644 PythonHome/Lib/distutils/log.pyc create mode 100644 PythonHome/Lib/distutils/msvc9compiler.pyc create mode 100644 PythonHome/Lib/distutils/msvccompiler.pyc create mode 100644 PythonHome/Lib/distutils/spawn.pyc create mode 100644 PythonHome/Lib/distutils/sysconfig.pyc create mode 100644 PythonHome/Lib/distutils/text_file.pyc create mode 100644 PythonHome/Lib/distutils/unixccompiler.pyc create mode 100644 PythonHome/Lib/distutils/util.pyc create mode 100644 PythonHome/Lib/distutils/version.pyc create mode 100644 PythonHome/Lib/distutils/versionpredicate.pyc create mode 100644 PythonHome/Lib/doctest.pyc create mode 100644 PythonHome/Lib/dumbdbm.pyc create mode 100644 PythonHome/Lib/dummy_thread.pyc create mode 100644 PythonHome/Lib/dummy_threading.pyc create mode 100644 PythonHome/Lib/email/__init__.pyc create mode 100644 PythonHome/Lib/email/_parseaddr.pyc create mode 100644 PythonHome/Lib/email/base64mime.pyc create mode 100644 PythonHome/Lib/email/charset.pyc create mode 100644 PythonHome/Lib/email/encoders.pyc create mode 100644 PythonHome/Lib/email/errors.pyc create mode 100644 PythonHome/Lib/email/feedparser.pyc create mode 100644 PythonHome/Lib/email/generator.pyc create mode 100644 PythonHome/Lib/email/header.pyc create mode 100644 PythonHome/Lib/email/iterators.pyc create mode 100644 PythonHome/Lib/email/message.pyc create mode 100644 PythonHome/Lib/email/mime/__init__.pyc create mode 100644 PythonHome/Lib/email/mime/application.pyc create mode 100644 PythonHome/Lib/email/mime/audio.pyc create mode 100644 PythonHome/Lib/email/mime/base.pyc create mode 100644 PythonHome/Lib/email/mime/image.pyc create mode 100644 PythonHome/Lib/email/mime/message.pyc create mode 100644 PythonHome/Lib/email/mime/multipart.pyc create mode 100644 PythonHome/Lib/email/mime/nonmultipart.pyc create mode 100644 PythonHome/Lib/email/mime/text.pyc create mode 100644 PythonHome/Lib/email/parser.pyc create mode 100644 PythonHome/Lib/email/quoprimime.pyc create mode 100644 PythonHome/Lib/email/utils.pyc create mode 100644 PythonHome/Lib/encodings/__init__.pyc create mode 100644 PythonHome/Lib/encodings/aliases.pyc create mode 100644 PythonHome/Lib/encodings/ascii.pyc create mode 100644 PythonHome/Lib/encodings/base64_codec.pyc create mode 100644 PythonHome/Lib/encodings/big5.pyc create mode 100644 PythonHome/Lib/encodings/big5hkscs.pyc create mode 100644 PythonHome/Lib/encodings/bz2_codec.pyc create mode 100644 PythonHome/Lib/encodings/charmap.pyc create mode 100644 PythonHome/Lib/encodings/cp037.pyc create mode 100644 PythonHome/Lib/encodings/cp1006.pyc create mode 100644 PythonHome/Lib/encodings/cp1026.pyc create mode 100644 PythonHome/Lib/encodings/cp1140.pyc create mode 100644 PythonHome/Lib/encodings/cp1250.pyc create mode 100644 PythonHome/Lib/encodings/cp1251.pyc create mode 100644 PythonHome/Lib/encodings/cp1252.pyc create mode 100644 PythonHome/Lib/encodings/cp1253.pyc create mode 100644 PythonHome/Lib/encodings/cp1254.pyc create mode 100644 PythonHome/Lib/encodings/cp1255.pyc create mode 100644 PythonHome/Lib/encodings/cp1256.pyc create mode 100644 PythonHome/Lib/encodings/cp1257.pyc create mode 100644 PythonHome/Lib/encodings/cp1258.pyc create mode 100644 PythonHome/Lib/encodings/cp424.pyc create mode 100644 PythonHome/Lib/encodings/cp437.pyc create mode 100644 PythonHome/Lib/encodings/cp500.pyc create mode 100644 PythonHome/Lib/encodings/cp720.pyc create mode 100644 PythonHome/Lib/encodings/cp737.pyc create mode 100644 PythonHome/Lib/encodings/cp775.pyc create mode 100644 PythonHome/Lib/encodings/cp850.pyc create mode 100644 PythonHome/Lib/encodings/cp852.pyc create mode 100644 PythonHome/Lib/encodings/cp855.pyc create mode 100644 PythonHome/Lib/encodings/cp856.pyc create mode 100644 PythonHome/Lib/encodings/cp857.pyc create mode 100644 PythonHome/Lib/encodings/cp858.pyc create mode 100644 PythonHome/Lib/encodings/cp860.pyc create mode 100644 PythonHome/Lib/encodings/cp861.pyc create mode 100644 PythonHome/Lib/encodings/cp862.pyc create mode 100644 PythonHome/Lib/encodings/cp863.pyc create mode 100644 PythonHome/Lib/encodings/cp864.pyc create mode 100644 PythonHome/Lib/encodings/cp865.pyc create mode 100644 PythonHome/Lib/encodings/cp866.pyc create mode 100644 PythonHome/Lib/encodings/cp869.pyc create mode 100644 PythonHome/Lib/encodings/cp874.pyc create mode 100644 PythonHome/Lib/encodings/cp875.pyc create mode 100644 PythonHome/Lib/encodings/cp932.pyc create mode 100644 PythonHome/Lib/encodings/cp949.pyc create mode 100644 PythonHome/Lib/encodings/cp950.pyc create mode 100644 PythonHome/Lib/encodings/euc_jis_2004.pyc create mode 100644 PythonHome/Lib/encodings/euc_jisx0213.pyc create mode 100644 PythonHome/Lib/encodings/euc_jp.pyc create mode 100644 PythonHome/Lib/encodings/euc_kr.pyc create mode 100644 PythonHome/Lib/encodings/gb18030.pyc create mode 100644 PythonHome/Lib/encodings/gb2312.pyc create mode 100644 PythonHome/Lib/encodings/gbk.pyc create mode 100644 PythonHome/Lib/encodings/hex_codec.pyc create mode 100644 PythonHome/Lib/encodings/hp_roman8.pyc create mode 100644 PythonHome/Lib/encodings/hz.pyc create mode 100644 PythonHome/Lib/encodings/idna.pyc create mode 100644 PythonHome/Lib/encodings/iso2022_jp.pyc create mode 100644 PythonHome/Lib/encodings/iso2022_jp_1.pyc create mode 100644 PythonHome/Lib/encodings/iso2022_jp_2.pyc create mode 100644 PythonHome/Lib/encodings/iso2022_jp_2004.pyc create mode 100644 PythonHome/Lib/encodings/iso2022_jp_3.pyc create mode 100644 PythonHome/Lib/encodings/iso2022_jp_ext.pyc create mode 100644 PythonHome/Lib/encodings/iso2022_kr.pyc create mode 100644 PythonHome/Lib/encodings/iso8859_1.pyc create mode 100644 PythonHome/Lib/encodings/iso8859_10.pyc create mode 100644 PythonHome/Lib/encodings/iso8859_11.pyc create mode 100644 PythonHome/Lib/encodings/iso8859_13.pyc create mode 100644 PythonHome/Lib/encodings/iso8859_14.pyc create mode 100644 PythonHome/Lib/encodings/iso8859_15.pyc create mode 100644 PythonHome/Lib/encodings/iso8859_16.pyc create mode 100644 PythonHome/Lib/encodings/iso8859_2.pyc create mode 100644 PythonHome/Lib/encodings/iso8859_3.pyc create mode 100644 PythonHome/Lib/encodings/iso8859_4.pyc create mode 100644 PythonHome/Lib/encodings/iso8859_5.pyc create mode 100644 PythonHome/Lib/encodings/iso8859_6.pyc create mode 100644 PythonHome/Lib/encodings/iso8859_7.pyc create mode 100644 PythonHome/Lib/encodings/iso8859_8.pyc create mode 100644 PythonHome/Lib/encodings/iso8859_9.pyc create mode 100644 PythonHome/Lib/encodings/johab.pyc create mode 100644 PythonHome/Lib/encodings/koi8_r.pyc create mode 100644 PythonHome/Lib/encodings/koi8_u.pyc create mode 100644 PythonHome/Lib/encodings/latin_1.pyc create mode 100644 PythonHome/Lib/encodings/mac_arabic.pyc create mode 100644 PythonHome/Lib/encodings/mac_centeuro.pyc create mode 100644 PythonHome/Lib/encodings/mac_croatian.pyc create mode 100644 PythonHome/Lib/encodings/mac_cyrillic.pyc create mode 100644 PythonHome/Lib/encodings/mac_farsi.pyc create mode 100644 PythonHome/Lib/encodings/mac_greek.pyc create mode 100644 PythonHome/Lib/encodings/mac_iceland.pyc create mode 100644 PythonHome/Lib/encodings/mac_latin2.pyc create mode 100644 PythonHome/Lib/encodings/mac_roman.pyc create mode 100644 PythonHome/Lib/encodings/mac_romanian.pyc create mode 100644 PythonHome/Lib/encodings/mac_turkish.pyc create mode 100644 PythonHome/Lib/encodings/mbcs.pyc create mode 100644 PythonHome/Lib/encodings/palmos.pyc create mode 100644 PythonHome/Lib/encodings/ptcp154.pyc create mode 100644 PythonHome/Lib/encodings/punycode.pyc create mode 100644 PythonHome/Lib/encodings/quopri_codec.pyc create mode 100644 PythonHome/Lib/encodings/raw_unicode_escape.pyc create mode 100644 PythonHome/Lib/encodings/rot_13.pyc create mode 100644 PythonHome/Lib/encodings/shift_jis.pyc create mode 100644 PythonHome/Lib/encodings/shift_jis_2004.pyc create mode 100644 PythonHome/Lib/encodings/shift_jisx0213.pyc create mode 100644 PythonHome/Lib/encodings/string_escape.pyc create mode 100644 PythonHome/Lib/encodings/tis_620.pyc create mode 100644 PythonHome/Lib/encodings/undefined.pyc create mode 100644 PythonHome/Lib/encodings/unicode_escape.pyc create mode 100644 PythonHome/Lib/encodings/unicode_internal.pyc create mode 100644 PythonHome/Lib/encodings/utf_16.pyc create mode 100644 PythonHome/Lib/encodings/utf_16_be.pyc create mode 100644 PythonHome/Lib/encodings/utf_16_le.pyc create mode 100644 PythonHome/Lib/encodings/utf_32.pyc create mode 100644 PythonHome/Lib/encodings/utf_32_be.pyc create mode 100644 PythonHome/Lib/encodings/utf_32_le.pyc create mode 100644 PythonHome/Lib/encodings/utf_7.pyc create mode 100644 PythonHome/Lib/encodings/utf_8.pyc create mode 100644 PythonHome/Lib/encodings/utf_8_sig.pyc create mode 100644 PythonHome/Lib/encodings/uu_codec.pyc create mode 100644 PythonHome/Lib/encodings/zlib_codec.pyc create mode 100644 PythonHome/Lib/filecmp.pyc create mode 100644 PythonHome/Lib/fileinput.pyc create mode 100644 PythonHome/Lib/fnmatch.pyc create mode 100644 PythonHome/Lib/formatter.pyc create mode 100644 PythonHome/Lib/fpformat.pyc create mode 100644 PythonHome/Lib/fractions.pyc create mode 100644 PythonHome/Lib/ftplib.pyc create mode 100644 PythonHome/Lib/functools.pyc create mode 100644 PythonHome/Lib/genericpath.pyc create mode 100644 PythonHome/Lib/getopt.pyc create mode 100644 PythonHome/Lib/getpass.pyc create mode 100644 PythonHome/Lib/gettext.pyc create mode 100644 PythonHome/Lib/glob.pyc create mode 100644 PythonHome/Lib/gzip.pyc create mode 100644 PythonHome/Lib/hashlib.pyc create mode 100644 PythonHome/Lib/heapq.pyc create mode 100644 PythonHome/Lib/hmac.pyc create mode 100644 PythonHome/Lib/hotshot/__init__.pyc create mode 100644 PythonHome/Lib/hotshot/log.pyc create mode 100644 PythonHome/Lib/hotshot/stats.pyc create mode 100644 PythonHome/Lib/hotshot/stones.pyc create mode 100644 PythonHome/Lib/htmlentitydefs.pyc create mode 100644 PythonHome/Lib/htmllib.pyc create mode 100644 PythonHome/Lib/httplib.pyc create mode 100644 PythonHome/Lib/idlelib/AutoComplete.pyc create mode 100644 PythonHome/Lib/idlelib/AutoCompleteWindow.pyc create mode 100644 PythonHome/Lib/idlelib/AutoExpand.pyc create mode 100644 PythonHome/Lib/idlelib/Bindings.pyc create mode 100644 PythonHome/Lib/idlelib/CREDITS.txt create mode 100644 PythonHome/Lib/idlelib/CallTipWindow.pyc create mode 100644 PythonHome/Lib/idlelib/CallTips.pyc create mode 100644 PythonHome/Lib/idlelib/ClassBrowser.pyc create mode 100644 PythonHome/Lib/idlelib/CodeContext.pyc create mode 100644 PythonHome/Lib/idlelib/ColorDelegator.pyc create mode 100644 PythonHome/Lib/idlelib/Debugger.pyc create mode 100644 PythonHome/Lib/idlelib/Delegator.pyc create mode 100644 PythonHome/Lib/idlelib/EditorWindow.pyc create mode 100644 PythonHome/Lib/idlelib/FileList.pyc create mode 100644 PythonHome/Lib/idlelib/FormatParagraph.pyc create mode 100644 PythonHome/Lib/idlelib/GrepDialog.pyc create mode 100644 PythonHome/Lib/idlelib/HISTORY.txt create mode 100644 PythonHome/Lib/idlelib/HyperParser.pyc create mode 100644 PythonHome/Lib/idlelib/IOBinding.pyc create mode 100644 PythonHome/Lib/idlelib/Icons/folder.gif create mode 100644 PythonHome/Lib/idlelib/Icons/idle.icns create mode 100644 PythonHome/Lib/idlelib/Icons/idle.ico create mode 100644 PythonHome/Lib/idlelib/Icons/idle_16.gif create mode 100644 PythonHome/Lib/idlelib/Icons/idle_32.gif create mode 100644 PythonHome/Lib/idlelib/Icons/idle_48.gif create mode 100644 PythonHome/Lib/idlelib/Icons/minusnode.gif create mode 100644 PythonHome/Lib/idlelib/Icons/openfolder.gif create mode 100644 PythonHome/Lib/idlelib/Icons/plusnode.gif create mode 100644 PythonHome/Lib/idlelib/Icons/python.gif create mode 100644 PythonHome/Lib/idlelib/Icons/tk.gif create mode 100644 PythonHome/Lib/idlelib/IdleHistory.pyc create mode 100644 PythonHome/Lib/idlelib/MultiCall.pyc create mode 100644 PythonHome/Lib/idlelib/MultiStatusBar.pyc create mode 100644 PythonHome/Lib/idlelib/NEWS.txt create mode 100644 PythonHome/Lib/idlelib/ObjectBrowser.pyc create mode 100644 PythonHome/Lib/idlelib/OutputWindow.pyc create mode 100644 PythonHome/Lib/idlelib/ParenMatch.pyc create mode 100644 PythonHome/Lib/idlelib/PathBrowser.pyc create mode 100644 PythonHome/Lib/idlelib/Percolator.pyc create mode 100644 PythonHome/Lib/idlelib/PyParse.pyc create mode 100644 PythonHome/Lib/idlelib/PyShell.pyc create mode 100644 PythonHome/Lib/idlelib/README.txt create mode 100644 PythonHome/Lib/idlelib/RemoteDebugger.pyc create mode 100644 PythonHome/Lib/idlelib/RemoteObjectBrowser.pyc create mode 100644 PythonHome/Lib/idlelib/ReplaceDialog.pyc create mode 100644 PythonHome/Lib/idlelib/RstripExtension.pyc create mode 100644 PythonHome/Lib/idlelib/ScriptBinding.pyc create mode 100644 PythonHome/Lib/idlelib/ScrolledList.pyc create mode 100644 PythonHome/Lib/idlelib/SearchDialog.pyc create mode 100644 PythonHome/Lib/idlelib/SearchDialogBase.pyc create mode 100644 PythonHome/Lib/idlelib/SearchEngine.pyc create mode 100644 PythonHome/Lib/idlelib/StackViewer.pyc create mode 100644 PythonHome/Lib/idlelib/TODO.txt create mode 100644 PythonHome/Lib/idlelib/ToolTip.pyc create mode 100644 PythonHome/Lib/idlelib/TreeWidget.pyc create mode 100644 PythonHome/Lib/idlelib/UndoDelegator.pyc create mode 100644 PythonHome/Lib/idlelib/WidgetRedirector.pyc create mode 100644 PythonHome/Lib/idlelib/WindowList.pyc create mode 100644 PythonHome/Lib/idlelib/ZoomHeight.pyc create mode 100644 PythonHome/Lib/idlelib/__init__.pyc create mode 100644 PythonHome/Lib/idlelib/aboutDialog.pyc create mode 100644 PythonHome/Lib/idlelib/config-extensions.def create mode 100644 PythonHome/Lib/idlelib/config-highlight.def create mode 100644 PythonHome/Lib/idlelib/config-keys.def create mode 100644 PythonHome/Lib/idlelib/config-main.def create mode 100644 PythonHome/Lib/idlelib/configDialog.pyc create mode 100644 PythonHome/Lib/idlelib/configHandler.pyc create mode 100644 PythonHome/Lib/idlelib/configHelpSourceEdit.pyc create mode 100644 PythonHome/Lib/idlelib/configSectionNameDialog.pyc create mode 100644 PythonHome/Lib/idlelib/dynOptionMenuWidget.pyc create mode 100644 PythonHome/Lib/idlelib/extend.txt create mode 100644 PythonHome/Lib/idlelib/help.txt create mode 100644 PythonHome/Lib/idlelib/idle.bat create mode 100644 PythonHome/Lib/idlelib/idle.pyc create mode 100644 PythonHome/Lib/idlelib/idle.pyw create mode 100644 PythonHome/Lib/idlelib/idlever.pyc create mode 100644 PythonHome/Lib/idlelib/keybindingDialog.pyc create mode 100644 PythonHome/Lib/idlelib/macosxSupport.pyc create mode 100644 PythonHome/Lib/idlelib/rpc.pyc create mode 100644 PythonHome/Lib/idlelib/run.pyc create mode 100644 PythonHome/Lib/idlelib/tabbedpages.pyc create mode 100644 PythonHome/Lib/idlelib/testcode.pyc create mode 100644 PythonHome/Lib/idlelib/textView.pyc create mode 100644 PythonHome/Lib/ihooks.pyc create mode 100644 PythonHome/Lib/imaplib.pyc create mode 100644 PythonHome/Lib/imghdr.pyc create mode 100644 PythonHome/Lib/importlib/__init__.pyc create mode 100644 PythonHome/Lib/imputil.pyc create mode 100644 PythonHome/Lib/inspect.pyc create mode 100644 PythonHome/Lib/io.pyc create mode 100644 PythonHome/Lib/json/__init__.pyc create mode 100644 PythonHome/Lib/json/decoder.pyc create mode 100644 PythonHome/Lib/json/encoder.pyc create mode 100644 PythonHome/Lib/json/scanner.pyc create mode 100644 PythonHome/Lib/json/tool.pyc create mode 100644 PythonHome/Lib/keyword.pyc create mode 100644 PythonHome/Lib/lib-tk/Canvas.pyc create mode 100644 PythonHome/Lib/lib-tk/Dialog.pyc create mode 100644 PythonHome/Lib/lib-tk/FileDialog.pyc create mode 100644 PythonHome/Lib/lib-tk/FixTk.pyc create mode 100644 PythonHome/Lib/lib-tk/ScrolledText.pyc create mode 100644 PythonHome/Lib/lib-tk/SimpleDialog.pyc create mode 100644 PythonHome/Lib/lib-tk/Tix.pyc create mode 100644 PythonHome/Lib/lib-tk/Tkconstants.pyc create mode 100644 PythonHome/Lib/lib-tk/Tkdnd.pyc create mode 100644 PythonHome/Lib/lib-tk/Tkinter.pyc create mode 100644 PythonHome/Lib/lib-tk/tkColorChooser.pyc create mode 100644 PythonHome/Lib/lib-tk/tkCommonDialog.pyc create mode 100644 PythonHome/Lib/lib-tk/tkFileDialog.pyc create mode 100644 PythonHome/Lib/lib-tk/tkFont.pyc create mode 100644 PythonHome/Lib/lib-tk/tkMessageBox.pyc create mode 100644 PythonHome/Lib/lib-tk/tkSimpleDialog.pyc create mode 100644 PythonHome/Lib/lib-tk/ttk.pyc create mode 100644 PythonHome/Lib/lib-tk/turtle.pyc create mode 100644 PythonHome/Lib/lib2to3/Grammar.txt create mode 100644 PythonHome/Lib/lib2to3/PatternGrammar.txt create mode 100644 PythonHome/Lib/lib2to3/__init__.pyc create mode 100644 PythonHome/Lib/lib2to3/__main__.pyc create mode 100644 PythonHome/Lib/lib2to3/btm_matcher.pyc create mode 100644 PythonHome/Lib/lib2to3/btm_utils.pyc create mode 100644 PythonHome/Lib/lib2to3/fixer_base.pyc create mode 100644 PythonHome/Lib/lib2to3/fixer_util.pyc create mode 100644 PythonHome/Lib/lib2to3/fixes/__init__.pyc create mode 100644 PythonHome/Lib/lib2to3/fixes/fix_apply.pyc create mode 100644 PythonHome/Lib/lib2to3/fixes/fix_basestring.pyc create mode 100644 PythonHome/Lib/lib2to3/fixes/fix_buffer.pyc create mode 100644 PythonHome/Lib/lib2to3/fixes/fix_callable.pyc create mode 100644 PythonHome/Lib/lib2to3/fixes/fix_dict.pyc create mode 100644 PythonHome/Lib/lib2to3/fixes/fix_except.pyc create mode 100644 PythonHome/Lib/lib2to3/fixes/fix_exec.pyc create mode 100644 PythonHome/Lib/lib2to3/fixes/fix_execfile.pyc create mode 100644 PythonHome/Lib/lib2to3/fixes/fix_exitfunc.pyc create mode 100644 PythonHome/Lib/lib2to3/fixes/fix_filter.pyc create mode 100644 PythonHome/Lib/lib2to3/fixes/fix_funcattrs.pyc create mode 100644 PythonHome/Lib/lib2to3/fixes/fix_future.pyc create mode 100644 PythonHome/Lib/lib2to3/fixes/fix_getcwdu.pyc create mode 100644 PythonHome/Lib/lib2to3/fixes/fix_has_key.pyc create mode 100644 PythonHome/Lib/lib2to3/fixes/fix_idioms.pyc create mode 100644 PythonHome/Lib/lib2to3/fixes/fix_import.pyc create mode 100644 PythonHome/Lib/lib2to3/fixes/fix_imports.pyc create mode 100644 PythonHome/Lib/lib2to3/fixes/fix_imports2.pyc create mode 100644 PythonHome/Lib/lib2to3/fixes/fix_input.pyc create mode 100644 PythonHome/Lib/lib2to3/fixes/fix_intern.pyc create mode 100644 PythonHome/Lib/lib2to3/fixes/fix_isinstance.pyc create mode 100644 PythonHome/Lib/lib2to3/fixes/fix_itertools.pyc create mode 100644 PythonHome/Lib/lib2to3/fixes/fix_itertools_imports.pyc create mode 100644 PythonHome/Lib/lib2to3/fixes/fix_long.pyc create mode 100644 PythonHome/Lib/lib2to3/fixes/fix_map.pyc create mode 100644 PythonHome/Lib/lib2to3/fixes/fix_metaclass.pyc create mode 100644 PythonHome/Lib/lib2to3/fixes/fix_methodattrs.pyc create mode 100644 PythonHome/Lib/lib2to3/fixes/fix_ne.pyc create mode 100644 PythonHome/Lib/lib2to3/fixes/fix_next.pyc create mode 100644 PythonHome/Lib/lib2to3/fixes/fix_nonzero.pyc create mode 100644 PythonHome/Lib/lib2to3/fixes/fix_numliterals.pyc create mode 100644 PythonHome/Lib/lib2to3/fixes/fix_operator.pyc create mode 100644 PythonHome/Lib/lib2to3/fixes/fix_paren.pyc create mode 100644 PythonHome/Lib/lib2to3/fixes/fix_print.pyc create mode 100644 PythonHome/Lib/lib2to3/fixes/fix_raise.pyc create mode 100644 PythonHome/Lib/lib2to3/fixes/fix_raw_input.pyc create mode 100644 PythonHome/Lib/lib2to3/fixes/fix_reduce.pyc create mode 100644 PythonHome/Lib/lib2to3/fixes/fix_renames.pyc create mode 100644 PythonHome/Lib/lib2to3/fixes/fix_repr.pyc create mode 100644 PythonHome/Lib/lib2to3/fixes/fix_set_literal.pyc create mode 100644 PythonHome/Lib/lib2to3/fixes/fix_standarderror.pyc create mode 100644 PythonHome/Lib/lib2to3/fixes/fix_sys_exc.pyc create mode 100644 PythonHome/Lib/lib2to3/fixes/fix_throw.pyc create mode 100644 PythonHome/Lib/lib2to3/fixes/fix_tuple_params.pyc create mode 100644 PythonHome/Lib/lib2to3/fixes/fix_types.pyc create mode 100644 PythonHome/Lib/lib2to3/fixes/fix_unicode.pyc create mode 100644 PythonHome/Lib/lib2to3/fixes/fix_urllib.pyc create mode 100644 PythonHome/Lib/lib2to3/fixes/fix_ws_comma.pyc create mode 100644 PythonHome/Lib/lib2to3/fixes/fix_xrange.pyc create mode 100644 PythonHome/Lib/lib2to3/fixes/fix_xreadlines.pyc create mode 100644 PythonHome/Lib/lib2to3/fixes/fix_zip.pyc create mode 100644 PythonHome/Lib/lib2to3/main.pyc create mode 100644 PythonHome/Lib/lib2to3/patcomp.pyc create mode 100644 PythonHome/Lib/lib2to3/pgen2/__init__.pyc create mode 100644 PythonHome/Lib/lib2to3/pgen2/conv.pyc create mode 100644 PythonHome/Lib/lib2to3/pgen2/driver.pyc create mode 100644 PythonHome/Lib/lib2to3/pgen2/grammar.pyc create mode 100644 PythonHome/Lib/lib2to3/pgen2/literals.pyc create mode 100644 PythonHome/Lib/lib2to3/pgen2/parse.pyc create mode 100644 PythonHome/Lib/lib2to3/pgen2/pgen.pyc create mode 100644 PythonHome/Lib/lib2to3/pgen2/token.pyc create mode 100644 PythonHome/Lib/lib2to3/pgen2/tokenize.pyc create mode 100644 PythonHome/Lib/lib2to3/pygram.pyc create mode 100644 PythonHome/Lib/lib2to3/pytree.pyc create mode 100644 PythonHome/Lib/lib2to3/refactor.pyc create mode 100644 PythonHome/Lib/linecache.pyc create mode 100644 PythonHome/Lib/locale.pyc create mode 100644 PythonHome/Lib/logging/__init__.pyc create mode 100644 PythonHome/Lib/logging/config.pyc create mode 100644 PythonHome/Lib/logging/handlers.pyc create mode 100644 PythonHome/Lib/macpath.pyc create mode 100644 PythonHome/Lib/macurl2path.pyc create mode 100644 PythonHome/Lib/mailbox.pyc create mode 100644 PythonHome/Lib/mailcap.pyc create mode 100644 PythonHome/Lib/markupbase.pyc create mode 100644 PythonHome/Lib/md5.pyc create mode 100644 PythonHome/Lib/mhlib.pyc create mode 100644 PythonHome/Lib/mimetools.pyc create mode 100644 PythonHome/Lib/mimetypes.pyc create mode 100644 PythonHome/Lib/mimify.pyc create mode 100644 PythonHome/Lib/modulefinder.pyc create mode 100644 PythonHome/Lib/msilib/__init__.pyc create mode 100644 PythonHome/Lib/msilib/schema.pyc create mode 100644 PythonHome/Lib/msilib/sequence.pyc create mode 100644 PythonHome/Lib/msilib/text.pyc create mode 100644 PythonHome/Lib/multifile.pyc create mode 100644 PythonHome/Lib/multiprocessing/__init__.pyc create mode 100644 PythonHome/Lib/multiprocessing/connection.pyc create mode 100644 PythonHome/Lib/multiprocessing/dummy/__init__.pyc create mode 100644 PythonHome/Lib/multiprocessing/dummy/connection.pyc create mode 100644 PythonHome/Lib/multiprocessing/forking.pyc create mode 100644 PythonHome/Lib/multiprocessing/heap.pyc create mode 100644 PythonHome/Lib/multiprocessing/managers.pyc create mode 100644 PythonHome/Lib/multiprocessing/pool.pyc create mode 100644 PythonHome/Lib/multiprocessing/process.pyc create mode 100644 PythonHome/Lib/multiprocessing/queues.pyc create mode 100644 PythonHome/Lib/multiprocessing/reduction.pyc create mode 100644 PythonHome/Lib/multiprocessing/sharedctypes.pyc create mode 100644 PythonHome/Lib/multiprocessing/synchronize.pyc create mode 100644 PythonHome/Lib/multiprocessing/util.pyc create mode 100644 PythonHome/Lib/mutex.pyc create mode 100644 PythonHome/Lib/netrc.pyc create mode 100644 PythonHome/Lib/new.pyc create mode 100644 PythonHome/Lib/nntplib.pyc create mode 100644 PythonHome/Lib/ntpath.pyc create mode 100644 PythonHome/Lib/nturl2path.pyc create mode 100644 PythonHome/Lib/numbers.pyc create mode 100644 PythonHome/Lib/opcode.pyc create mode 100644 PythonHome/Lib/optparse.pyc create mode 100644 PythonHome/Lib/os.pyc create mode 100644 PythonHome/Lib/os2emxpath.pyc create mode 100644 PythonHome/Lib/pdb.pyc create mode 100644 PythonHome/Lib/pickle.pyc create mode 100644 PythonHome/Lib/pickletools.pyc create mode 100644 PythonHome/Lib/pipes.pyc create mode 100644 PythonHome/Lib/pkgutil.pyc create mode 100644 PythonHome/Lib/platform.pyc create mode 100644 PythonHome/Lib/plistlib.pyc create mode 100644 PythonHome/Lib/popen2.pyc create mode 100644 PythonHome/Lib/poplib.pyc create mode 100644 PythonHome/Lib/posixfile.pyc create mode 100644 PythonHome/Lib/posixpath.pyc create mode 100644 PythonHome/Lib/pprint.pyc create mode 100644 PythonHome/Lib/profile.pyc create mode 100644 PythonHome/Lib/pstats.pyc create mode 100644 PythonHome/Lib/pty.pyc create mode 100644 PythonHome/Lib/py_compile.pyc create mode 100644 PythonHome/Lib/pyclbr.pyc create mode 100644 PythonHome/Lib/pydoc.pyc create mode 100644 PythonHome/Lib/pydoc_data/__init__.pyc create mode 100644 PythonHome/Lib/pydoc_data/topics.pyc create mode 100644 PythonHome/Lib/quopri.pyc create mode 100644 PythonHome/Lib/random.pyc create mode 100644 PythonHome/Lib/re.pyc create mode 100644 PythonHome/Lib/repr.pyc create mode 100644 PythonHome/Lib/rexec.pyc create mode 100644 PythonHome/Lib/rfc822.pyc create mode 100644 PythonHome/Lib/rlcompleter.pyc create mode 100644 PythonHome/Lib/robotparser.pyc create mode 100644 PythonHome/Lib/runpy.pyc create mode 100644 PythonHome/Lib/sched.pyc create mode 100644 PythonHome/Lib/sets.pyc create mode 100644 PythonHome/Lib/sgmllib.pyc create mode 100644 PythonHome/Lib/sha.pyc create mode 100644 PythonHome/Lib/shelve.pyc create mode 100644 PythonHome/Lib/shlex.pyc create mode 100644 PythonHome/Lib/shutil.pyc create mode 100644 PythonHome/Lib/site-packages/README.txt create mode 100644 PythonHome/Lib/site-packages/_markerlib/__init__.pyc create mode 100644 PythonHome/Lib/site-packages/_markerlib/markers.pyc create mode 100644 PythonHome/Lib/site-packages/easy_install.pyc create mode 100644 PythonHome/Lib/site-packages/pip-1.5.6.dist-info/DESCRIPTION.rst create mode 100644 PythonHome/Lib/site-packages/pip-1.5.6.dist-info/METADATA create mode 100644 PythonHome/Lib/site-packages/pip-1.5.6.dist-info/RECORD create mode 100644 PythonHome/Lib/site-packages/pip-1.5.6.dist-info/WHEEL create mode 100644 PythonHome/Lib/site-packages/pip-1.5.6.dist-info/entry_points.txt create mode 100644 PythonHome/Lib/site-packages/pip-1.5.6.dist-info/metadata.json create mode 100644 PythonHome/Lib/site-packages/pip-1.5.6.dist-info/top_level.txt create mode 100644 PythonHome/Lib/site-packages/pip/__init__.pyc create mode 100644 PythonHome/Lib/site-packages/pip/__main__.pyc create mode 100644 PythonHome/Lib/site-packages/pip/_vendor/__init__.pyc create mode 100644 PythonHome/Lib/site-packages/pip/_vendor/_markerlib/__init__.pyc create mode 100644 PythonHome/Lib/site-packages/pip/_vendor/_markerlib/markers.pyc create mode 100644 PythonHome/Lib/site-packages/pip/_vendor/colorama/__init__.pyc create mode 100644 PythonHome/Lib/site-packages/pip/_vendor/colorama/ansi.pyc create mode 100644 PythonHome/Lib/site-packages/pip/_vendor/colorama/ansitowin32.pyc create mode 100644 PythonHome/Lib/site-packages/pip/_vendor/colorama/initialise.pyc create mode 100644 PythonHome/Lib/site-packages/pip/_vendor/colorama/win32.pyc create mode 100644 PythonHome/Lib/site-packages/pip/_vendor/colorama/winterm.pyc create mode 100644 PythonHome/Lib/site-packages/pip/_vendor/distlib/__init__.pyc create mode 100644 PythonHome/Lib/site-packages/pip/_vendor/distlib/_backport/__init__.pyc create mode 100644 PythonHome/Lib/site-packages/pip/_vendor/distlib/_backport/misc.pyc create mode 100644 PythonHome/Lib/site-packages/pip/_vendor/distlib/_backport/shutil.pyc create mode 100644 PythonHome/Lib/site-packages/pip/_vendor/distlib/_backport/sysconfig.cfg create mode 100644 PythonHome/Lib/site-packages/pip/_vendor/distlib/_backport/sysconfig.pyc create mode 100644 PythonHome/Lib/site-packages/pip/_vendor/distlib/_backport/tarfile.pyc create mode 100644 PythonHome/Lib/site-packages/pip/_vendor/distlib/compat.pyc create mode 100644 PythonHome/Lib/site-packages/pip/_vendor/distlib/database.pyc create mode 100644 PythonHome/Lib/site-packages/pip/_vendor/distlib/index.pyc create mode 100644 PythonHome/Lib/site-packages/pip/_vendor/distlib/locators.pyc create mode 100644 PythonHome/Lib/site-packages/pip/_vendor/distlib/manifest.pyc create mode 100644 PythonHome/Lib/site-packages/pip/_vendor/distlib/markers.pyc create mode 100644 PythonHome/Lib/site-packages/pip/_vendor/distlib/metadata.pyc create mode 100644 PythonHome/Lib/site-packages/pip/_vendor/distlib/resources.pyc create mode 100644 PythonHome/Lib/site-packages/pip/_vendor/distlib/scripts.pyc create mode 100644 PythonHome/Lib/site-packages/pip/_vendor/distlib/util.pyc create mode 100644 PythonHome/Lib/site-packages/pip/_vendor/distlib/version.pyc create mode 100644 PythonHome/Lib/site-packages/pip/_vendor/distlib/wheel.pyc create mode 100644 PythonHome/Lib/site-packages/pip/_vendor/html5lib/__init__.pyc create mode 100644 PythonHome/Lib/site-packages/pip/_vendor/html5lib/constants.pyc create mode 100644 PythonHome/Lib/site-packages/pip/_vendor/html5lib/filters/__init__.pyc create mode 100644 PythonHome/Lib/site-packages/pip/_vendor/html5lib/filters/_base.pyc create mode 100644 PythonHome/Lib/site-packages/pip/_vendor/html5lib/filters/alphabeticalattributes.pyc create mode 100644 PythonHome/Lib/site-packages/pip/_vendor/html5lib/filters/inject_meta_charset.pyc create mode 100644 PythonHome/Lib/site-packages/pip/_vendor/html5lib/filters/lint.pyc create mode 100644 PythonHome/Lib/site-packages/pip/_vendor/html5lib/filters/optionaltags.pyc create mode 100644 PythonHome/Lib/site-packages/pip/_vendor/html5lib/filters/sanitizer.pyc create mode 100644 PythonHome/Lib/site-packages/pip/_vendor/html5lib/filters/whitespace.pyc create mode 100644 PythonHome/Lib/site-packages/pip/_vendor/html5lib/html5parser.pyc create mode 100644 PythonHome/Lib/site-packages/pip/_vendor/html5lib/ihatexml.pyc create mode 100644 PythonHome/Lib/site-packages/pip/_vendor/html5lib/inputstream.pyc create mode 100644 PythonHome/Lib/site-packages/pip/_vendor/html5lib/sanitizer.pyc create mode 100644 PythonHome/Lib/site-packages/pip/_vendor/html5lib/serializer/__init__.pyc create mode 100644 PythonHome/Lib/site-packages/pip/_vendor/html5lib/serializer/htmlserializer.pyc create mode 100644 PythonHome/Lib/site-packages/pip/_vendor/html5lib/tokenizer.pyc create mode 100644 PythonHome/Lib/site-packages/pip/_vendor/html5lib/treeadapters/__init__.pyc create mode 100644 PythonHome/Lib/site-packages/pip/_vendor/html5lib/treeadapters/sax.pyc create mode 100644 PythonHome/Lib/site-packages/pip/_vendor/html5lib/treebuilders/__init__.pyc create mode 100644 PythonHome/Lib/site-packages/pip/_vendor/html5lib/treebuilders/_base.pyc create mode 100644 PythonHome/Lib/site-packages/pip/_vendor/html5lib/treebuilders/dom.pyc create mode 100644 PythonHome/Lib/site-packages/pip/_vendor/html5lib/treebuilders/etree.pyc create mode 100644 PythonHome/Lib/site-packages/pip/_vendor/html5lib/treebuilders/etree_lxml.pyc create mode 100644 PythonHome/Lib/site-packages/pip/_vendor/html5lib/treewalkers/__init__.pyc create mode 100644 PythonHome/Lib/site-packages/pip/_vendor/html5lib/treewalkers/_base.pyc create mode 100644 PythonHome/Lib/site-packages/pip/_vendor/html5lib/treewalkers/dom.pyc create mode 100644 PythonHome/Lib/site-packages/pip/_vendor/html5lib/treewalkers/etree.pyc create mode 100644 PythonHome/Lib/site-packages/pip/_vendor/html5lib/treewalkers/genshistream.pyc create mode 100644 PythonHome/Lib/site-packages/pip/_vendor/html5lib/treewalkers/lxmletree.pyc create mode 100644 PythonHome/Lib/site-packages/pip/_vendor/html5lib/treewalkers/pulldom.pyc create mode 100644 PythonHome/Lib/site-packages/pip/_vendor/html5lib/trie/__init__.pyc create mode 100644 PythonHome/Lib/site-packages/pip/_vendor/html5lib/trie/_base.pyc create mode 100644 PythonHome/Lib/site-packages/pip/_vendor/html5lib/trie/datrie.pyc create mode 100644 PythonHome/Lib/site-packages/pip/_vendor/html5lib/trie/py.pyc create mode 100644 PythonHome/Lib/site-packages/pip/_vendor/html5lib/utils.pyc create mode 100644 PythonHome/Lib/site-packages/pip/_vendor/pkg_resources.pyc create mode 100644 PythonHome/Lib/site-packages/pip/_vendor/re-vendor.pyc create mode 100644 PythonHome/Lib/site-packages/pip/_vendor/requests/__init__.pyc create mode 100644 PythonHome/Lib/site-packages/pip/_vendor/requests/adapters.pyc create mode 100644 PythonHome/Lib/site-packages/pip/_vendor/requests/api.pyc create mode 100644 PythonHome/Lib/site-packages/pip/_vendor/requests/auth.pyc create mode 100644 PythonHome/Lib/site-packages/pip/_vendor/requests/cacert.pem create mode 100644 PythonHome/Lib/site-packages/pip/_vendor/requests/certs.pyc create mode 100644 PythonHome/Lib/site-packages/pip/_vendor/requests/compat.pyc create mode 100644 PythonHome/Lib/site-packages/pip/_vendor/requests/cookies.pyc create mode 100644 PythonHome/Lib/site-packages/pip/_vendor/requests/exceptions.pyc create mode 100644 PythonHome/Lib/site-packages/pip/_vendor/requests/hooks.pyc create mode 100644 PythonHome/Lib/site-packages/pip/_vendor/requests/models.pyc create mode 100644 PythonHome/Lib/site-packages/pip/_vendor/requests/sessions.pyc create mode 100644 PythonHome/Lib/site-packages/pip/_vendor/requests/status_codes.pyc create mode 100644 PythonHome/Lib/site-packages/pip/_vendor/requests/structures.pyc create mode 100644 PythonHome/Lib/site-packages/pip/_vendor/requests/utils.pyc create mode 100644 PythonHome/Lib/site-packages/pip/_vendor/six.pyc create mode 100644 PythonHome/Lib/site-packages/pip/backwardcompat/__init__.pyc create mode 100644 PythonHome/Lib/site-packages/pip/basecommand.pyc create mode 100644 PythonHome/Lib/site-packages/pip/baseparser.pyc create mode 100644 PythonHome/Lib/site-packages/pip/cmdoptions.pyc create mode 100644 PythonHome/Lib/site-packages/pip/commands/__init__.pyc create mode 100644 PythonHome/Lib/site-packages/pip/commands/bundle.pyc create mode 100644 PythonHome/Lib/site-packages/pip/commands/completion.pyc create mode 100644 PythonHome/Lib/site-packages/pip/commands/freeze.pyc create mode 100644 PythonHome/Lib/site-packages/pip/commands/help.pyc create mode 100644 PythonHome/Lib/site-packages/pip/commands/install.pyc create mode 100644 PythonHome/Lib/site-packages/pip/commands/list.pyc create mode 100644 PythonHome/Lib/site-packages/pip/commands/search.pyc create mode 100644 PythonHome/Lib/site-packages/pip/commands/show.pyc create mode 100644 PythonHome/Lib/site-packages/pip/commands/uninstall.pyc create mode 100644 PythonHome/Lib/site-packages/pip/commands/unzip.pyc create mode 100644 PythonHome/Lib/site-packages/pip/commands/wheel.pyc create mode 100644 PythonHome/Lib/site-packages/pip/commands/zip.pyc create mode 100644 PythonHome/Lib/site-packages/pip/download.pyc create mode 100644 PythonHome/Lib/site-packages/pip/exceptions.pyc create mode 100644 PythonHome/Lib/site-packages/pip/index.pyc create mode 100644 PythonHome/Lib/site-packages/pip/locations.pyc create mode 100644 PythonHome/Lib/site-packages/pip/log.pyc create mode 100644 PythonHome/Lib/site-packages/pip/pep425tags.pyc create mode 100644 PythonHome/Lib/site-packages/pip/req.pyc create mode 100644 PythonHome/Lib/site-packages/pip/runner.pyc create mode 100644 PythonHome/Lib/site-packages/pip/status_codes.pyc create mode 100644 PythonHome/Lib/site-packages/pip/util.pyc create mode 100644 PythonHome/Lib/site-packages/pip/vcs/__init__.pyc create mode 100644 PythonHome/Lib/site-packages/pip/vcs/bazaar.pyc create mode 100644 PythonHome/Lib/site-packages/pip/vcs/git.pyc create mode 100644 PythonHome/Lib/site-packages/pip/vcs/mercurial.pyc create mode 100644 PythonHome/Lib/site-packages/pip/vcs/subversion.pyc create mode 100644 PythonHome/Lib/site-packages/pip/wheel.pyc create mode 100644 PythonHome/Lib/site-packages/pkg_resources.pyc create mode 100644 PythonHome/Lib/site-packages/requests-2.3.0.dist-info/DESCRIPTION.rst create mode 100644 PythonHome/Lib/site-packages/requests-2.3.0.dist-info/METADATA create mode 100644 PythonHome/Lib/site-packages/requests-2.3.0.dist-info/RECORD create mode 100644 PythonHome/Lib/site-packages/requests-2.3.0.dist-info/WHEEL create mode 100644 PythonHome/Lib/site-packages/requests-2.3.0.dist-info/pydist.json create mode 100644 PythonHome/Lib/site-packages/requests-2.3.0.dist-info/top_level.txt create mode 100644 PythonHome/Lib/site-packages/requests/__init__.pyc create mode 100644 PythonHome/Lib/site-packages/requests/adapters.pyc create mode 100644 PythonHome/Lib/site-packages/requests/api.pyc create mode 100644 PythonHome/Lib/site-packages/requests/auth.pyc create mode 100644 PythonHome/Lib/site-packages/requests/cacert.pem create mode 100644 PythonHome/Lib/site-packages/requests/certs.pyc create mode 100644 PythonHome/Lib/site-packages/requests/compat.pyc create mode 100644 PythonHome/Lib/site-packages/requests/cookies.pyc create mode 100644 PythonHome/Lib/site-packages/requests/exceptions.pyc create mode 100644 PythonHome/Lib/site-packages/requests/hooks.pyc create mode 100644 PythonHome/Lib/site-packages/requests/models.pyc create mode 100644 PythonHome/Lib/site-packages/requests/sessions.pyc create mode 100644 PythonHome/Lib/site-packages/requests/status_codes.pyc create mode 100644 PythonHome/Lib/site-packages/requests/structures.pyc create mode 100644 PythonHome/Lib/site-packages/requests/utils.pyc create mode 100644 PythonHome/Lib/site-packages/setuptools-5.4.1.dist-info/DESCRIPTION.rst create mode 100644 PythonHome/Lib/site-packages/setuptools-5.4.1.dist-info/METADATA create mode 100644 PythonHome/Lib/site-packages/setuptools-5.4.1.dist-info/RECORD create mode 100644 PythonHome/Lib/site-packages/setuptools-5.4.1.dist-info/WHEEL create mode 100644 PythonHome/Lib/site-packages/setuptools-5.4.1.dist-info/dependency_links.txt create mode 100644 PythonHome/Lib/site-packages/setuptools-5.4.1.dist-info/entry_points.txt create mode 100644 PythonHome/Lib/site-packages/setuptools-5.4.1.dist-info/pydist.json create mode 100644 PythonHome/Lib/site-packages/setuptools-5.4.1.dist-info/top_level.txt create mode 100644 PythonHome/Lib/site-packages/setuptools-5.4.1.dist-info/zip-safe create mode 100644 PythonHome/Lib/site-packages/setuptools/__init__.pyc create mode 100644 PythonHome/Lib/site-packages/setuptools/archive_util.pyc create mode 100644 PythonHome/Lib/site-packages/setuptools/command/__init__.pyc create mode 100644 PythonHome/Lib/site-packages/setuptools/command/alias.pyc create mode 100644 PythonHome/Lib/site-packages/setuptools/command/bdist_egg.pyc create mode 100644 PythonHome/Lib/site-packages/setuptools/command/bdist_rpm.pyc create mode 100644 PythonHome/Lib/site-packages/setuptools/command/bdist_wininst.pyc create mode 100644 PythonHome/Lib/site-packages/setuptools/command/build_ext.pyc create mode 100644 PythonHome/Lib/site-packages/setuptools/command/build_py.pyc create mode 100644 PythonHome/Lib/site-packages/setuptools/command/develop.pyc create mode 100644 PythonHome/Lib/site-packages/setuptools/command/easy_install.pyc create mode 100644 PythonHome/Lib/site-packages/setuptools/command/egg_info.pyc create mode 100644 PythonHome/Lib/site-packages/setuptools/command/install.pyc create mode 100644 PythonHome/Lib/site-packages/setuptools/command/install_egg_info.pyc create mode 100644 PythonHome/Lib/site-packages/setuptools/command/install_lib.pyc create mode 100644 PythonHome/Lib/site-packages/setuptools/command/install_scripts.pyc create mode 100644 PythonHome/Lib/site-packages/setuptools/command/launcher manifest.xml create mode 100644 PythonHome/Lib/site-packages/setuptools/command/register.pyc create mode 100644 PythonHome/Lib/site-packages/setuptools/command/rotate.pyc create mode 100644 PythonHome/Lib/site-packages/setuptools/command/saveopts.pyc create mode 100644 PythonHome/Lib/site-packages/setuptools/command/sdist.pyc create mode 100644 PythonHome/Lib/site-packages/setuptools/command/setopt.pyc create mode 100644 PythonHome/Lib/site-packages/setuptools/command/test.pyc create mode 100644 PythonHome/Lib/site-packages/setuptools/command/upload_docs.pyc create mode 100644 PythonHome/Lib/site-packages/setuptools/compat.pyc create mode 100644 PythonHome/Lib/site-packages/setuptools/depends.pyc create mode 100644 PythonHome/Lib/site-packages/setuptools/dist.pyc create mode 100644 PythonHome/Lib/site-packages/setuptools/extension.pyc create mode 100644 PythonHome/Lib/site-packages/setuptools/lib2to3_ex.pyc create mode 100644 PythonHome/Lib/site-packages/setuptools/package_index.pyc create mode 100644 PythonHome/Lib/site-packages/setuptools/py26compat.pyc create mode 100644 PythonHome/Lib/site-packages/setuptools/py27compat.pyc create mode 100644 PythonHome/Lib/site-packages/setuptools/py31compat.pyc create mode 100644 PythonHome/Lib/site-packages/setuptools/sandbox.pyc create mode 100644 PythonHome/Lib/site-packages/setuptools/script (dev).tmpl create mode 100644 PythonHome/Lib/site-packages/setuptools/script.tmpl create mode 100644 PythonHome/Lib/site-packages/setuptools/site-patch.pyc create mode 100644 PythonHome/Lib/site-packages/setuptools/ssl_support.pyc create mode 100644 PythonHome/Lib/site-packages/setuptools/svn_utils.pyc create mode 100644 PythonHome/Lib/site-packages/setuptools/unicode_utils.pyc create mode 100644 PythonHome/Lib/site-packages/setuptools/version.pyc create mode 100644 PythonHome/Lib/site.pyc create mode 100644 PythonHome/Lib/smtpd.pyc create mode 100644 PythonHome/Lib/smtplib.pyc create mode 100644 PythonHome/Lib/sndhdr.pyc create mode 100644 PythonHome/Lib/socket.pyc create mode 100644 PythonHome/Lib/sqlite3/__init__.pyc create mode 100644 PythonHome/Lib/sqlite3/dbapi2.pyc create mode 100644 PythonHome/Lib/sqlite3/dump.pyc create mode 100644 PythonHome/Lib/sre.pyc create mode 100644 PythonHome/Lib/sre_compile.pyc create mode 100644 PythonHome/Lib/sre_constants.pyc create mode 100644 PythonHome/Lib/sre_parse.pyc create mode 100644 PythonHome/Lib/ssl.pyc create mode 100644 PythonHome/Lib/stat.pyc create mode 100644 PythonHome/Lib/statvfs.pyc create mode 100644 PythonHome/Lib/string.pyc create mode 100644 PythonHome/Lib/stringold.pyc create mode 100644 PythonHome/Lib/stringprep.pyc create mode 100644 PythonHome/Lib/struct.pyc create mode 100644 PythonHome/Lib/subprocess.pyc create mode 100644 PythonHome/Lib/sunau.pyc create mode 100644 PythonHome/Lib/sunaudio.pyc create mode 100644 PythonHome/Lib/symbol.pyc create mode 100644 PythonHome/Lib/symtable.pyc create mode 100644 PythonHome/Lib/sysconfig.pyc create mode 100644 PythonHome/Lib/tabnanny.pyc create mode 100644 PythonHome/Lib/tarfile.pyc create mode 100644 PythonHome/Lib/telnetlib.pyc create mode 100644 PythonHome/Lib/tempfile.pyc create mode 100644 PythonHome/Lib/textwrap.pyc create mode 100644 PythonHome/Lib/this.pyc create mode 100644 PythonHome/Lib/threading.pyc create mode 100644 PythonHome/Lib/timeit.pyc create mode 100644 PythonHome/Lib/toaiff.pyc create mode 100644 PythonHome/Lib/token.pyc create mode 100644 PythonHome/Lib/tokenize.pyc create mode 100644 PythonHome/Lib/trace.pyc create mode 100644 PythonHome/Lib/traceback.pyc create mode 100644 PythonHome/Lib/tty.pyc create mode 100644 PythonHome/Lib/types.pyc create mode 100644 PythonHome/Lib/unittest/__init__.pyc create mode 100644 PythonHome/Lib/unittest/__main__.pyc create mode 100644 PythonHome/Lib/unittest/case.pyc create mode 100644 PythonHome/Lib/unittest/loader.pyc create mode 100644 PythonHome/Lib/unittest/main.pyc create mode 100644 PythonHome/Lib/unittest/result.pyc create mode 100644 PythonHome/Lib/unittest/runner.pyc create mode 100644 PythonHome/Lib/unittest/signals.pyc create mode 100644 PythonHome/Lib/unittest/suite.pyc create mode 100644 PythonHome/Lib/unittest/util.pyc create mode 100644 PythonHome/Lib/urllib.pyc create mode 100644 PythonHome/Lib/urllib2.pyc create mode 100644 PythonHome/Lib/urlparse.pyc create mode 100644 PythonHome/Lib/user.pyc create mode 100644 PythonHome/Lib/uu.pyc create mode 100644 PythonHome/Lib/uuid.pyc create mode 100644 PythonHome/Lib/warnings.pyc create mode 100644 PythonHome/Lib/wave.pyc create mode 100644 PythonHome/Lib/weakref.pyc create mode 100644 PythonHome/Lib/webbrowser.pyc create mode 100644 PythonHome/Lib/whichdb.pyc create mode 100644 PythonHome/Lib/wsgiref/__init__.pyc create mode 100644 PythonHome/Lib/wsgiref/handlers.pyc create mode 100644 PythonHome/Lib/wsgiref/headers.pyc create mode 100644 PythonHome/Lib/wsgiref/simple_server.pyc create mode 100644 PythonHome/Lib/wsgiref/util.pyc create mode 100644 PythonHome/Lib/wsgiref/validate.pyc create mode 100644 PythonHome/Lib/xdrlib.pyc create mode 100644 PythonHome/Lib/xml/__init__.pyc create mode 100644 PythonHome/Lib/xml/dom/NodeFilter.pyc create mode 100644 PythonHome/Lib/xml/dom/__init__.pyc create mode 100644 PythonHome/Lib/xml/dom/domreg.pyc create mode 100644 PythonHome/Lib/xml/dom/expatbuilder.pyc create mode 100644 PythonHome/Lib/xml/dom/minicompat.pyc create mode 100644 PythonHome/Lib/xml/dom/minidom.pyc create mode 100644 PythonHome/Lib/xml/dom/pulldom.pyc create mode 100644 PythonHome/Lib/xml/dom/xmlbuilder.pyc create mode 100644 PythonHome/Lib/xml/etree/ElementInclude.pyc create mode 100644 PythonHome/Lib/xml/etree/ElementPath.pyc create mode 100644 PythonHome/Lib/xml/etree/ElementTree.pyc create mode 100644 PythonHome/Lib/xml/etree/__init__.pyc create mode 100644 PythonHome/Lib/xml/etree/cElementTree.pyc create mode 100644 PythonHome/Lib/xml/parsers/__init__.pyc create mode 100644 PythonHome/Lib/xml/parsers/expat.pyc create mode 100644 PythonHome/Lib/xml/sax/__init__.pyc create mode 100644 PythonHome/Lib/xml/sax/_exceptions.pyc create mode 100644 PythonHome/Lib/xml/sax/expatreader.pyc create mode 100644 PythonHome/Lib/xml/sax/handler.pyc create mode 100644 PythonHome/Lib/xml/sax/saxutils.pyc create mode 100644 PythonHome/Lib/xml/sax/xmlreader.pyc create mode 100644 PythonHome/Lib/xmllib.pyc create mode 100644 PythonHome/Lib/xmlrpclib.pyc create mode 100644 PythonHome/Lib/zipfile.pyc rename Wox/PluginLoader/{BasePluginWrapper.cs => BasePlugin.cs} (89%) rename Wox/PluginLoader/{CSharpPluginConfigLoader.cs => CSharpPluginLoader.cs} (96%) rename Wox/PluginLoader/{PythonPluginWrapper.cs => PythonPlugin.cs} (71%) create mode 100644 Wox/RPC/2obywmlm.f50 create mode 100644 Wox/RPC/tr3fzfc4.och diff --git a/PythonHome/DLLs/py.ico b/PythonHome/DLLs/py.ico new file mode 100644 index 0000000000000000000000000000000000000000..3357aef14888c501bcd7bfe02393760306a18d06 GIT binary patch literal 19790 zcmeI4dw|zd-p5Z<>4Hj3%_K8ZGCQ*|lYUZ^rZfnP*P=!AKC7N{f2!})?$qAcJ<`~@8ye6az5iQ7=W-5o zu2U!OGu$IbICp2u&|mlJ*RxybpW*(dcR%gxT$bk0kgk`2d418`iA%9_`sa#^qm_Pj zDJXXH=FL-s`G3xgD}nyw5kJlq=s$n6k-NsOsI;K5Yd$IxDfhSKW>p1^t0IwZ-RNLe zT2*ePo76l?_l`$)O^t35wo<5TkJ zUs|4@U#|K6y&pe6zb~WEuJNnXPEjAzbbaG`59jLfm1&C z#qi%uk0}0DT3S`QnK8Jht4dX0jUVXM3?d;P{zUPQ_Swe0F2#Uy^%$z|)#KB{--}+x z_kCmiY1^iMQXTs1<4r5 zRsE!Q-HL2;KUA=&e6v)qDx!NSNV)FOrG9ExDd|W5^1k`~{QD)+h$1Af@oC?-t=M^P z4|T3EU34}QRq_=cRMlESANm8$Yx)B;MWsQs^1t=;3#b%caI%{)IL}SKx~F^W+7sN= z!tQR=MJKs2m-KOWT;AK=dqpodd&KeXiQ-e;JtNL{Gw&{N|1Lk>EuM6V%bIKM$OYz( z{`{kyGnCc3Vy%Z+&Q0_`^zeG=YMJLzWeTT&pr2? zTl&INZsgbIrf)R&;)^f3MT-`>H{N)|z4g{x?(MhVb}Lt|bRT^1f!pxOJ8tPW=2op* z0@SW4^G$%h>M>yvgu`qrqbcaBU{AUb0S&Uxg8ijD^r!Vr9*OZ%Y&-hJ7nf&W@TsTeeghc(@$gTV&cv$7*OIk}PSNb_AfsJ(TY*!bBw*=q0D ztZBp86q>9 z8cb;HY}fcZOO|DIkhXvMMm!gbQ(|$6qr}H47oOrC9@^8DUVM_f`-(np+Q^gKQ}-0Qt}iS0 zc*|Vh73TUY#vryBs`|0V9&=NtPIYtU%yDned)VEp*yAb17z-CJbg#VfijOfq{P07! zW_6|eW6+qAYV8YVU1L0Z$6$!c%K$Z0L=*VFh1>!z*l8n$jwzrN<@{S+a7JIBoaX6ku5z$Sas)JFa8<_6#W1Frbl9R!(8nlvF?XfF__ z+@XR)1UiNDyXl{kCdOji0|a#`@R#F`HiC@ty}kS{5u=;AucVbhc&4;G>T|^7;af*o17@*Grc!H2~W{ z9@N+ew!=HGzWS=C0U65v4LRuSD}K+x{r7slop#x5z<`uKt7tK1(H_Mr4_MeN)9{t2@%hs(+Wh>Z!T}mqW&z(E>)(#yybWz-2CVy#? zho=FbgACv+^dJjx=NkEIZ{UGzcn-h87hQlB@P_~B=)^CTRakD;Yl&I+H_f`frY-Bs zqG6%guSG-V^JeXzGb?-FZ2R`@_tgb?_3`-2*INMa4-jM#>V2^j>;Qc^>qE0s-ZAU* zw)hVXlEJaBnspWpgI1Vr-EQ{Rx6C@t^{Tb8uJ~`;whdh#qiuP6=|Tx~NDiK!KnFFv zM33NqB0AtZJV!?84f>DY)&9;S)KB=I{$7-Z6PKCw6t2gM2AxM+f#?GNipm=iUP zy5g@j!-D@u|Fs?&5adA({z1>tf8>E)p&Nk~Y#cp9@3DrNXx=0RX*crYh5gq7zyi9^#QNw@Q zSr>R0KNDa2uaS*H!v|)kiiVR!!&B?yd(?XUwOa0}g_u;G<(t--T>u&a1UeGQB+wF1 z$M@fVZ*R>SXAccK&F=Yop51wQFOS&SpPK#tW3%6_GW#twyc@G;=}eDc&-f(SGd?L( zc7Qz}C4IuCcbL7FfCi7h*rZ%^tqG zhfNxMg57^*Pfr5`{PAGOTq9Og+sBhIU zBWlp#@o(S0eYOAB8qYfaBY9xItOr3J*aP>$PQYJ&&*t5AfjxFj51V}T2{utQj1vu% z0rH>ciiZD|kN>aLX3!Aq85)8;5o{%%4z8hrGPCG7duG`2 zHs#vx_OGF$VaN%#W#c+qA#;X?^F)JkbaqypJ>!$G=iagfd{Q_0B-ZEPlYUiUc6b#3 zntsXSulRmUmo8n}D@G}S4*ViDIs+ZVJk-#_GuGM=m(j+0OUyuduJ|~cQFxp^EgGH> z4UdS1Ib$!k%^RdVbts>U&dVf|ZmiFuA;cKJnj3vNp82{?#a{&dKmPdRGm%9A>=nGh z4cr4Q_2FFf9!8rIz&7Y#M-`JeJhw_euU#$0lum0sM( zMqSj$iY~~v(Sy&n4_7QUXo!z7ygkb&Q4--VfA95Q_>>V3ffqD@6L@0}@Hxl?A0Hnd z6AwWn`u{>{PkUZ8JS!Te4Hpfv1?(9buxEVISou|G_y;r$Jkf6an`roJz7<|@lBWSY zi7{B8LyXZy>zm4t^dFzW8b%xu02<;U$b))!cJjjyKiJ~?2iW{kU2V#u$H+ZK(Xn|A4=A!Rx>D zx&&I#heWj0Mh7&ZTfDpWt*N%4q^r#n4YNgqw`b9SPYU+@fPB(@SLE4U1-SGMW+rJTvlfT+w_G%5? z=Qb6YYyG`d`<^b6LmBY|{0}sQx;9#B(!o7G0bAHpS+Q_Rb&P>M-x9Ou8t?5k{sDjH z16T_JKu3T;19fe5>`o@&gHM`ANKd~8yZ*(SSNy9*uy{r{uDiAErdr4N9Ws; zhrxfVEqZXs&KN_sK#YMsR=;@Xn{s_ikflpt*?(e-{xH3OY3tq#$bJZYy|A`Z@J}` zI-fs)zhpf|N1*L>eoz7(@SpiOS3vhGB?I`*`2ze7^aL8H>B~Bd-V-BXEA+3>ev)Uz zNQ?n335v-7_Cw^gx92~M74%={$(h_k1H8xn&|mNgF*Uf;hR$Q>K_=h}{^&gRf~`?5U5m#*=qYv3 zUutLw5co^Y{P7U*qK))(It2;-M70{gvY+%UX6de{-YQ1^4M3IfIsx3 zOXxcH_+@Yp`H{yTe|+3ez}@4|9AW>fwWkcdWDSB2Y!E)-Kk#*|M|F`2e1~py2V2oM z%l;mnVLa9X`GAM(*RQ{?d=c>di^wIAgMt?Lt~vI_ z&+No_*DH^I(0|T<;1jSrnGoL-{~#mQH2~eB22cDhJiuPjckss!q>m43`k$&Z@f4&Y z>u~-lKT(FLG-S2@!^UsYt zba?#_I!;|v&%=GN+xQw?=bk>u0@~p-G@|R$qaBJ7)=E~at9)azH)|94?WyQ5xBNE< ze24JA14}7QblZzE=fvM2n`M5^5BhR^2`um)X(OOsj{^zUpHH^mh(TuNk`LooD zj{G=b{GS`|FkVq?9*frXVs-sk-6&Q!kJah1Ixkii#cEC?gl|1+zDv#!^b%Bmr^S~$ zbuWD1(%Jn zjQG23x(a`$m~)H#?dMtxzLZ~DslC_4Awz}?)ZRB={f`#3SG=*|BIP*9lW`W>OXs)b zyvY|Y+hq2pPUZCXOq8$GzqWFieE1~IS%v?^N3vf62LL|_;P2&AcL+Ag=Ps4se2#(1 znUZfL&qaQPGjZ}mZ*MkREZXak>rKZ`j~qF2z#Vto(H|U$o!EP_KH}F|i}2ONvcxI0 zaZNc#xhis=_FF}^k7HA$>^eem?&6}Pn9LW3f4FqTV(A`5m-#boa?YH|hxx(bPr`w`C;4-)kHUdm8#x~IksKAdPV$6*kd3Ik z9Fs{p>$v`AaM1AK!w0f90|5tO4tPRrJ*BXZ&-Ia?;T(~|+yJ>(^2g--;`NblS;*0l z>m$d6K6ZTGzq&QdPaG8Ti>#}}ZXtdPxbOz&%A5sG(s?F1U;WLVjgXDS2l^BS%8MkUZ6ly9)N0GhC-U+ZC0{ zc?t)<=fNh(*-`@i#1+?EbIqWlqN0Jsc0j;`a{zcj;e4H36FClYW#pO2Z;&S=$3$*} z92xngVSkCjog*(caPa!5ylcpPGhY1s_yB;|28hQ4T#*0#8}p2O*E7O_GfmFM$+4i1 zrjz{S2Qc;Cvc=B!|!0bg&8XOyv5=lNH5qV6rnRqj~&uHTV15cv9_y z(ups_ULfoZzyp9E0C>PBY{SRPcj}{Tg8Vi5cyHk!n0|Nbe>&qRA28s72Oj7T9;~(OtKc=d2rl?V_yR8Q z0Qtb1O>0-$8xti8{jqc z-vR$L*|7rRyWJJfe|--+VA7;X{lNqMhCXy2S-=nc0qY=RLo>R_T=<1xt6C?vUwY}K z7fF||RE)Gklalk>)1J!DueI0nANqs7v+i&mbe?zsyn>GaH*7W3TC2W0>ZqfxJOBLi z$7_GSUURb**i%V|*T@|RybrQ~ACzz(+R;h;0`Gtiyns*mOz^Czs3_OO&Gt08+P(dc z88c?Ugb5S8{_hT#fCqiB0rY_wkvIu|!FP!|3!k8Iqkr_WX9T?e4gQDmDs?6g@9{a% z6le}}!w;T?GhX6lzTwAaM8kc1F*n%x`GYQGI=lO z_VY8(%{Sld{eL1nLL7`P;*U7{Aui<134QztbNl(BIjq0v5_2#nfX~C`ux;pMK6H$I ziT*CY`>1`So4G0J&|j19HTjPW@V)pxcph6L*Xum&CXK=Q$-Wl;)`Z>pz5w>MC;wI} zUfa|4H@o$A`G2XT7i+ICaCHFs(LWyYbRVEd*MJq*>F;(k9HmzRYVAo?+&$w~p z`ivhxe%i!|6Spc?@zp~QJ#^dT$&+{SJIVoU&={9L`skznx%xDauRm4m?c67xc*5H) z_Dn&}^6AUtry`%G@1Hqm{a$0NQjTpi-;AS!=<5{iLC#cM$9Ii++FRYLeW1$BFa~|m zX=1n#&xCy?KIJ^^o7gjPhOk6o%`y6}QzgX5ZpMrmelBz$zXYJKyh|CN?FoC}nbDBU zKa2frQ9T3SgdKq^YYDo&c+P`%>*dkd@Gr6b8~aE0uk01rt8~&{X{_*44$<$)!5#f) z-hUOI>SLTu+JoIIoEd|?ID0S7BG~t_@9d_1Cuh_lR={sj*u$`gn)=Vb8)L+mFTRhS z>2Qv~o(EV6-?TY6=^P)G%BE%T1Z}GTr%~~GbrN+;5CWHLpU05T6 zj|3<735?C!P*G7)6#qVc8XaUDbV=>ro{%fN;azx)oRo{%#deGBDb_71mUYQE zwa2g9$6MBgQ!H!MDqSzMZdqbkpO}$&p4WUXFC+2%LaUwcK3{HG%Q*(SvN03q{BI2o#w&jED`C(&cI+4%VE$Wxz7hCOxAc)Hym%$?o%OV#HEWLQdg3-yPOMpz zk)a0$bGbxjt>NwRjrX&K}wSpjuDZc+J8d2HC#y!0dj^w z!Oyae>wyvc7hA`V9vHr6|12lU+5fxki>I;q=r%SCs+EO3zA=%t=v%yS@nXwbOtyKq zUC)fPFJ7q2_q3CD;_okBtX`~sT@!}O#6f;B{j-?^Y}b9=ix<wt^TThq#IF228*+-%rvqWb6c!i8LCwp&_1GyVJu-J_nc1Rqoq z&+vI`8sRLymw&Q85Tme+i&y4z3_k@dlO|2F&N$-?Ysr!&R%T|Vl~a{x72Ap}TSbZG zbUH12t;2GJDlKn~*Ybp_t@`?U%NcW7j*Tv>I#y#t4sMQ>6 zwwk+RR%d6Y)v}|_+OcDYb<@^->(-rl);IQMTbFj&tZRA;t?M=xSgi*;t+p$>t$X%m zSzjFTTX%h`-}=8toz{b&@3PLj7uLET!^(L8R`va`ihl*m`8X`^Q?NEY4J+__Sk3^YLq}FWq{xb?<#&vp)T2SdTycxb^bye`7s*9M(%Oy=49Q)mN>z-g+xe^gloU zIRpQn&j8iwDP}-gmgN*J=2qs)3(j4!V#RrxBM*!nlT@-Uy5Rit&s~w3d2XVIlyT$7 zj~AGNRTt`k%*^G9_Oz5~(wKqr%#@cnl=+>@`0?CY9D!k?X%NnO`kqt=B!yb zlMgJ(8pbVqWD7^VKV?QrYTArBvvBtR zcmSFPw$Gh1BYoDCS+f_dU#16$BYR*6Y(IacX`hrbMP*IK(zAsEAJ7Q6@PZ3P|J=0H z>GP({o3m)fI?bQTIz6B-TEn?1(-+N~&Gz(JGbf~z$YC5!BimDf!wP880`Qs*plXV06rc=o)>vu3dW>1#8V86uWstd2KZ zbLY;PGk12pcMh?7y%59t)d}Nu?%a9v=A})aK6A#b^vToH(`U_@mo|Au%7k~@7cE{i zVfrM~KbsdVTAVg{QF8m7*(u}38SMFyHf0LeA}zUn-pmQ(rcRzYeb)5U=`-fco-vF4 zr>BhcKYMX%`nc4Ivp7HFCeB+-YSPkX&U|-#^`0nN33Z>Al9JfC=cY|fojNXcQu@@H zQzy+?v}hjtPn(gJvSyh6*%Q(yv3)}N)byzn=FM9)ZeXi?H4hK-KGjL~+*!xscGpL-=MwLXw$A4m1J4)>_+)!- z*iIR?OAN|Mc8YA1;^JaslavRYme23AD%;&wZCk+F+frt=w6<7H+gq%gx93@xb=s^? zZ7jC>F5hI`zTakj?fSh|2JHv?uVMM0gVjWvVcWB?Zn@ycwOTQ~dx)>mJF_0ymK z%zF5dhpnex{G;{qYp+=+-aKK@_~*wzXW*YR@Q;}RZB%EBA2Bk>0X8fc{^XE+CZo(T2X3je;b?VfqLT167$tnCC&+F9jr!AN^f6C;^9G{P$#&U*U znWO8}3B+LH#QA!K_)nTRhV)Dro0>Xywq|*L+^V9@WG>^rzkIxezo&=ZuOyyH@(JZP zuOdVUiYuuMGPX3zqRmj=<3AciS@Q1iVd(2w%>pB87Ncm^>Hk2O$+6|3Pa-6Y3x55; zGM=ppcZkK$AuJd~yjr0LVAUqik>LFvWVabt&J+(^wf2q>%Z zd&4z_7lOq7aTCU4-1u?ko_U^qCEh)4Ec+mg8Scy6*F8Qn=Cm=;*n~F;pC;aC62uRq zS%Wm%9B*83!39{fXc3m2w-n1(F30kVR$$o$tS?-Sr7M=wZa*7KmM!7+3M^l_0xMRX zixsK~y0>KcQo<4}J$I>rB`cO-8Q)c3OI5ETT(lhLoWBI;oJUYiIQzVFuyDyD`W0t_ zHZZ6R6j3~zAf6Z%{-vd*C@U*NMqVbe?YYP)&qIDi0rEXX$g>w9rzjU0SsBPK%0XUf zKJqII&HX}mF$4v!A{5q@Ajg@9tb%Ohl;$DVnQ!`0o#!e*wj&qW>FGtX)H%^pcM9=DncdOE8@@O<{*bq-d71*q#U;9a+LOQ4!WJlt0_cbv=qhu5`6O3 z>+##)J%P91dE59;NfPs0Cm(Tks^Iut62|-=~`KG)8MQ$64T{e{X%24Da zf7l9;mzRfv;sO-g$ulLyr=$o)<;5s=2y7@U=QZ2(Y<@9$%$ARW@B>*F;8*UX!)nAstPWb3x#Dx zD0Y_+_Y#zP%TXTSx>uK@sFZjW6~g8&g{`s#B~@G_PdUo?OqrLw7j&Y$j!^GJS%bs$ zAzDgmNq?0MHg73zzxxi{^k0DOQJ~-*@JEd36!_*=k{Ckzdr z9WDNDw;LXh2PMR>qThqc4b`aHTm#p(T2yv>P+Y<}w%g#|<%5m1Rd#vc+Q|0Jwealp z!L`AQ>U}|!hny%ZE<$P0&OZ3eZoa?W3wviJj=%mI{7(U8zX6IL;rxpRuEE7W1y+-W z-d_W+zXP=X5?J+J;4gpq%PXVBzq+~_UauErHFh{+RjAtNg|pR#>VbfnUk1rdTSb=} zrM_}h@AAXdR|9uHVM8sdx~t*Y?t?wxG_;oa?QpiaP*&$a<)&&ld)Z=WAk5jV=K?C{5e_~v)MiPy+8$;I~^WmGgg3D`+P32FH1 zOUX~X@Ap5m<$A8isY;sP??)gIK!v{w-t7U@Y!AY>D+E_lHLCl4ah?d+;cEAyc55B{ zJ3QyrX@#J|#kFaP{2c=~6zT>UnreKow|fNX%T5S>zi@i%5L_Z zL_=CA6aw=-sHoyT;B&#FyUdH(^h zLNsvx7v2rHsHa#SI2r$jh6V_#JlqF@#IK&Xg{gxA+)JtNODPwXq|IALIgk3`Zw;b0 z;y2$z+rsd7*TKQLm)vR}y<=Y?ZrhcOep}i4=1|kUVZA4(G5oO$`G`GSz zJlKrzz8J#$V~8GVMO|M5yn!0Cch~d>;0#un0qz>e#MgIc;kKRG`0{qrur(L2z49V{ z{T3h^!lWVe2hxxv&(cYf=R(SYbW#R&lJ@6>PFnUo;Osd5vhR{hS|k#Ipti}6;Kq8? z4@4n3D66%@+v$Vb<3_Nh4owH!&~&H`(V5ynRD`PF2~@)u^r4pe)n6Y#pfPA57^y=b5`@QB4TqcdsG}4m+$U7NyFUYW zlZHF?X5p*5v+-}F;beKfmOAO`o(hssbA~c8xd-*Cs1BGsXJrTS+y=WxnERw zavu)64gde((mZ^JG<=gZ+`fl2P!=T5qCxU3opc@bs%W@MG;|i>P&;X8wPA0p#Lyr- zWn*Z6PS_ahxWBQyhyP=-7+P9d5NIZ@d#D>X1-K8DBfPg6vHk6+Yas7zi=lZ(E7~sY zLf6MPnA#T$pl)ZQ*`paVhTz$kp2LHmiQ?X&_4xKa(m+}G25I>BVR@EL`rMX0+_*6h zpX$%Y$9oHKw7U>jkcLZ0!+z4Rhcu|1Y-2Q1Hdx-He}sE$Yb$)s0k}JBQ10VCw51WT zp?0(#>VouZw67Vh109HVH=*;2UPQOY;BYvMd@v6WfvwbrFaO{xc;T1d!1oWV$1&1y z4{0#+Od6z<67u|isFOauF(04oFTgdV;RtECoHQIHAMIjHe(Y6TSAERHleXCg2rg0(XZj=Fv2Yn)HgMtn)<(-d{#yqr;KY=T1i`n zGT?Mq;PEFO$M5dF9zQ%>jPDI);GSW5mQG5@^B1U-M8gfkH2e$s=tx%~F6)TXAViIg zL3_J`a3l5AUx1&U#QVBT6aLbnHrj8JTgj|&jBu`_JxvJ5A_zyq;8_Jk+M=jytw&YR zO*@HxTU{j_{tEau*1;96Mk(zzU$Y-~+>uHDa{2Xrw~g2slIJUj<@u!N{>PG+dThY?rYIJMI)=tEFTF|_cx_>YRSHuHfZxHpnA_#1%H~cRI!qFB6dW4gZsGO6*(%2Z8p!jkQ32TM>Qa z$g{aB>zkNuRY9P=SR4mdog)D+SX)n zZ|QDDYbWPC8i79|y-FXAK8@W=KY{C2K|eutU{eTg^1u9+GB$DQjXZN5v_B{0Svo0Mo_}`NXXV3xX0-gn^F!$9kZx>7*O7j7AMQs}dowzBlZUR{ z%=zbfa82qqaNpV;MR-8ALn~UY>_TLy1&squC@y2Xg7aO!H;Ta4dQ{W?Xu7H$5z2!6 zh`t-P;K`?+G`jWYH#Xth2Mf4A$88Ml&$sR=#$DI6;kQ4%)5ISJ1_sU=E&koz-RSA* zF+9`0uL~`k+R$^TA3Z~a!9Jrq1GInaUMKv$b%+eaP~B96V1GRt_fSr^G@y|23DHou zlXhS?ZPN`wG#qS3?MCj2TS@mu>aXpsxb^$D;i;#d!rO1ZZFoHKq3g#Udki~w?!@^# z*g)Jz9e)$B28T}+7&fMJ{3pN92@?Z&ZiudNbgtD$L0MZ z`o{(sJ5l_ku&mI?iTnlGO8$C3c)kptYTD@3(be=Z6gQI(YT}m}8DK0~dgmj>4^PIw zse|@VM+|M7+7W80hl4(EenGzRf8~$M-Vy)XDF+VP%sl%BKl$H9`%^J3*{#Kl`;?OR zT_F$ZI_lBTLq8!LH28Z1UerW=^nqx*5`V=m{~q`^_qL$ts*UJ9veC?Y@4sw9WKYb* z-DHc_b_dY7oBEadGj>Tk+K=`idZ5+te}OF?lZzaptQ_qy`agVtcGcyb=(%nang`n8 zqkho*hxvZ^U<+I|?!OEE$^753zZ)^q(RHvF&4X?5b6?HM%0fBkxWrXzXb}IqBIJp_ zkdbHUf5k@&7*}lA*My3Q3ylYw5!xCC&kdsE%3ee^Qx+KKkiQV24_f|?9q?~u3}tfwnfY17Kf}Zg-ECe3w$Xpt6{elkgr>{e(Li4_NFPA?0nL4AkiPSl zdNl8AL#U}9Z3nxIuOL~etz*2Dx+ij=1vO1RBO@-(lig`Q8UMx9L8H#U2!Da>&G0tD z!59jwieO{>Tru>u>(-i>x?<~9E%eDqgJRQe#k*>OR>e8(Jlcoo zrkLS<`9QIQ?Pl&xtk~y4Xh#_J`=YQr;<~4#qy!gVd~t&RmBUm1Yc%=0H0`~DKqv@j zO$7=nijZ58k3ui=DrI?Cm$42!bA*eth+__Afoq~XQDy;a@|VD@Q*I`T%8HF|pt-M$ zh7b(Xexu*)tM{2$g<=8TaBZA-XoHvAX>XACr9%rCCu0uodE%{vxblyqDQWHP)P)3B zwcF$?GHt|(d8+jV%!ifd;^OS}ShH>ovTZpgN0!U{SavD%Eq3NRDhrY8$VXKN_n;v6 z1nw1~jt11XH5wftUqSjm*g<||{788Q#k&+|lCM)@` z>^Ezq+)LY$ZuEV63px(>p#4Y>S`T-j{o}o8+|dM24P(8`mB4WymNdm4q?-#X>BH93|Jv#^^Ip|kjl9YN9`{^@JSTNgaW=}sPIyQ| zp{E%3XeHdt11MLpcI{ddr<1OaQrCAJ?M2g`7BuZ|L-QqV2=>tSChnSN`3;g=eb;(u z4T$>{MEIlPE*d9=!(r3c+V$k~^=q*%`(k7kW|3#sV(rCi!NYb2Bm*ad+H@~BH`m~z zSg=6;gktiV7x_lYktoMw_=ho5H+fap;(OwL`Co~<@Si~0eLb-TiCl)p76=c4;y(!x zeu?j@6}uJ>Zr!@o*pEENkL}yHn_S|SEnBd8^JZ+?vhY#b5E3UxhmtSuBP@n3b`r^5wqM{g)NG0gZ$=_0> zXVr(!a!mMN0*&=i&&u!>{%%Ph1D5rS>iprF-j2Ecd)LI!^vfACHHZAW)QSEQ{r|o3 z{;>Y?hv`Vv1H;#d*JFn3vBUL5)=H>OW37Wd3kd~;k#kzIHr~Hzopq*2awZ)&D&Sd+ zsjs~9N*i;z%#h;sgs(VUzs~zVdF{2=V)N(E7caeEkzDIc)j5O<2&)JejRyGJoKHS^ z0@%u2PdQ_F%CRXHtenDX=632C8-Dcv0sP&L^q=TERhi23){TT0_!}mC6nOdNm(j)? zhw@~Kg%&V=tDLv;#lLzL_ywbK`S$_uyz|bVIq)2U<~g}Yu4i*^`h#rSEO#!lJUjZGuKSBa;C~RD$k|-ielo*4?S`mc#yOw<$4!! zEa{HqA{%0!_73fFr92B#-d~9lf0@Zgmp0J$qkUlSt3r7zbJbhiu=n#^$%ZNua}oj} z=BkwQbUz)>JL~*{a#YIiDDQs(*FlBjEFnxx9-QCJ_}atd=h~_m&teQfaUtdO1&X<= zmi>9tO*i5AaT1nPlrO7e>{j_c<;reB;PjlGe+9?xnx>Um~H zHY2~=s_D|7nXeq`n5lreVb=8oDIw|cE;C3_-HOXn|*lv$;WZebv-7gt(>!B@+ul%&`2DV z_f-De@FQ_hu1z@}@uPB7%5^GF7^IA_{5UbbaDDsIx4}(J0ra9FzF*Jm!p9UQdj#*t+ZrPYd&7 z%xk;qX=fJ|nVhz})(u~O(7d3yvSNXsXFO9m-{UX8h<%i?WE{kgzLWSdpZqA9&{-Ps zV^W^ZtiNnyW6SKWhqsA-b6d6H|Jpw0v<^fO+7mY8E8nIZiSmWYQ{DN={twL=zW5ff z@oDBfiG$AbNG6oCRY}m_O#4C|2bPibSA1Fd zbzc|l?rtxFI~t7r7}?s42Kq^gMJez9(C0f$-cb1}SfBAMA->!2t%n`_^Oq^MeY^aSkB#yuE81BEuZSsDKPm3Rw!&huN zArs0oDc7ew*}yOk8qEE4Jda<`v7dNDcixqM`S#*JoljESuW574j2YY9islW>5e&4O zGX%H&;A`*Ef2OCTkB7hi?_BXLo5{Dg?PgAe zIf~|?Hq`Vm_pY-fj2lZAd%Jz6Tjg(c4j>^Dr{YIFNM2h?IHmqqZeQ^oe`CPJh!qo7 zzFcylb&w89>;W2EplcP$#Gju16<&JwQOd+g{79J)KdOAt`0~%h@6rBdlh^3j)n)QA z9Xq?AxVnD>ee-r7>b5g?+{zda=c&5A*5q7%c(og^JohWS{2!0L%a4=^<*&t$H|!1K zPk;K;2aYfP(;T$!P+Xj`{mV9(d};I67U)cma#+6ZcrHu0h<10g7hk^fR=oPc<9Oh6 zUATLw(3}NG@Z(K8O7Zn;`|+R8Jz@Nu529Z_m;5uuwPPL3HFw9?Up$e#|0d==kqeiO zmVczYfcA&va^l1Zb6@@xe^~Z`^!NAoLp<2JmHF(=9q8KKV|-T+X;h4~ZZqQ$?S7NX zs9{|hVtjt{GnQRbTVvv%^5JDu2xpyp{vi4j<97@)wsB+=TK9IC z{YQBn|^|lF|^jJx{NQbIF53nqa8na{=-dS z#%mqO&St!kK7W2b&$%-0qrF(QK=%Z?r#(V4B0pO?MAwSpxf#RzsN=Wo>Og&eBMKOI zRy?{g%=j_S_yx#wo>-0HLr-gs*_W%D+(suUhu^?lxZ+unUCr_Q1?l%Om!SDk?()Ot zU;e)KAf3I?*+^H1*Vw;`7wddg-8P;Fpu7cH*KkkP-019M)2>!@Ud}uKbH34?eE-@W zBgcw;_<827W`p0z%JBH|FHWg{l;4pJp!1a`mYtJnVx6+d1sTj6X+Dxc_Mz-HLGs+2 z7>t`|9~pZ$XYQ!G7;}7+V}FbwUnjX3`$Ms5?eX?7&tnJ6P0g4M%6KMG_NS+-1{F~k ze9Tol!j&f1QQynl#b75|2HOqo^}UQIZi$$)P%cmW9H4AU#oy>($p6vrM&xfK7mYth zxo63=&ioepN>I_}j>pS*&Nr_tAJu(6IHEkO)X%sf+ay!Xocq`wp6lRQf+*u?;XTZm zUdb3K$J9BwAagFm@tdnThJNpHvhO22gwHg_eV!Mu>ioCzXgW(O{!Z|Fa;>qYuN6<0 z-jv=F{@O33LuE^9Jv0Z*3w_Yo8ee5R<4<1dvFCT~+J)V_cVo|6P}gao8LN6 zFRB*kp5#(8Dw$!d^jXGC3;Ehep&or!zilY4>kIehBk4@2Ym6WM6{?p)^{qd?TLC#4x)}{gMazxFY(~FzksXz;E^TJ2U8a z%6`-DA2in;2fGbw@?qpdedF2yBjDOE1CC1*8 z{~_N)zK?8O`5XWC>C2!#+Y)+FJSq6ePkw@@ zzJC+GzQ4?z=e}{f6Ze1XW(|Kw;(e`I^R`xV{>IZw|F)Gj6@6L{&t&Sn=0lG>jJMvQ zlgJ``c-G_Y#Jj3#S3DbFerkPghWTwsS%_!+JIMbn@%(;x6K#M^5u^L5^9PdO)pz># wMU>y?SFT*CKaDYx>(Jh+eb4y*4$04#4~!wXdBD=Z+0F;rvLx| literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/BaseHTTPServer.pyc b/PythonHome/Lib/BaseHTTPServer.pyc new file mode 100644 index 0000000000000000000000000000000000000000..47fc35c4e0c9be79739b05947f6298d4cbf3b398 GIT binary patch literal 21389 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 ITdTo;0ESgpB>(^b literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/CGIHTTPServer.pyc b/PythonHome/Lib/CGIHTTPServer.pyc new file mode 100644 index 0000000000000000000000000000000000000000..120ff20c81e03a9d9f58a312a7870d0e5c4abfdd GIT binary patch literal 10868 zcma)C-ESO6a_`w)F3A-sQY0mcl5CAEOIpd)%9d=|mUTW;)Joz>B6+hb%VO+ohBHHQ zmdl;x^sLDBEpq{Mc}QN9#{j`S1ObBN;Q%Af!(A>P4+#(;`3Le3ByT~G7bn2w_p6>I zmxez??)3CWb#--hRdsdsWdD1#@XNpb^NOd^zbxJ#;nDww#8+wssijsd?pniAm&CrFeuB`zoW<{QZTi+I{}KV?U@?m+eXrKM&$kp-|ljwY?Sj?M7g)w!?<6 z?Wk#2!mU;#Afy4bS39;;Z3WFFY_8k)%T?QL`u6ftrCNxC?RKCOZ6}fKt%p}v!=|mh zIBX>vBP^`h$wpvDy0jL>o5joaTD$2bAx6Q-%_y;3aiD?LE(WFb5=Va;HvMQvU!E zup4-7RFhwvwAYSfPOTM3UZ8~=P0-k|Jy!>MR$%t|>h_p|;mPKx3CND!bi?O?ef28) z9kBY)Xu9KV#8ES9>qZA0uaxJXI1ANh_R~3MabfZPE&J}$;-#wnq*Au44;Cu+{LDLvwio$W z*%$y|JILik*JF2!GhK|5022h~b>b#%ZGf-8`6gFV7Q7XQ=nJ7SY@?St&yCVIrXN zqT1AVqt=Cwu%mG(P5(i z(8pQ(L3!@(zE*7&Sh~-Uv~tJPQdQ@_ZhTzKW!)R9)<0JR^B9oF;8t3NXiF znz05JjB%yNVYGupOqJ~#ic_1EPM!=9ONR-FPVXz-x025;;s1a(eFnJaUC5>w1F{1m z+sCZMBB__Dg}Md{Npz)@Wv*eK7EbeOHhYot15x9P;yvEcWp6~$rIb^)UTr!U2>sv;0@=)brjZ22nxId6E#UayPiXjd+ zHBnIEL}tV)7*3ED5+#B}`AYD!R6QeXfMP9Ey13-26Ne?fhqx`sP`5AFcs{}zaA0y+=hm6=R|fw9rTfj9o=nmSMY*X zZ_kQdz+gKRO0iR6N7WlqyTSchx3|nruutOwQ9H2MaZrb;h9)8(HlMqV5Lp;`*Guq# zbw13K>}-ZY>T+QF!J6A{BnOtr?4Mv4JdxfCkep@|Zvp4$7@!?D_GyrHSq;`hFkGC7 zsEO$sXGMd<&2>^^_($HG4JC@hK=0!yl1v!`JD}}txG`wP)L~{^`_i>b+#A^}TUI}6 z>`T45Kth$e7BVeTEs_Z&HBegfqDI4Q>7YhZ#lE1n5w40wXg9ap*kQ$%NV}L@cuvU} z`hSgJ$f&8K07(~$SVD!7WiE}wj!%~5C^B$K#dYbEsfp4p}DY3eYQ#M>#gI+`Qny<==V zX*g8NW^4&cMOx-75~5p;Fo7hCU^JqgAeP$gk(L}dH+^<* zK#-s!C&nH&T6VoU>hr9Lf1gd=0hRg2F}BaCWjs$gG){5`i7Zb#?%(&u?He=$TK5K3 z6CDPaVdp-&4~YKiaA#~XL!4)Gl=bMFmLcJo^mKPfP45l&<})nwDfH%pQ3|Zlix#;C zXA+~Ma#)=Z*9f~(I&)w!kh?udxTA$bki;N0K)82Ab&n|hp8|YDwf;;pBfZS1(tp>7 z2f%$J63@}za0Y{Tx$tKD!Eic-m8y@+T#m`S0D!)7ccWI#qv>g+aHtM zxM?{qg=6Y=Vw@a6P7@JA(+mX zioeVvt)CU7V=A#(2{QfDa-RP(>jTG-YMfJh<0{R+ruL2zi~|$*E5L0^_4CBzzbbvd z$abbxcU;w97vQX#;q=GU)8>@Qb&sj~1+`gF@lUdrWo`c=`-!2$2Pp#fby9voLVH8n z>NdJ;f05n(GMn-RQ@cn~H-}XG?^&`2HAP{_IWWXH?*c@cQI&##AFs)f6RJC*;$u0a zggC#?MZ>h$1!z)rCslkihm=4U1ZW)#GNpE(%7Os;vhpty`tE1*Y7c^PoJQ65FNqKL zlU#R7)vvI&{s!3vKx=!6wFE4xvsexPGOMS76)jIus?RC_ppK(n=_ejIz%K~l2^Ifq z4k;mKg|6f(8IsPkr2MM{rN4=FnO5<@fL{{C`+|E-y6u7`^C13&+7l73UsK(av<}qk z?U8|}#Q3K2@q0_^AfxrSlz(0MHw3*oH62m$FY_=Vh+*xWQvTbjJEJxs)6WOGr-T7B zB!`ir4 zVWqRJI>*FXe4x6}K+r8>Oj>S>7~jc5jGLDFgjGLCX{dil`bhv#9W-EyrU5jh4L_vO z0$;FrFS007ryF?RD4x-Y3PuYCEug*>bjJk!=ErtoYXCaVhS;e&+l(oDw zh*}Espin|^kbGbHVAHFr{(zl;o3re|+AdJVP~O7^*L+3gk{_w$Ax|?j1b;Y)8G~17 zBp=!T5&QeM1=nNcgRQ7U=EGhFYy-or+}>+4@X2&i{zqbg{%f#%j@;kOsTg@sCQFY> z(r{k(OYDE=)$W}`qElb|M(O!rC`GZT>PtNV`f6}_`>R3xo_1eT^<~vPPvjKJ*VWzy zp$g0WW7QS=VRbL4_;bMnDZ`3h5Z;h)=`fxEAly)nUA;YyyJzp`(^Ff)<`nm3aMf0QeysLzMp*ZjqiwZjtdB1hfv~ z40iECe0eeaBSM@9L|+TMTt>!RyVY=UWTB5M(E8%Hz?qO{>N6V9bKeMh;Moe4oGmJ4 z=i{b&s7mnd{$dntd^a7bMxhXEX&SP zb!mR-Q9qXDC8sLq5U2d(C*?}D_PAVquyj{~2Fr8R2f%c1NsvgX>dY-x9$}EX2Fbj$ zuw1Q?l!S~13g=m^Qgsjs6#%FFc&S>hJwQCAzdU#Mt|Jb;+lIFqho8%NGNg|z0YVvm z?g@skK3gt}i@fUU(39o6)sG2rR!4@OU&53ZtI|PEK3*iD-K&kDxsD^C!4`8g2-v0_QLty@TbJbT4YiT#(CA#(l^O{41GF=mgGV3tJAOpI- zkBE})4ai2X5klH(X^Zq_zyOrVyw@2TW6`WEPn;(ecj8-GRQ)`E2pdCts z47t{5>kWs;Vd=BuhDi%RBn)9P1jc%T1$Yt`Gx|aaYDDWMsGPzkJ=_v$7FfUCx-P98 z4O@f}%)omd2s=0A{v$cX_0HX%o{%;e|aG_v^5=ho9XPm=Q0-M zvE2+ksHBj)6C-rt+#y{=;x!^2ICCs=3b901DLlnXC`v>_D5ByTuIfY#n2Fvu5d~or zwT*d(Q-yMK3)oY4a4YT@_KS5i?2@c#nQ%{vvfLaf)UA#)kBoF{ZwqENY`}OqC1jk> znEZAR#OxK$JFI+{l>`=!($ckEiQ;&X5WgvcXtczy8R`g*pqQ5Nj1;WZW{{Ry&NVQb>(zDo)=BFqV6xUU;BzwWsmz2mnHd)d&>+3?2vd$*Co-qe+ti#! z{fS%_Sf?`MnTgDBW*GR!tzj8sBy%!z0gyw0ngre~MmWY1fM*6{Wsy$hMgTpA=XmBg zpwK%rgO+jR3n&en|I9hG=QBm?IItZ@D>07Zf0(&UQFb57XH6`6ttP@(tC`Du6sgd) znjd*-e#6zgIxu_JkI?8mWbz1!$a%clUegGZJ47m%Ear-b@o3qEWb=}>J6L7OeaGz; zFXq&FJer}y{7@bXi~n3cGdwapIDBFxGn^Y9@F)hPmjX%U(Eoviel={q3IEA)60x$~ z#|!}DRAJx!Y)+ZTDGrnT`T?gA3B0|)>2=#?a4?n>Q9K@9kw-HQQgZYp1b$C}EdG)x z5wSx@MiX&d`4!U??Vt3aWqdEEw!e^Opv91ymD^0=95m|F&4aHZEg3%qDHICTVffm^2S zZsKr(J16Jf{MG9>-oI(TQ@Re1ADTo}axyd-|H!1y~Zl6lQh#T7_939;38 z%nb_;Ed5`BG{P+yZ``Crwz)yIIb>vRfi{9h%iOr&LlH1WzCR&RxSGND6~qa##y|xdZpJudk^4QoTU=ON=H(E+)nFdO*}w@KZYH?K%Nt(Uz>UM#4A)W~`Zl|N z4R|$x_ZHw2iIQzUVDnCh4?En(j@!Y<2#Fix9+2Orn2R8+*Q{W}l^h&m9t3by<6@*^ z2e@sUwVR~IrZ$33~&uP_}N z3>+g$J^Uq{;OQV+u%;ShMf-(%PU5I)3FA}lJK$BxP!bJQBZdm8VH=1PgY**$Tsm!8Z;X;DO$|u|e#BhJapcTI@;S4mdyW|p%-?{V!MCj6$ z!UeR3c$B$AJ%gNhXgu;d&rxz12a?TLC)}LVn?~8bNv%#^jstYLu}3L6)+=}xlbHX2 z}gAeAIZWn|6alfc&1YQ-s3Ie&>naMyb0&V646a#5=p|KxWG%HyOQGw#Q*>R literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/ConfigParser.pyc b/PythonHome/Lib/ConfigParser.pyc new file mode 100644 index 0000000000000000000000000000000000000000..3e2ad8998ae79316051796ce3d7d9b2558468002 GIT binary patch literal 24918 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 literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/Cookie.pyc b/PythonHome/Lib/Cookie.pyc new file mode 100644 index 0000000000000000000000000000000000000000..61207a03b5c90809d361f2592b1771ba6f8920e6 GIT binary patch literal 22230 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 RY*@8n%ZBYO&Dan3{s+(ByK?{l literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/DocXMLRPCServer.pyc b/PythonHome/Lib/DocXMLRPCServer.pyc new file mode 100644 index 0000000000000000000000000000000000000000..432e4a0561af48be0edce098251bb930a2e845d6 GIT binary patch literal 9564 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 literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/SocketServer.pyc b/PythonHome/Lib/SocketServer.pyc new file mode 100644 index 0000000000000000000000000000000000000000..679a5ca1f0ac45631207a205b0145ba9924a1db0 GIT binary patch literal 23733 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 literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/StringIO.pyc b/PythonHome/Lib/StringIO.pyc new file mode 100644 index 0000000000000000000000000000000000000000..971a003f4a0fe60f088b317bbfeaa6f3212632d2 GIT binary patch literal 11385 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¢_N)pUV$Z3t zDRxbTEwSq=oEN*H!nU|=*}EWiQy(vi-BRI_*z+n}7P~F>g6exk>_u(7D)y2JO|h3% z04G;exGwgp3a^N5s>1-PUz**dduLwEJC@G)47DXHm33;FmwP(frL zrVr#Gl;k6}V?0_~PcW{==WI@%qwgP-(Q&2HKcBDTw}{ovc3ZHe?6ek8V=CI(SzCpj zLF`n>ei*uJ8C~798>d-2?zjj~emI?{MLl$A>Us~=ce-&m(=HBdu}aUPx_$p%_rd+b zv2G84(80!VxG}_#p61}79;}2HgVmrBoDDlf$ii)us#OS?Qnjzd6iSph5;sgDPEqY5 zF03G?BjHSA&R_!VafF#R(ds#64gM9ufglP!lLVoAXAMZEP}Z1EJEuzVWQ^HC_Shv; zkrBQzJupNLPlhY_HLmCsR#BTNkZ6UEC@-{Aj=>po4kJ&7ff;Ioo8N%JJuznO#29KX z6+;Xj)=!LK?xkXQ1b^5#F^2h)UBRE|O7C1mz=(*VAP(&nm>h@lDOf-gmFzzDd&df!5It^sI*!L*C+18!9 zE7vpTk;_PtF;~l-Y0IK0=gg(gV0k@1LH>soe;n=4DLzfofDxU2Mht0zp@})iXwSp0 z1n|+30Lat`z>Ira*Yo;cEB7vRFQec+bot=K#SNbSFGQ&_l0SNCyi;m`fUIlk8-%pe zMI|k+st(d`Kh5fRfW!6LDZI_Q%Q$_=0$_Wp4&HHL!?f4!Aj4e8tTLb*L5C_7bRc_@;AA;TH!(B6JT;_&i_>OsK3EGo+^Q%_7T+&k zOcr&5X7~%`y-A(aA5|wBQypLe|BUv9kLJ+dBJ?6*!@k^th1@9QAp{ROKSy3w-o1ya z1!2c6`er_A!i3S}a2-oEizR4Jy~t^g>P+?gy|`jM<`aJ$kkd#_sEnwoXEL16i*0L- zc?WBxyjkO<3btUc_3$LhdT)bEETl=zckjOPPk?qheSGT4vYC|VfiYH@AHn#I{en^r7NH>kwx361Ub?W(>X zQ(w9Wt-S$jp9?oe&Q5<)XJ3avbNE{0aGkDQy+W66IJ(AbZjGnLp7*}~Vb7R9W24C% zNr__3qnIO%Kt2fhPCDX9NzwQp@$njFOx-@`L-+qH_h*cgkJ9hC-~6e zGKL;MXvB8J#!Lrw^af_$L-D6GbuWq{;6>6~qD+T45RM0dTb4_*$&@(Dl_9!?t-dIb z=r@>O6T+9$Dx68DP%@~%a4@Ve!F$UzyF_nd&<@Hm_mq)O&R~ng^#|X%3WAv!;34q0 z;}OiHJVUpGZ(9C~gg=&M+Wa;q{(Wro!V&($);t&x3#B9cJQ0yfKKJj&);+EG0Qc8B zdpmiQPPGFM=P$V>igdVWQPd;#&Z@ZqK%S%X$bevsC+<6!q;B@_AJMy*#n-RV)&&P@ zmLr1U-^T%9P^W{jP~cIgG#q?yr_=BUjNUD=Fw|LyM``!~!q|P_rUpisU*~WvAU1;d z%vdX%Ds&O!M4H!3;+|&XnPiqjJ^CY7`wFGF#sr(;PU|LN`ivL1`?$#JS2Sb#1AExR zW28BZ1EOVC{Hzu6l^|-cqRU6Lc*IXG`u-X5g+E{NaXWpCHE5TJZ?w@xR+m`uO)t8} z>N=}eSlwVnMA56P=!yA4iDu*Ibv832YBJJ{5HTnt21i84^e#f%sJ-e}=`K{H%h4JU5dab^Q-zDv-aqLQEgkG65e~#Hf2dwg)uQTZN@BzC! nz!yrg_r+n>e$aEf?#ZDmK3L8KSV{TNo9JT(pB_;Q;Y#=mE6{iV literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/UserString.pyc b/PythonHome/Lib/UserString.pyc new file mode 100644 index 0000000000000000000000000000000000000000..b90fbcdde79846ea6953ed4495382e5552c248ed GIT binary patch literal 13844 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 literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/_MozillaCookieJar.pyc b/PythonHome/Lib/_MozillaCookieJar.pyc new file mode 100644 index 0000000000000000000000000000000000000000..a35d0eef7a8a752573ee4095a2098ea7ba05cdb3 GIT binary patch literal 4440 zcmbVPUvC@75uYO|N~9=Dmj9&fL%Ob=igsiPFd7$egEo#Ww+d`lIH^@CxS)@`C3)iU zj^15bVn6~#9H4#fd!Ootd3Kzg-spu~z-- z@r%PY%|1o^{}_*b0TL6PfCdy7C=KWY13xa%NkPU%N{cio(MgF0OLVeCgEF0zX|PNu z%QRS_lNAc$66q!CVC52hN%WfNcPABAc~~#ArT0Oe<)0^M8mV2?(9X7_p;qlY?CrPRwiKb5@ z<0{}hg~B~!a^u*#pL5qRe71jhxZn6?^U40xy~e|5d(ET0&yL&%&v@?^dKS?tVe%6^ z_5%=&Xkn9}5}T7E?-7BCi@a^b2K(2`{D+8qS>)J+vk?3lyQx+cKF1Hk2Ap`H#`#DM zqOm%QGN)XwT2Z?{8Zz6cmdVeoHd}TUB&#~urb;@pYGk#ja=iosX=E+0NA%_~wL41f zt2>y_`gc^~)LCx&c3ZVZu+-B=s~!utw9Z6PYt*$W$#_l;BkOK>SC20A$4RH74csvK zKrOb9nWN+~J4Rc-tyqP6tcV0B2>P1`f zZFk(c+fv>x)~Dm_d}f;+mx%evZNw+v@tb;_XIoC`^Pz6Lg+Cm-Se^Aa$Q*=O{1w!g zQI>Iea)z|Za+kCr+8WO?a3Nbq06S6JZO@%XbkrzI&ea(zU*)f~IWvjVKEvMPY$Hgl zsN<4oqs+VF#efyWiS5rEOC0K9=FZP}?l{R})XBCK#n9xfsD*U2BWzIANkt$f5zK$v z-fquA)5zhS>tO}Q;O)@Q0_}GLyII#nu~y-eNB2Iw|G^@ZE*IPLge~~+7yfX6`#kJt zC^dsVL)NZ7@ zI@2cNtaJ8mDD^m(;?!~C&>?L;{WkGj#`6e|-7MfZBs!Jzb-F~8fKCHGYo}#$1v)L# z1hXZYl<9SW?585I!~y}%K^*Io0$qO{&=&z^MB_gM=i}f)$1+WDY89woAd}JoB=CL; zR*|sA{7I%uq^8Tfn&(zn^(l_|8cW!N3+7DC*YxsWE?lK}nZ=$j({zQV6`EFQx=Pa; zP1k68i6*NQuds12C(!A~6`HKgovHzl%r10E_9{w~_*>Ph_sj!4b(AiJ%S={4>eoR; zuS*8nF$*vhr%9$!$owJ~H>)Gl?#c8Z>L%?b_}mq30KX1dQ0878lTAVzhsS zeA73&NbdjIYvX(9-u#{#;)Uwm&7#}tv?I~%$ObqM88A|uO1c>^w>dY+e$H6lsCDcV z@L9GiaS@#oJihMw!$vN(ekk}O$C(HYarn)`3&7Ii^jtM>Ts+}eAiE>&RxwJl#3fPM z#JLpmeO!ER*D)d?_7+Bu9y~u7yI!8%`|0yEX+3YgeWl(Rj?tI6&HE##$@jrsyxSOr zf?A;#Tnnl}5#O}}(^^oYQgNNuir0e8pj^DgoS;@J2bIEluvsYM4dbFvjChUzR)P(@ zU&nK`um-voEQ7Xrd+Y(1$0IxzAi*dJ2l^{y?hAnW*9w`f+3Pf*m-iWA5qWg4hfjo( z7Xp6)Sta`X{a{j}Q-Cu19QcbSM_>V;uYovAbiNW`;_>e(09K=uYvzv((|}M6UiJme z7*f6xE`ZE~$5-w?j;+ZcR69Vh_Gn}aYMgH8yqQddA9 z(EkpH1Uo%Gh8Ygk6~Q(SVGIBbDXO!O`$kIp$-}3Idm*PPl;4mHOcjq*^{dR~A9SGt zk*@qLSF5yM$Z3{R$C00jF1dC~(feCM$W<++9R7eux0(Ey$rUDdK%~upCgC=7_y?@0 zJk66Vg{0_|oqT*o-%-^3yJuusN2Jo*siVnZ_ezwset++hza=e_)HIVhLQg~}&& zDT9x|3;DQ{^vN%MA6USRAZ*ArA_s#Yw-kb?{I328Jb&c(|8rJuxfIKV?-lCBe*+%o BI#mDw literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/__future__.pyc b/PythonHome/Lib/__future__.pyc new file mode 100644 index 0000000000000000000000000000000000000000..86dae7c5af7b77c6364c4dfb3447296955b0d4ee GIT binary patch literal 4262 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 B3^o7& literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/_pyio.pyc b/PythonHome/Lib/_pyio.pyc new file mode 100644 index 0000000000000000000000000000000000000000..cfaad1f8bd5836e07e09f2f98c772db46e7c9b24 GIT binary patch literal 61784 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 Ze{27HZ$7^N-Mi{Hzp(!c*%z`s|1T+;y%Ycd literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/_strptime.pyc b/PythonHome/Lib/_strptime.pyc new file mode 100644 index 0000000000000000000000000000000000000000..9413c8a2f81a36625e1a8fb9152dfc1b951ad2ea GIT binary patch literal 14575 zcmd5@TW=i6b*`Qn4ms3Nyh*(1vTUt2tC5z}>awD&wXC&P(ppL+N^Vl-iXyk&obDl; zoEy7)BvK{=!*Y-yu#uaC1W01X2!a5~gOeBt5acDW-xI^gO9JEv1TX?4L7oyM`My)# z%^@YN)^8y>HFY^%b?Vf))j7@VfAsbK)%;gxD=PlU;`Jhu2Ksq4drH3%}@)d z=z2yiWRiMTEo7yhRkfU|cd3QEG6g`Z>NZs=N_aoH6D0sfBUnqkcrW2W85m%I#O~fcggZd`#+tQa?^Y%$A2p zpKpRbvr*8B{JJ+4cr_>TT(eSh!q5v%r{S8_cB2yc%|>{(xA(@~>$9`BX5Z^I@pHFX zacbTio-?PW%$t5#X+H4+{ZJS+13X_7kg2fcRs5=7F}aB8H>%B`?r=_-hcj5WILD2^ z!}6gScq`r}z5!>poG9{whKUC%tA1m}bj&acSZP+x$lHv}O0y9;egj=H9Z^euURba9 z!-q3B=I-2|iT7Zycu~#4WLW(}f2AFGX0sicPgkADWPjUP0m7lV>~Y0*2-*;-Xw{4N zCQAY#p`Yx*sa4vfVkl680mj>v2-|9bC|-jUUfz=77U}Fx`Hgr}y}kbb;%BCeQ&CYj zib}KI@@t;%=tak!FV5VzZr!*(drSA_(dUH~rxnBG&~~xD9_>TRsqq{l&&Jn!1s(E} zL3sn8Z~#T5)S4k>Mm;yc8(e>;oaGP~&<7b6P$k9WSOvYiH|)7P_imLjpmvLptaWzr zuD`r!C&W41+KPJ6osj$}>LHO(nTY$ko3c}iB9Zt2pYR?E59|)nKq(?ik%7Esgwb=# z%}S+<;>w}Ca=WC`t=zm+dX(EOm4dQn%fuvH$NpwDr;^iGQPf_-wH*wLGt?3iHHDcW z6Xdn)b92_64<61XqQSnZ{nYc;U1y72QEk_1X3}mrb*xgpJmp7T-K_axbUNi+r}HUi zc{%W&_&7TEQ$1X@>yU-jbV1#UmpgxPcfHS%1_R5c{Rmynxb6W_UFsp9%*8J!>{Z z0fWo}JC0e`DY)qv+q4Nal3koR#-@CV$op~Sv!s0LIaEgj@sg@1!`){9K2LlZ_N@R!@r(y;`S)9(ka7jUn2FIsK7p$Yp| z1JlFwzyxV?*`?LEFHFG|bAXS6Rmr z&I&9TtPEJtOOM0b^dp?xS<{?bg&g1yTBq);duB*O712o1676mVS^@)&X2jz%pZd@R zPC8xP-{j^xwOKW2*3CNB0ptcg5Q;l5=$GxYI`r4V` zQLul{44_;X`8f8V-JqX<-8~4JEi3_LM%48-dE8V9DPCA@U5F05{RDO!#|2dMUK2{i zxM;+t(!FtJdJgGayGzdjJvnz%2nFO^5)0>FaYCGJv+l9&HnC?OWdyfp-E@}Wn5470 zO^t=WhkqNjt$5?DW*GX*prs#%)bQXQh;Tf!>;gO6 zgeSmqm<+t4C#K5eG_9by5;*m`7fhnvY_F_NrZa&#pbz$tE?pIKJ#7ZjD$Fiw;8%KI z!q{B9LpH;c5aIar6a3w__ipO6Z%tMik@eb(dd&dI9lQk8W`6~ zbO!eenE>7%=hY;J2P0l0l)o3~s%QsSV5~s`5<2uYqAq+x?KGm-Z;_z3-E!Rfe3m|< z$`p;fF`Vf$#Fmg+{K(Fr>lH3k*qm1XHWL^cE+Xs6^ z?PN(M8mKO{jXEmuE@4Z`v|}?qz4S5**;_zmC5|q545q>fqybxO(?JrLS`&IY?WTVw zo^|T`Nh|dq%iN+SB8{hSO|WgEcs&UZ0%|X}e}tZp(xI}G#-vgB|3pb%R)mrkMa!Z9 ziIj*a3i+(#d;5fTq`jkEU%8XSZtyPMtP`BB#NsU!uP0j(P%+tL?XRG%iI&+%v;!Cs z_N$`;_5;Ul&MUX5ZZ6#?mw_EAS-7d-jspIHNP&6aqTo7G;6=Y$pszw66GkOGfDe$< zAc+wKMB zUR3V8%DtrAY2{v4?q`*IMY-=O_jAg2$*UQ_P-s+tAtx7A`s?c~)?w$+}zpuZgbwXDBdA}!~yT)Cp#k0Q!h(%O>Ng$sJ@wzS@T zSGVp->(V9Nnw8e&Y28|r*7?i29+2;m_pps9q**@}wHQiCy9iQFbaV70|sv+J>JMKtFhc2w>4j#XrbW?W_Yu)it2f+xY z)vVNZ3ld!qprXq3$1Ey5>of{smKpf<)){uujEM;sgQP9G*eB7RoC%Rlcn_j;Q;!k~ zUg7Fqb1Gg$1=tzRNTPA{FOxbSEE7UzP+E$3#yT!IaJKv)6qx9lEzzM+ zSSETV4xYZg>N)(tLtOZY7tzP4w1a@p<37OKGObXv=E`@&dn(@#?fKWMe-bS=yeX0) z`owQlJ^e<%aZG-P4HLfw{=z35LH!u~-r=siF`nx;#?YHLj=*5Vo+1&Vu@ZCftEg-p zj4j4<1RLfXgDQu8uJ@|o1cUVq&I4)f5L3TNfN^|Hq7SerwAeaa3e{Gla~lKY;AUzd z?O#?99sSU;YQ4=iER zKSGxTfK@JQ9K;Faj5l#k6PbchrV}qbZQI1owq-#Z&YRn=u}K!UZMRvmZHx9j5{~G+ zy5T-x(LJ$*vFQX^M8YB)?&2%8SA?N0ZkbNB+?n!&`Ap$>p-|{4bQg++DPik_0N5`UJ>2xf*n*nFabVyZqTcXU&S}!61K(3Vb7os%r{}33N{={7usvf*``3ao?mwu3@7?6za8ute_L<<1YdFjLg@c z%sN2Oj^UGghX?l!m-Y_JLVVhN3*vu@Z1FJ)o%=G^y{+&at#~`4A8BL~X|YP1nKKFL z)LV$1IEYIz43mVOUK*JUX@kn|Ke*~%yZHFr)cK|D$LFUmEG@d*=TNyKO_ZiIPK$@( zhBOX*rg{yJTv__+`N`=WJys3J;<4M;E@1E?Cg7}?Z_(8tw?p3H`1qY`=P`I;Y0pv` z=uY^>7-;R<#c4oIFKrXQOPndjFvXFTPHfWwLS9+YGp?n})?dABJ>A+pZcSE8@V=LB zZT1>5BB}O)%%&g@uU*2R-u=6syMGu`J8}0G^9Sgy5cpw%~o*jAJGVNDDo<62#O2hH%fJ0 z%8HbmQhqd39tN=7ICXqa-#9s^n7pu!K&`ceW`{x0`q{P-QJQO7w=9#xRO#BEDzQda zN{pS%P1uMDHy9Zng3UanZd+eKTP#nUY__iRQ7U}v28vx{X+0q%H@A#X?XIxC(8DdYqd`5Yd@dRNEge{qU2tv;iL7~`gi_j-dK}e2Z zu#7^F0D*X>I8+=c1b&aS^I`E71J90M8sIEell|ndFltv{AAQ~{@jvBroF=bifSRln zUMq!R7M-Q=v_yx*uL^mD`d)zGs7TUW(DtOVhMb1D!#dU}u42>Heo|!J!Bm2w9EH?` z>0T>@vfWfu{0niVPpJxHa7~LwPbLRx8!#$*106EG zjyTOod~uM$(FshsaSJls6F)>Tot5ip_{Tul@}f50meKNP#_HI(@vx5(c9D-#SMtb7_YDnFXANipS z-5@m4pw5SjEoL1YM4iw4HpMz*q$NIn2iFUEZO8>Dn9b!iT-8PMy~qXHxcwTRC0-V% z(h(E7f7Z9y#OITDM1XEQDOx~f;vC!~^jZrn9<%s73*PChO%}2mDjn0yLa(x=^Z@<> zA4vq|jeMqfrZ8L>^{KTgG|Aog@LP!W%cy8#@e&VF6|sGeYdB;xtHRIIs-b@rf=x3A z2~1nKwBuC82#(1xt~Mg_>qwSW2nXm+@vqzB4IB5Tb_d)Dqj_%0pfY-9?8!FxLFkg!vO*Tlv#dO@un4$ zO?bhDuO`HAnn`kd6|XZ$I$b}~Ij_uxchK5=BPp2^b{rFh#AvpS3>Fp*%zI6#m8aP_ zclxY|qvXDP>BRquOl4F*Z&5~=DZogN$_g-n%EIkt8J&r+cN%-++P&(kp zU;iIPpBQ`y(S-wsD>;3$3kr$~oetc%yjtsK-2fB98AqFfUQp{f6?|#mu*^XNg@<%* zBe78--bEdjMG$HiR{*wazR^IOt0-}W#}$P0ue zd{>@@85G0Uv4T)Qg92_1H)|#I^5p@TKs=E2PbABNi6p0iU`7sEiX8+H4Agq@Ie<@5 z?O?;bY6s||L?Qv@0L$DCoF@cSFyk;++8I`x-_LFjtF=RH-dy@#cIS}VmRE8~q@GN4 zSYa69l5uVZ8$gHyiI;+!0{XRFOlMPLJgBx2pM#ePx`a8P2VN%4&{Q2tN}Ws)-x*b#zKV{^ z!68t`Yw1HtEFv~BuC{UhI3JvPS64Kl)=Xi9xE3Gs0~tA?f(Kmyci&d)-K;;@Sm@fu zBnNS;?drncJn+EZeDtQ;IU<6XSL;10_)ZrxjqWMI4s|Gla$I*$Q)Hvh5Wa!agNW)! ze$WM3#Sm21Hll&O0^gnA7F9uYjXLOxeqD$1(1icjF3i?|$^#BZRdiBPpdcO&=csy~ zqjK3Z=k0ui;2_inSP8EIKry~W`PH3_#ddU#p)tw{ZgPC>l%Q5nV=o0Br3yHvw!une z(Mzacw^#<1GgOK32EZ*pcmavGMfnX1u18ex!+c5(9?j$~#t=VbZ?};Z#txx455{jZ zZ1*vGFk7C4^$TyINZnHA2pA^d>+pNr9>3ATn_uzGo4yX6k-hg7@iRjDr;9of`4+0D zO5rJaBMsBJyU}yLO&32+2)S)wa=0?3(!Q~ou!MO8F*qzR<_M)Guiok4K|E0@2#*00 z{|=!8An@7bfxxTd<<0OtvlMElh;Q&)s{r+HviLC^Q@@77;ts3|iyDhM3&wt}udr}f zfIpO6kbDLZEtiGI0ug-%dXUnU?5>4KyRz0o;!SvhQ90$ez8ka7!n?yvV}1P7wW~x1}>%^cN9?2`%2* zC0%rf*DO8Qg+4hXnE(k>xn;Isa@3Z(V4is24n*rV~b!tLJdX#b7 z`Zh-eb-u1ID8XN~ew&Yc8-h2>?j zY3(}83CW7U0>mdJttD%ei#4L~_K!uH<5!e)vO-THj&u zJr>_(AtL`n)_#Oymo`#+MJPjda#g3iuThpm3L}yO@;d+q;BVGA#7_p<>DSI@1G<_rtpET3 literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/_threading_local.pyc b/PythonHome/Lib/_threading_local.pyc new file mode 100644 index 0000000000000000000000000000000000000000..68c5c980f4e0f41f1dd4850452ef6b20a6f8b365 GIT binary patch literal 6469 zcmcIo&yUMcg?<1CR;b`njrOoyYQB(s&=V~BH!z5W+}25xVaA{j9R?wBJWjZ<*JM_P=#H1 z%_QX7cJi5EvOiPjC;ugSoY5{%ad z{+RWKmi-C%vCq6tbWZB505>&$=QsJ2$pfk^U6zt#M{&)n)sxHi4SeZT^14s!k?3E>z z%8bk0PFQ*F+BFF%Z&P(9{zj2Or5KDeig8`QDx$3b(vw4lqMe|Yl?t)*soQ|jk^sU}<1sF>qP&gmMuMQS8tC8> z4%WBTNm@TI=%}hHVh88LGnJj-6DVAi z-Oe=F3EC-zt~Mnj1!7U;E!|tfX-J;n@EX_Hz;TFX_ep*oj_opvRX>W4WOrC-BTE1e zHJ*Shv0XKF_CdqFnx>f`ZpuytpiZ?{24(`ui;a#UUVfY`ziiY2*-VE*kz3F8vqWj1Y&8c#hMZBVOQe$EQBy3eytLThxfZivw4@SYpv7YK74A zCGoN)92#w#AdXg?7Ttvoj9aFoBZ)&qPe`i#ElqjYW}R(uv`Q^zMI;b)#4j9?Tgz5? zy0&-;1D3_}WntDx*P%xS+=3}v-4!fiGjM4=8?+v#Y-zbTzr82 z{V^S}P?@SMs4AFB%qqm|>e(e%8}gjpo54=%%+*O4!c9pM^OpSgM%L(3};?guz z+iAOT4R~sJpL+g^TLXBYm|*1y#O@_9)nX_!;9s}|(gZFAF#jM@A#6({2_WAhMQwsH zK9fM2(_v+rNdV{JD$lkmj@Cr^`OM5nELS|{q#{_eBoqPDfcUQ+;T(T1@^e*k%*_Cs zw%C;x@(c+^Ie%OU2pj<+Cpb+vCJKrdu*Fc=#FvbK{LXI%2n;B4465K94WY0ba$FJ+ zEQ7b`b{4m3F#a=wI8nk;Wa5M0W0<~xn{duLZ#(Nw+d1Q$TUy84H=RpvOg;3Y>E6So zd$=h}dV)VPAqWmXfOK4bz-K4^7`3}hOh}Q93H!9jCd?1;vKVHL(IH3Ld3KrUjX94g zj0q4iMO3zS;9`Umv<6T(582@~!zS|xbMMs6Oa)PVJWfj$e4D1F{3%t2qm<%IVXv~c z3HAKI=>V}e%0~+3pK)iOU@y^_lr&%t-_#Bi`MmUw0Ih4QB{j)U2-wep6q6H4k6G*uUfY5)T91HFXoAy-$+A!wtwrI%Z&FkTzr5 zawGf$ex9765P-%3Oh9@k$7g59!GNuYKieaOfAHiXZDS@IM6}3nQ14EDUMvA8N1iBC z5-FTB0>)`fdt0D8M*DF6Tf literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/_weakrefset.pyc b/PythonHome/Lib/_weakrefset.pyc new file mode 100644 index 0000000000000000000000000000000000000000..f87566afc25d4b0a11b66e698bc17cf2571856e4 GIT binary patch literal 9438 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 literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/aifc.pyc b/PythonHome/Lib/aifc.pyc new file mode 100644 index 0000000000000000000000000000000000000000..0055df3480dc7623f54715773c095f5a8e82dec8 GIT binary patch literal 29358 zcmdsgdvILWdEeOu2x38iq)3n;DO$XINL`Y5)56}DYo$qzN^PQ`KzaAU;!`WA7D$f5I#J?x-i(kz< zS9R_Z!knw-T|MV6A!6~oyOej;0aqP#)eUZ8z+FOoz(s>@9u3XxavlC zX~X)cGVF@3a+|Ikr7uNRb-Q^j=4*tuDV&tF<0H9$YxjFs>l{sy+@I) zuDVT;dt7z9BHLVbT#@aX=nhvOcS}3mr5!F;-Rb7BlnEAVYCBzZm$G)JSrabW<*Iw! zn^@{@7wvYJ_PFR?SH0I=&AZm+ykGoYcWJMS_PQ(YbJe|W-)L(xXQ?aqx$67e8#$M2 zxU9nNOZ(VYw9i%Vb8i50fqVV0U3H&3i>$NHR0Bi;cV$1Ph2(xq9`MNnmOSW_2Q7KX zCl6WjexJPGk`GwYPw@e_uk~y`P3*pO*i{dsB7VUl&{eD+H!t|x1E;{N)TL<$OxJ=Z4h#9PTt&pDusxa>uTjyS?K8R6JP1)$wXCnvo zW{U48rkx&lZl>LtpAXv2V7c6iqu}JZGiM$;6_guQMT7ZTJ&KQwjJ(*uzi|-VSgzM9 zwRU|ah}-3MR1KQ##i(_?7Dq<|#DZ!RS6a2@cCFb6=AwG@dQgjlcB>PO%%Ns5-)tpA zsOMV;I@##15G*%c3SircgPNm&xMVM6(y#Jy8KkrBG&EU-W@P(l3&&@UJ zPR6y@qbIYt*Zvd`g>Sst_JEGZNx)O z+m*r$kRreia8C~ewMN{I%Gj`Z<(xVI_?-+iyP(o+#I?8`v#{I z2?}5>t2FL`;mpkR=>&$&`S~~^R(QZ16~cC6qlNY&INWlpxd8Ab^PZfmH!D|-t=vT` z+lML$+q40>)`(&No0`KM>SwcOJfi zv|X+i!C2xby2^jK#!9^zM@5k6xkeB-F`lskj@qf#nl}BTLCqs?)CN@*kN7S*U$P$V zbkGE5mkU?<<^S058AXMh@S=+4mc&4YPnJI>#WqvkdfB`0s$anQ_Gz>h|Odr z1m{B3ZX{%h2?Y;5ly;jjC|g5P4b%kA*Xkk~FqNfdqj@wq&H|tUcA`lfMDHZW>$Pfo zv9EWLX@p6l2-7$6v?gKzElBm%n)Fb%Ux0B8)?RY~R?XUw?zl&4)V1h-dJKw(r_WDM z9oE7!O!SLmZK79yFSn(44Bqu;mBEMyNp@7d&9G3B%1gwbu8Eg}b_X0WAyR^g*jKN6 zj@dhMd9DeJ2H43d*SY8@PdMH$-0%Ta~GzY0AdD7MPb?S$)5tJRNvp03nBmE_S4h(K->3D%=XgE-O+ zH4NH>+ygI=)Dg_MAT@)Y2TJFLsR@(hUWD0Pv`}kES_8@gqQC$y7?qdM7>t@Ej-OUX zUXe7-)|H4>)Ne=ix((GeKXqK`v|3OGAdpNBqq65V!X(U0N!3l+Kv5hPBCgZu#FRNl z#NLuVJdJz7p`lG}PAe?bz>GO#zmOwjbK*^D6)aqPsf{I~5pN+pDdETy#WaD>i^N6r zRBdW+)d}Q72aG@M%VQ$Bw=v>miNf;2^ zZZ%h=fz7s{!mLk}T>oi`lIxfkmJTdr1vjK7E?x60RxR4n@zt{RE1WSp4YU}(U? zI7nxisMI^Mv^_hL^$xSnG03LSe`PVS-ffX-hY1t%xNy6g!iAIx_s*~jcq1=2J3)*! z;kcQgRo6z(MbMp0E1s{lAd`Bb2H`r=mE%varax!oWkAkOvyBKW6BvMV9frjD7yuQ| zglGUy(KJk;Rhkepm3Hu2x!&5PE0P|1qPtgv5{HU=4gKPn&({PyTB3e zXmT8&(CBVnJbd^F0h??z=HIi)JUOL`PIB~rfeH-75e-WL2#!LjvC^(BMc9;c(gwV? zgKQI#M}rmYy-wJiLONb~9yGq@)PEw0Eq)S57 zVj-g7np)kGDqb8AxwuWJBuqup3ltBy5ek9@3=1m`LBf6Y(uoH&lQ?UUL?1l}5o&Ma z&vbhOY>HD<65E4_ae3__ADLgSAf`V#giqra4{5v$p;T&* zD6!P6cIrr4Eo3>x;xWXIU4FhccbOAEw!9Lu>}n`iAHY8+KH{eGuEKHo<1A0% z7jqIT`(4|)D>AR&L>w@T+${~ zC}~L@uIYtCPnx1)&*EE{#lNR;0RTo8iAPtJ(N{E1# zNM|BA(pk=ZBIj=EZi`nv50dOYk#~(Pz8Z>HC$Bm=cLL+^TebG#RU!|n~~H->ODcQ{u-Sjdm$_T?(XCH{zL+Qj!E zLX_6dP=E-Z0VeEeu1X2P>Rv)D7P%NrU)q#7i`GENpqk+XYjBx2)||c2Po0!RfImPB zi6QrHC;5yf8FFF9`R+q3n_IY#N&Idnh1=Z7l1;6nx&06s@6Fum?{;q5bekLH%U`@_ zGkgBs&a7)gCHnsDDpN~Y2S`w?L+lYKcXiOUpv#Dn0`aJz7+U5X=;sQ&1;8zkqxv2> ziM3*^#MHD9oaO|W1i9>r5F0(fn_z>~B2+}b!fJ~6>Dt?zS^xf75X#1@kt{|8c{79d%qQYnTB zW8|V3DefC@EGt&8CNVH{e+(g!hx^eeJjmu8OdM8REPRm3-3)dy*u&sn1lDmXOy=V| z3X?ACl{EQF^b&sv0i_A$$ynZG$`B;Uj@+T#2=XXXMuCY1q==8Bz($5+_-n@i5j;Hz zBoj~Km?P!5!jAbz1ciTNGO|dgDFF3NL?nqAf%MKRM@)b@z{x@70ChJg0u+(&&?Wc> zZB!2YgUodZ{z2wC1pgp&9fFIHxemca$XtiuA~dE}a1k=^A-D*c_Yho!%zFqfLgqaL z7a{W=8c)23b|l_Ia1Gj_ekOP(+=(SsC_IPpBc~8;UPKOMEJTbr5hGZuxLs+0iUo79 zR;vRVbtCDPf3L_x3XO`0rLeBNaLGrY{MyYvyPbmjYrH2JY8}U znxZG~f_U=I9EQ09_1G&IHteWtToE@IQKd6E6mvRTlcj9(lGh=H>*LDBt8-7xJtK zSY5~iHLzcB5d&YmIpnTj|FK7i>{MqH#IJFtcPYKwEew&1vHc#xkr3aJXN7ykGdH@) zMlmVgs^Sl-7^?tgv)DG}9!|-o0Ut7Bb*Vtx1`L}P3le{!2T>d#PsYylb_@5tE!gsS z$15MBT2%*NHK8>>iJTJmipf!Ux0qORU}Rw}Z>~{gx@#yxpMx54T`BsmC_>+p_z<#L z(L3zGfch}HVhf+MRD*S|v0!|ZM587ZIDT~9Y~s>QrcTV}IQ<3W6;h;nXJ!}gAfaJ- zqX>!tI#l6Q1A9GZR)VJxDzz;^OEYZcrmo9*0X9al&JuwZ9%skwg16l;=*T>y1DI8! z)uz4Gx?Nf-$(cv&4cLgW;kvz(7c#bk=cmuB@0p8J;nexkxoQ0S{M5;hPMsF)W}@~5yIM|n zKaT42c0i>B(4qu$*s7OwMx`KAwg9^wsqk3@I?wu>4kT}@qLZD%>#04zd=MfeewB40 zhO)mDOQRA-6knrxmJH~(9l~h?^YAajg0IE;Tah=8e;F_6_{&2uerPXNPT&vVCszI> zBB|bq2)FfE~l#D?DY8*;O&&?&pFlI?A>x>Q}U1xGz>J;jSClIW2 z7F=U1;@vyf7!M*z3`rN9PUHh9um!gc_z2Y8H&ELPWpF^Np@WDoNPxq|hEE_6&7Yz_ z&uQ@+x^^{N;UvomJh2SBFd!_#JApAQqt*ha&h6vWiLUAN*~eP@bpqw%V9o!i;#g(v?Nh@fjcZ)dLu;l-DKP+2)a+P6IHT!Wa#Hbns%ZNyt z5%A-LoP7j(vgP222YqQM<$UZdtT32o0Nvb$5d*4O;Z+3doH?Z(0A_;iEzX-=^ANu+ zqqUSH1t@|z@v{a~G@-Ivh6~H}RynDAX1KW@jY1qVomkE~=jDmRD?-1JO>9SQ&;;H9 zdL)B5gaaIX`2&`n$*?Mja|kXRu+qCU?Mb`?ouzI{)M4T6(Bjpl^lCF0 zqm472@&sd)aG6;5X5+ODM1%wG%rVffW$U|F%8S$$N~d)9{sR)k9>~S2M=lTpmiq>@ z5ko5&P^hn%9UoO;LqWI!h9aFJTQ6npc&N;~3ATlJL@$JciOLjX+l0?d+O-ELy5k7e z_mFFSlV>%C7zzg}JGGj*M^oUrSDCCZtZD@}zGs31qLV@371wBZr2~i*sv?nFKn>3# zW(qX4al6+$!7SD&nP9+;eMo&S6dh5l8Q&)aC98E1@S-P_zIu&CRJqs0L5@Ks-iG-S zw`ni3DA0MmvK3~O32fLX2yQnt&22EPXzRG7bnB*(0EnxpK@X5H1ye>ZtPQXQP_ZN9 z)Ha2ctg%6MFqIj2_pl;wnv4`>wju?{FeMe-v>B30qSs5cu@l47FP=Grv&GE0OH+cB zK$s~!q4WVxTQC!JtW!d4O*qK_Wk?Nr#Qm#-g(D?!F*Y~nwQ%4^Pyu)BX7EBt_b}a+^6l@7TLg5ET z&yrm>et>EMz}dqE4^nxi;Z^N`=FBvEisAs)II|Mo(7Kcd|hj4zv5s7LnbVR zcrAzKIaeByY7aVraZtu$b~8#D*4mK6JrL?#*{ss!{vb7{oxl+6_CI^`+5}2?PCyF? z!2vg6{retZF@j0SOvtDOD*y`oN?^JIIm0Rm;}=YMbs3suq-6iC+zO15XbjrlMy@&A zxChp@?XtGL2xD9BS}XSwdl(m7V2r{71T{37!C+bYoiv8eHfm}6zhZko`nbCaX8hya z%8{PoSURy<&$HKloJ;2MBhBN-xtF*$JcZmM+Zm03wz3`SyO4(w{mO1#Cmc!^y;DVp zR0M?rHx00Lp^I&@b)h~4u?&q|6AWVL5T-B0yB2z_o`(q%@MAt8w_OpKZYh*`Jf5x* z4<#EUo@->=X5re4*lf8)pX|qjIlMFJGE>oytH$=`BqCZHM3S!kk|$>$JAPc$rqqki zpPW^MEFnIKiWRe8k^gtO=XaaXVl_CKv@EkFr_^c0o#ka*0>IaadUp3qA>Gn<+r^@) z=?!n9VfYq;Rg<4#>1SC=i&?1aY6&`8pF+UOM4l86JYottjgY625H#yTQm~kY%r*p# zNzz3YZe>885XKC~8C+o?2E+l*Epat=HTEf%NZLNj7%u~*2dVqBk3ITmNuVT$QcB?A z5a;2Pl}Q^Muc@fj6nyqOV zbvNS2YZClmSCXA7u`l(o%Rj}yDZ2#cT3K*6UZoxi{si7}`jwE9KC1yfnQ&9kIrhu2)9F5f%2q= z^(4Tf$)&zcS#`Fd%fPeXb7wI{yx&cn%&4bM$NLecq(-x_xBbE>+b+WgU+?2Ym0^=h zCoufcM4ABI^hrt0`Qk8&guybaNU;uu#^WsD$w3%UUIxOL;Z^ENKbEkYh93fO1)+!F zU@oL;C&JX}6p7oS$ulT>n`lCsg7h000E%#{@pteLHhK`h9d0B3E$WVL0M$Y=5t;GA zR~Y*^11QfQjsni$l(_h+kK* z3c}M4_BMX;Q3OMW3Lh*K3Im0~!Vtpj?@(a_{tn^qcwr+-3x!GPfV$d~UjiqtKZNJg z_{EPShL!Lu0RLay?ctLEZ(=zRQu- zT>zo`P0+Y7HN^}ME?w5@>vJ)u^VCyM z)&4hRW4r+gx&E4r<^G!%`Z2`9%M6%jh|fiIDctfJV*k8(xg*t)YK}vhj42do$sWq> z7{DDhSnp_FutK5yoCK?1MFKG4szBEk!J;jqbF3{Gi(~{)vIs8Uq=7@T^btVBa&WzB z5onGUf!<*eTq|2-b8?#t?ay+c$${x&2(OzEV$xMhq*uQ)IDi5_haEBu!DUG|?+}OFULY6g zWdPNt<3|uy{6(g`*YQ|@Z&mD_j$HY5D@$K?yd)44)!rL)FAy zG8~$_cW~Fc*+DA3-IMO!J28ILSnu9Z-|XCJ@9soxxt|!daV3(L+$vdB^^UWDqjZf% zR5R->NiDr6ThB(Nm0$1OsCPwbl;hcyd$&m^ZIrKfn|LDl)Sb5J04m*%#E_o|D#GcV zF~5GWL+*9aN7!K!KMQVE26T2HV-r;3&-AT_w3+u^jwNEtZF$>4UV<^(kdmi=mhaHx+U0CPG;1=$kcmLGb1gO3M&f!;JVeS-@pPP^QFAXPXmkYiBk;=fw#zeI$( z8f*}d{kv$Egx2kKH66C8fj^@BL<8qhT=+}nRJh9vkc+Cb!MD9JO{*r2nSg-m0Qpb9 z@|Z4=r2`t`@5ab-L4YGMvH`sT8aAyJ2xF3nf9;B!wH$)9s~QQ46~sHehXSwg%{GWn zo^^lcOdQykq<8%3chH^)9?|`CcP+BVw1=|)=#|DYT>cn_3V)fw{S0Wo41WcInNNtz znO!pcH70+RrTE>BE6I2YWZ*Rah`UF8;q9FLrMkHn2JM|W?+G!0(sVB;k@y?+^RU&@ z#I@EMW&8YIhML~7BVq9#16@&LZ0gcnURojXaK zyU=0g(D@HJ443G#%Vut(i1E{iaJg7FkX(x_DObHa+2Eg|Njr=t%p4%kjC>QoJ5)+p^tv4%eqF*V(rB*8{*%uM?!VXp^LwOxi z#ItlSbQ0C=1(lSMFC%H1rf6XsOYf*!ZbmH`Q%twSQ~$pp%$V(9q~8M$PX7zMGbb36 zpWyd2G6)i}G(wIEtWaPBkBT2vJYg^7T6mF)QhAW|*`kOG;kOxREr5&*e~ZDF5tz+Q zUym@bWQWT;`dbSYZ(_tPOXLg6(XFcjAd7cT??;Suv4#p!>GK2RqIE@TIaWN?@E~B7p zKkwwIEnDS}xQP#-A@3Xqac>CSBEJ*($|qKQYBi?c)&aAS3U>!ln?G$aFO#rM00<d| zaB5~|>U62gdq^jT1YWv)wzEe@-|F;^ZbKs&2Cq7nmSv{?Ul|3ALQ}bK71p>H4SK+{ z9+x4z#wKaOP3SleQT^QLXHmA6tdb&GN?O0od2+{o>b^qZ&tcF$2chtj$TMa$*9ZZ3^p+X(l zEIglpR*7eA;JwdDkshMPc-9fV=BBR9RAOSfpvIZv7#2Cb+PPl)5q}uPJyyI#r95umULuyu4TRq^ z;sY+8>hV3BfMBA~BPbFVd)KjpYzIpmc zKN<#qSwA$dG5C_Gx4Ec$J+=rty+~3nqD#BBLd40pP#0KT4BG1w8Iu)Xq5mKqRMsL$ zasExj&O_`SOmz!>bjsl0B*uS}Uxo66!kic`R{Le-7}kQLP^H|bq!a~jTBGxoZiDdg z2#BfK#;b6yz=LT>zF($ug>Q~mf57#(+)9vCm#-R2#e98lv)A5An}3SUk(SRDZYu4- zDtR?IJ z36oOZKf)M04QCkqF@x_Qu(Pg&yJn#Y{1QuFVsJ+>&)YS7!Il6JpA6hb>U|m|RF&vJ z-Ro?%nyVF^u1V3P@#JCOR=j7g5a{SGd#8OEDIy(=7WXRxc>*Gbw6Ua~kt7ezmiW z0Gw(Q&o}e9ddAjC;j|p&~#suFBS{6g_-mUW7&%v=b%N|!{rU8_Hnhb6x zK|83m!7SA=!=2W*;jKaMo^;*mBK}9xPr6$Zw=4pPuoZ7Rx&aG^+||;6%uJD%GIL`I zKZvNg@V$vx-~EO39An3%HQl;~Kf`*|eZs%R;4u~qGxj0I@Uzb=-OBou)64a!Pp+q; z>gd8_7h1@%!dz&+%j8K0Iu2rWp0SDT>C`@lJbT5>$IK;jf+_Lk_-2%xgp+*@pUbq5 zz{m=B?!0-uPO>3Q7yjEqUCs4z5A);+SZkEE{GAxP4j)B^G2A1J0U!Jv^k_VrL#D0k zW{q!ttx!qu&LvB(sTutVdY{4u#XL&V)J?yt0t_a55Q77(cqhL+vjvZ($M7&?0C7I6 z=JAvU6*|M(zuQrVPP2Hxk)Kf8?Wjx6y93roZ+aQTDEytmFXjo7$PA31q;RKU2}$wR z2_9#mO%1pc^m0>-d7wd#v?032CI%Y1w9zFW9c=)E!#8Kpcmnzkz4V3W zNc(FM^9?5^36E>s3lr^}qxq22h#<#slWUx~nX$MrwwXer-$pV!*J=-_o7x_P{|2SX zqbt`s_T~Gie}nrnjtDhY8U}x^5RA!6 zm<#n$1AEIvS_%7VmG~$FxrQTlqt(+J6x05Sh9+cQSxxZfY*1OM;Pr>0QKJMa7nvI2 z*!2os8(*ZU$M^%;K%e2rta@ndEq&a5^N0T)W8A**Uokky;7<{B;RX*D_>3}%{Rb?* zlS(A}(_6%b#8|{jsNHZR=OZ#cm>Lv?k}`LKPU)3g0X9g(;o45&7w&6AO;>FO^Ds$r7A?p;kO%!VB zAUI4gZMI4bYSR1KpUcWPqqC?P4?`ZUCBKX-aJvj8B&+U6(ynbp_Yxl3W#K@;QZnu? zHJBQ$+}!(acGl#~e}qO~;+`Ks#O@dPfROxj7k2p`#K@1O*&-|+;vlH+J}3XD zVet1De3ilPGN>^48iRQTx>a3Z?DrW&48G2Q%+S2hzrk3Y!8aK!Ggx9E;`laWf5@QB zfX4tkbLd3!EhZ&y|AevcGx!4rTw?|V#cuT*34a~6#`A#0X+(zZD~uJk!5^Kz=?s(K z26(Oy>o*FI^)dXIQ^3D_@f$?hc;SJ<2T-!Jg3fdaKyaPHFXlRle$f43D96pEBoR;- zD1-OFhEc@aN61VNff!AgpYhTMgfqij7{ZZzS?@9R{mU7e(`B>52s64RnFeCw z&aqjI!b^x?KuAG_*TdgHTn9-Or+10?U)b>fV>8F_Is#aO4qu-;Z1#{pV-qe5pB3Rh z;h!fN*XIlqCz&hj-wzr400Tl+$3kl}!6ZwwJy~TtIMZ(eaxwKAJp$C*mQe^O{PMEO zluAo@Tq(0NSpADW6eQUs3ctm4BK@893u&@mn z`ZT^NbgcMrGAsBBH!Juk3yb95uBN3DzDtd7KNpZYh0h72N`7*f-=VY#_oG#f#We>Q+sBn3TOPgc+&7#zx%cjJ7k>xDB~#|0nG`*iU{IZDT4* zLwqQj-;&=sFq8*5+TRhx?@1q=3>Wrq&2N9(?Zod(qho53+YDjG7gYS7kD2Q%qyS_N RpWqDOUp~4S&u_vQ{}(?9QnvsA literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/antigravity.pyc b/PythonHome/Lib/antigravity.pyc new file mode 100644 index 0000000000000000000000000000000000000000..4ae647eedf62ec4539201c92e1c0b0cbd203e766 GIT binary patch literal 188 zcmZSn%*(YYJRvxl0ScIav;z7L0>5GrATy(+q`*pFzal$1MK3u&SKrvwSYHEVTnQJDC{ImFD#|Y}PAw{70dn&T zQu8!`Gy{SF8=@EElbIBgm{*dSUX)mtSyHK2P+7tORA-Z$pHiBWY6mi~7)0+~a#$onyK@0mMy&OLYQe{aWsJo@QDLd(AWCo#DxMN#zh4&@PjZ=2+QCcDZ0IgxG9@g;seuCXIq zJz|sJ3BG2X@vr<+6U!|&W^hEdL1vRoOfPHH+vaEJ9de>k?v*)VgtMI?h`n*^15rLp8#`|-XS0cl?XFPt*7 z$pG(5!~NJ;1Z8X8Jj^o zDaHue_aywVUOpjE% zm9%)EmA5)-uD$Y8o20|kn*9};L_JTlEFM_(dW?*!Pj#BOufQ|#j#GYsIp6M-sX&pSFl379iF#h~lg(7y zsbh5*qc14;;5k|HLg}f5v6NukiD~;({)M z{*e()h@RIeI;+zenn^^@8+6uS(LUKA_Z|0@vxrWh^0&Fcl+W&vLXDoU(bEMXJaiqF z{j1{Gq>~!CiHxty_!eO=z+~_>I$NV-T#2F1&`0WM2b&xf$9f;?#}c$ur;Zq&P zYLuSB0D`#3^1cV%;NrPIWjg2#x-gnCJunSH+fxaI5jxd!Ef&ZhtuW#1)j{oSW{SGE1PyN0r5`@I; zzxyn)!s0S$UROlLmzJVQzRRCY-EH<~p%R0x!11p7h)z;)C|^d>aYRq_ls`ShCCnh8 zT@LbmAO9&%qHUi86`vemd<-A2aB0@A)ZdFXqh@V8sz*D~cC;Qf@qW41jCQcae*rE0 B)~5gf literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/argparse.pyc b/PythonHome/Lib/argparse.pyc new file mode 100644 index 0000000000000000000000000000000000000000..961d7781557ac7cb4fbed8aaf965b45e20c125b2 GIT binary patch literal 61934 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%0AP-uzJ-+WfLSuB%9fw+ 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 literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/audiodev.pyc b/PythonHome/Lib/audiodev.pyc new file mode 100644 index 0000000000000000000000000000000000000000..4efa711efd7e4e7dd0a09cdccdbf892fecb35e42 GIT binary patch literal 8063 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 G*8c$116K?H literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/base64.pyc b/PythonHome/Lib/base64.pyc new file mode 100644 index 0000000000000000000000000000000000000000..fce23d0014c0a9b6f92d6bb976e55f7561cb7d49 GIT binary patch literal 10798 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 literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/bdb.pyc b/PythonHome/Lib/bdb.pyc new file mode 100644 index 0000000000000000000000000000000000000000..151a7a4c72fbb16d1ec2cbc332c84e358916c65d GIT binary patch literal 18186 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

)$b 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 I%3SUL062s33;+NC literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/code.pyc b/PythonHome/Lib/code.pyc new file mode 100644 index 0000000000000000000000000000000000000000..427596e1cf6503e3ddc3633cfa3d44cf4fa5f223 GIT binary patch literal 10093 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 b_)Xa20{eOeG^^X{u3h@OE7`>ld*1&66Y|GD literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/codecs.pyc b/PythonHome/Lib/codecs.pyc new file mode 100644 index 0000000000000000000000000000000000000000..c39a3321e71c6579844a9db95d8bd9bc494785b4 GIT binary patch literal 36115 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

-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 literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/colorsys.pyc b/PythonHome/Lib/colorsys.pyc new file mode 100644 index 0000000000000000000000000000000000000000..72e9df8edf3c5af6a6ba466c703673f8b5f5b434 GIT binary patch literal 3871 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 E1N;v)9{>OV literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/compiler/consts.pyc b/PythonHome/Lib/compiler/consts.pyc new file mode 100644 index 0000000000000000000000000000000000000000..4e2ce9ae2ddc3652a3384421704d6a654d29bcb7 GIT binary patch literal 722 zcmZ9J$!^;)5Qcy6OKitUdg!sI!lyhzQB;u`mk3P?Bpo$G02K{$5ReTOdnnLDAF6NG z7wC|78aNX8Y384W9IEqoI{s6BH8bAf$zd~;d^jB z_&!`8egHRsAHoe&&M4)KQ}h6S1UG>n!%g82;AZd>xI_3U+#G%ecLaY3cMLy=JAprf zSsc>=!ib=XDl>+!SAf>{=ZyI4_(t2&;$Zbx(?x)HsIend>I=MnEBXc5S)WB-jb(1Bzl{>r~2;pI~fm6XilGgrYrw&|LA|*-F}S! Spm|T|x9DvrMr+^RD#U+1L5S1< literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/compiler/future.pyc b/PythonHome/Lib/compiler/future.pyc new file mode 100644 index 0000000000000000000000000000000000000000..096d74185b49cc1ba24ad21f093e730cf30dfcd3 GIT binary patch literal 2806 zcma)8?QYye6uq{SO}yEprGb=!M9oL5tq?`6Pz9(UXiMo28dbADB37x4vz~38?Alw; zY??^vAHoChFuVpocorT2&bi)ADixw^;_I35jPJc?&bj00@74AnTfg)MGW#vy{v9s& z7fdeFhYchTWfaIblzu4VNcxckc_hE#@q*;|UzL23-D8oT`-_sdBwv$!>0}7~Wu3kx zc3JXR_Cl%u)HkW&y^Q3Yg!hAD!1vV@Ob;kop68*Q4TN~ zYzHJbAG$_}|I}Tx>YQ_b3ZW~@657<%HdR3` zfy-H87}`t=#5G4rmX%L(J1k0@tNywKz>v}nWYAN?z1cEn$RN+8dxxdZ4t}U>u#X(x z&qhT)6VPk0Dx%Dt+Vt#YPGySLIfQB6!L+Nm+$AmuI>81&y%U zLWO@IJST)Boo2;pR5+hh!(^UQV#{o2gp#y#_(oN7S~r`lnZ=$xbjmO#&3Q>ee4bh8 zumRtFihe`Uuj~>aYZcZwHIG6M^O6U*tX-E&u=k literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/compiler/misc.pyc b/PythonHome/Lib/compiler/misc.pyc new file mode 100644 index 0000000000000000000000000000000000000000..94c2cfa64cbe2129cde70d50f8b522158306dc52 GIT binary patch literal 3448 zcmb_eU2hvj6uq-{+&DCpCT-I2RRfAJLWHNjwWu^i2nZHhKLnzp!Szm(jqSCwGiej4 z6%Xl8;+0>(&*2BaIoDaQ)zFYcO*FGJv*Y`5&b@bURy zG5q(Kc12zoIeH+^MZWpUoPLB-sTR3Pp zDZkaE^e~4h^=alqC+oT}!?VLt--T;f?ese#xGdDL?uj4%` z>_sQPgw@*P&GgCR?r<qqt=7w2}ZWy;ob(2l>$gbd%H%YU*cES3b1Dju z6Btx#!c8nDCSY+NoS$XkDrQhcCrK8jw9~I*lmMvrWT4cn`ZPTl^*wj&H4rXA0m*WG zH$X!9TT>M_Uxk07o#8R2AJ{*5W7soTayJ-0b$6z;6Z*n` z^}T@uBmjU%0fPY`VIMWE$OnU?A{HvR8q+IH2rW{FqofmDlM&%xI2DcWH&L z&a04giUK_))J#2^{?{7a4xMhVi?{kmFCSs}dzh|JCs7O;*=Nhq`#9Y#is3jYKnNCA zD{;XD@m90&73uc0PK}16OXi2-*nlKYCJ6pndx-7p%41BTVg}b`6%*=DFkYJyq_6Z| z3$vL@3=KCbjv10=^j)Gr(&f>i-&@7AFrz3-6u-`M+Br4@AHS8hDr%+w;BV~l6?|8& z!f^EIlwRs9#w&V}eb7t8T2m_3e^xh*fiz3pQ5o###Cf1Y*6zBH1~;(wGi*qYw3i7RgFdl^%Mvlr0&$lV!X- z*p#iUY(c8%DSC5~|1QQD>iQXIB@t!K)VS#NJKn3pRJ*5uW~8L=yf9%g9(1zZzFVWA zA7c`9oa(pjZ+0}H^kYm^eS%OCiy5Tsu-cZB9U2`qZZk@dZ_pR^#rE4VSUWeg;Q>5rcc z^IkvoK~JgbV(@B1>VhqFD_BetiR!4rH!xbIq$b(W9)A4oWm?4_apIl$OH5Ojv6J(t aoyGh6<1gt~BubOBUSGVmIA4qExBmq%d?)_^ literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/compiler/pyassem.pyc b/PythonHome/Lib/compiler/pyassem.pyc new file mode 100644 index 0000000000000000000000000000000000000000..0d32efb0ded9d1d854c0d88a5d26a9b0370169ca GIT binary patch literal 24734 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 literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/compiler/symbols.pyc b/PythonHome/Lib/compiler/symbols.pyc new file mode 100644 index 0000000000000000000000000000000000000000..7326d1cff55d85199a283c495dee6bdbeee89ee2 GIT binary patch literal 16837 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 O?ewF32O>%M75)!Zwv#vj literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/compiler/visitor.pyc b/PythonHome/Lib/compiler/visitor.pyc new file mode 100644 index 0000000000000000000000000000000000000000..16f36584a6b17fcd1070fe91876f47cbe76b8cf1 GIT binary patch literal 4037 zcma)9U2_|^6$MC&5*52v;>sVLv_YG+qFb3`Coi4Y)2So7bUGcyv+~5Q>dbbv3z};! zcj*OaSu@s?^VUvZ`qqEY_x_vyjK1WpJ?COcT2020On?9gT-=X?bFbU~Ilum|M}OW+ zRrA-z_ixeMpU`FaXjLdR(Q02SowZcfQ(0Smt<-C!{xEE7x((>ke~k-e|?RS=e>#Zp38Uk9)6j-+*kENE$;aY&HWmkg%n(f z9`{4Dwt`|5jVndB{T1rP72GO%;nrxc-=&22I!ZmT^{A>R&Lk$YQ$M~w%4_G%QBoY5 zYGnM_8Yr>8Zt(XoOd5^MQC<{bW3y}9OoOz%d}?ft)f!@_wXNz5!>Sf3)5^gfF8Dfm zVQZHZyxNu-k5#2P8t3WQOspSQnaQ0=lcKQMAm|X5-KRlRBf9TvYq!md;HqnhfWSR`kADDI-A(i z^9qrY%sp5p6PuYW*+|nK9#8ESoNQ}r=5xB4LFC>h>>`9WZXp6i;@q~egQo+t!!fk_ zJbR!<{CGFeTeJl#xz3dE#N1qeV)#Wq!tGl z5B-6O(xg@C>#8v0>L~baoEMqw0h(c)NQ3Fwtfs%;KqAo%6Z)USl}WjUK8O-AR5svq zd2j()p4>JEHce&@L3_hm6DK2Y>v$nUp3oQ;S7|y!M6yP?$uw~a_}V~k+~I67 z>f>8U=dNNjc=Ct*;7M9drg>rOCk+w?(__DeU*kA0b05b)!`M-R(mkD0H%{1wXzo|& zUVfxrY4uEK`R-Sj)JdDFKGW(I1}*hhkoWWR>QS~-oMQZWbWg3{p?ml$oZOq`ZkqUX z+~*b13cH1w2$Az#5|^IYoK>92>?oNP{udZF)?5tM&{+#>W|+VfI$8#>p)sbVp1~N9 zJ*;f0la6`?zE|pSP1R$rKU+~JD+;cs<;XG+vZ5|?vZh|Qn**G-xchbq@sNRC;-9@f zJ+dpdNgVn;%!A<^#j)@~97j}D@)bN6i5o+(NF#CVX)1n6ysu^41T}gG>ym+%9*rni zZagHv2z&@;&vm(O7c$T4426N z;Y}aGE%>wrIq+ogj$`cZR?FnJNSGw^nIqve=7yIMy^8~)S9A`eC7{Gqrhu@6_MX*D zf#^KF-oimg{HRtBruONA=mI(^B;puUGb`p%iQ}wFn+Sb*FZ%3@y?YVQN@#+XeD6y| zWc2oj8j%Jl#L>X+m2Rus>UHq%T~FKZy-X(4!oIDd`7yS=S<&PuTL5z1R5U1Ch%xtX zbPqu3NF+801;>VLM8+YRCY~99%q~H&**rOeBb%^X&+42R7%Np-9Fr(VvqCa-W?$H% znlhbkGf|>M@LNvEacqkzw}DZcU8dn>g#o8wE zBIvl98RuC+jZp-Nyejao&>Ei(Au8}3!m~>v5J>Xng5?$z06LHTp%npXkLDgWLD{%POQ|GQ9ut4l#>^ueG}S)hFr%JcjDE zrLJaOb%;y9VF5iv?TqD1L(&`+=#mPD_n&{G@OdQqLFhY6<@UgkdqQQq@&th{)ZGNF z0N!)zIgK6rp5qJp`SqJ04{m=&s(tcMt8n z)_P5^V0}aXRCjb=vKomZy3FnhJHABm%JP00eUB19!m&GO!b9C|S9e<}Eny?s?(jE4 z8gM~02+%9^`D>+4S}H(_>pfN95MT)jb3J4{c?Jlx=DdSwGElq00!csgY)mS)b;KY< zWHE_JAl%LQRLYXDF{CD2A5`wl2}a^0$01PoPKmqe@(nG;6ZN6pV)FwGh;ck=1+shXy2nfVE|S-yYjg4$UT07Dp3aN5m;Wi9p&7Vz?w5=XG4fJ(3tAVk0u_ m=$Yt4b|0ZzDj=gXXmLBFvfnWHZXMmm%EeokKJ4lXYySfb)pxc4 literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/contextlib.pyc b/PythonHome/Lib/contextlib.pyc new file mode 100644 index 0000000000000000000000000000000000000000..61b31a5fcfe9f683df6e62860ad74a2891b091ef GIT binary patch literal 4394 zcmbtX-EJgD6+S&Z9(%lA>`lVLDv2n82xCM{$PY*>#|m*)As1Myc3?KvqM>KH#%{Z( zd$y})?LqdM-6m)kv=JRyGHL36)Dmx%134md zWL|dh9)kt3^U}wrrhFpuvB*a|3z95yveOjXl;noK0P#g0o9tdX-F<_+w_7)Pr8m+2 z%%@rEQ|nB>D9vH&_g-~A_I6-%Z+b=U?U8qD#%x<_?%%s_-gxtkwe)j5Tde@c{T#Z( zG9J2WTIVz_bN>|#CdUVH9`D-HH?Wjj=WXKW`8F$Dn(z9rVf?<$Z5jKb+^jhMv^sK% zB3ZqQ=2p>J$O;6|*N7iQ4=EJ~b;8NPoJ8BLI*)uC-A`;bw55vp&g`vBVta+MUhCDc zbJ{j}lqeksaxBtOIarkP zH3@>i0|~qe`Vug zYs-BV{UseZ!0f(t)f*G{0hRH4WpUVAO=%J>BBrX^DsroeiwJA9$nFMT5rC7sj|aBX@sy|285GGVv3=tTAaQCkt@XIv9Wge$jn%uS8@YMi zSw9+X%&hrxJiCb-)#c5)>Uws2Kh5JTd&-gZUS{K*)GImmQfCJ70g{Ht@SG&fA76H5 z6FYJ))3}@2joG`ccZ*~^;b0$)Qe2QZ$QKuxT$J>ZlxG~w+fNmA!is3{d8*tOWbVNb zG&#_bX%+5ybd_l!B*PH?s77%Lkk{f(j3+s8RJ-A8N+8hyJSlS-Su>`bCKYm<{ zN>lXV5$D)W*s;19&_5^dD_@+}a#J?eAZ3_1c^u~+QK;H{o_FzBv&|LsC&bBSmc9WE zzZZKm4Nzv350O70xA6nPZ7 z;x~lVgriC}us^y6z@rt#rkfSLgUa;HW|3Hvr3dz6K2bxOe2ui$t7>Cot$+$<((Njf zSN~$pB7;fNf(LwQ-s&?OT}fUuD?GzoPG>5`S*m_&y6Uef7E?37=C@2$F49eC%UT&m zuV8d7TUo$?KT*r1aqbI-+TY|ltrz(KpD#06QW(06_u-AHz52AvQr$1ZD^f$r+6}oZ-xX04Z`rg46|OI3mI6G`kyM zlR!7nw=pCrjvQ%}*oo!0Y_An1cD!rLPGrZA*xuNZkJnBV?;iV{^~Q?5vDfR(*{prm zUcd8jVq5$Be_!3(4UiNCS$p>EIXlBH)U8`pw;o@8@2cwj(+$1<^wQs$C`IAFKK{PK zFZqkkC@M$MWx`xk?ug2rQMoHBuZhatQF(1tUKf>nqM4rPGH-jM^7?4DBf3mBk9S6w z$?x&5=rRR8z9za%4Ib}~E_X*uo72a&(dBi~rP>owSEVPq*&8*!HOl33A#bl<)^gDs z;dy;@dA$|vi)QVE>MVGfn zW%BHZ%A4%%&ZxXOy1XkYKVpx&qwn-<^9o2Uv&AgXol}T9^Kv>RUV7RuI`R5KM_?Pk8Zpxsyq?h z*b}`IsVTXI(cC4PT0RhcjE3da?DD%UzBj6N+2g_JIi(KxpF#igWc1wS{;1Ls-Qbf? zS+Dj-EqKD8HnCtt_IV@!xnkc5}%67N34cJ>D!}iZ-=7t zGxl~kDnDxxuaK6!$3Em$@%WrQ9!V>CuRVHIygg=*&qU?tt&(TcY{xDAJyH1uOMfmZ zzi5&7M&%P0IhN*p$#Om)m0z~><5Bq)i@Xq(M=bJUR6c2u6KRoAEAmoQ9<%h9qw*<> zyb_g9TVy0Ezt18kqw<;P@@QJ{tQ8!K%CFknQ&IW-7C9Z2&spSsQTe<@&Swk$C0)ppUe!XXyc$ijaxP}6?~lqK(8J|(Q8~8A`KUZ$MJKaN<64QT?X@iF zf|g?CqSf|#mihs$)XD`*y_BWKwq)LjW+$S#$>{QAH1}F``L)Ov*$1Q9*Q2>h(dA1# zua71MSou-%kH7+FCMPfEOZEEAY9)WYSS!y~Ycu)jdLw_UaxGt)tyXHyWVp9?@_IGN z&(+I|v&xp_2Ws_O`RQV{F}sv6SCeM3)*Q^&8`YU=Ey-7F`S(>5a*h;}gZYb<#%w6s ztFIkDK5Cy!4&|pC^|^fWdL=(wy>{!?t)Y2kCEh4DmiXvcy_7T?G>ELF`rMq_lBbRN za^>3MOg_BR=bCC>sa~$+8K7khtR~lcscnwos1(&8hqd2EAYF7Aav6(+P zF*bJ6yZvghVSP}y&rh5^^(56&iY68tl{`gy^<8gvIe)9#ylxE-pVLT}i;Z$RN{8}v z&q@~GDpqHU*BEs*ulIVhIe+}=ry13RMwhM+C)2~VO7rQ#%9)S(!BZmXI5U-+dk#XAz<04h4wtXGEr4zz3%O8 zcC%*vx!IFN0jH+Oy1%$spRJabnp;U2t4tRcXPe8?H;}$;j;v_=;5IjsW%ky5p=4{c z03_PS&ee*mS zz%YZgVYWUqQ)x8UlBg&P*~-jRn&<4zfLhj6!D3@3i8V9>{5(h=CpLO~%2(ad_fGMV zsqAyZ^Go)Lf_?2NvL>2>DA%3q>gdk(<+kLK5Aa;fPqQFu#korU7FdS0olh3$=RvAv zAqQ|Qslo$3Nx}@EPgZ!TLZsTP7H6voc?}8FYn4G8QFT+z9_5$7j-(?PMQ>;EoJO-X zvK`S~SPF)fJe}z%GpwCr3v&FqvButYX{2w!0#cwW+5vGZcQF?*Y8rig*hfEkglIM# zprDz(y$6zJuUgbBmTt~g-m1)2HNXQJ|K>V^Tg66AsN80u*(jDO*T`wFCJf1+y;_PC@QdO5VC*DHMvA{jvrVj}Mr< z1jJqMCl)>bt8h7bK3%zHf6vnkJ&(-$-}7`q&#$KW!N2x?amM~m08Vu=ff zSf!MKlA1rtFA;|(Py#O2MUBS<+c$EyN~07pvPx~z9tdt)$IL7ttDeOT!s_kNN_x&U1y!O znqI7xv|93F#fr1D0ddvEpHP2eW>E~>p?tLoLYtk05yEUw(RO^hNzB60BS;_Z*kpG6xpC1|<%U{2Kd~WV|l3eaTWEC#!&1<#lTa`vq zoXt%!n&T{dbmGpDGp z6|J~ttjY{PSSE3vhj_1oeg*poRm8XNiGghA8!3*(b#CI&Q{@o@zLrdSC3evo8kZ-IhW15#p{45T2@NvSwr znIXZ!YQ4Z}0I)LfrP=nE_0|*>cx}=M_2ooV_sxMTLr+~De0gB1JXL;q@VG|?U*2yJ z*+~w;g+b&$AOdX?qsW(Y(amllMz9|#wXcb&8}89jB6Jr(Ykbnc&wvgV2e^a8@o$@| zAU8?kZ=%L+;YoyQhtDisS$C>(R)S~mR(8=yxfxd4c%Z5} zQGHQ?t!o8C1EQ>s1++97n!@D^v@_yd;XN33h^nMOc&v73?Yg}IcFO6#d#;Y zMp*Ay#`^ShQfb=g&aGxDxARdiTaffvXx<#XF} z8*(KpG7!e9{Rd8(SzjCZ-E7n*~wF`1%<77;uHln7~kLQ@X^rTIfk>4`sRiCvZm z0C*zo7&+G{(P4lV14D`%iG{UR+yICQ6*tI%vr`=Qnf#DfkQ?|iiW(oyF(EhBN*;ot ze#hx_XSDn6bVsdyu& zPpx4{JLr0NQ1OM2=F|tPn?a@Z%V_^vYv}suE(%t9-V-(cJO@t@M&Y050BzV*jTi0i zRl9ivCV5m3`=YyjY3AQIsep<|+V%E&DkE>n^IV6#OL)wRW#@3 z9kHI{VKr+_%U!GMsG9qCct~P`sIxQoL~cVzC*sA1+!`3xo{n{$eNj&?{5twrfA)Vz zU&roTFY9n4;TGO+$ZhW2ODgL#KST$Qd;ai8G-!V!nfJ|smyg34--WQ?hkOed^zA^o8U!Li(m!weXRPxl_D??LHUmXl3Zap=a=Jmh( z&?h1|q-E|~sC;iBi5*_$%g3{_*(Z9gOe5)UBtc2D1k2%a2Tq zo;};*{ENoMivnwWUGpF$C;9+pMM&mNN3@$Xag6>9=Hxj%bhSUM@rSimtlJ)taDK zpt3bcPY>#@jV6G>q0lA1Z`d7F|IS*Frm0T80K#$J7qt*W{{YF$gcH5agd1d{YfJfJ z5R8HV6}V{Ann+ec2!na3pcD%kq+8L8Os=X1K`xWJz*5SvSZg5v&D5%Q#LG%%^VXqN zUu-7TvICjYvlf{mx>2mnR1RSl$jTTnwZu1R#9CD&fw?GYFcxwlcQ%VMD%4Qv2XH); zhh4HRB?&@hxlLkBvuNnlpis+Paf#KOuaUb^g;L}PTyh*beC+Vyezmawsl!Kz%7~FK zwl^TFF%;p`{fF}Xph5jPIWg(QPZ5y}IqK5v>=OO1VJn~!R$Eq$w>Z-$5CxAsd;G|I zjvswKD@d{WY&qYUE**Q%;fK~>A74=iHC$`dZ&qp#s^lRJxAre@y)>;Dvnn@fy%Ur# z(Sr;fQ%C4V&;UHBmizUhy_V(OxnE^Iyv&$Q9t&;;)i9HYv8k--lfespY1J%qx2{*Q zX3e8L1=c1hB)G~ucw0rVK7dq!k)W9o-P3ZJLH$unwaGxsQA|}c)h5<81DI5QW7-+O zsZs(o1NfGxbg?0DMjta*ycvMZYKB$;bOy$%C+Kq^>djP_TLmJoZRur z=2aT@5Y8%Ptb+WnD(>N}s50mWRQd2!`N_eTjgM*LoKjWgfY!}4b_Ovs#aUbW8Ovi0 zOoO(Y7S?OI(in!t_!L_@Zvk~S&m*QF&1Yci*621ObavuG z{@8PekF20UrbRt`bm;IiEg~```l~4c^{yyp-@0F!bOu$%`BYevz-+H9l;zDL6fzPm zM71LKWJZ_TbH9ehdQ$!ZnTU`TJACx;GZZ@Vo} z=tzXZqYZtIt2z&Yt4btC0w4WG`I!*u04_#67fm@(0(hzNC?8@S(Vm?XX0S~LDH%B1 z#Tv$e(sh_$AkM4=jmq$OCFSeaZa}?;joP#fz0ggU<(&s}?U^W$)noJn^JT-0GnE>? zS^Q_g!|lO6WX&3MLPH?>7IkdTC8B9>vc?Clym?|OdEpQeTJr9YM#7U*{k)m#pPIV* zq|n;baQZa(B=c zfg3)WllK~!_{9a>It zbXZ_E#Hz07#)cqbO`9V@ZsC|Zd1Irp-q<7!8XsuH>Z&IKetR?$=+(}eI7bC0IZBo0 zBSRf{KHR|d5F|;zsJYVs)&xZ9l^ZD!Wfw(l894Fr@#DOA)FBmQ)bp4h8k_k!T7H?LT z4!OuTk9U?_w}ef^DQ3cgq>2Q!#VvDksvr%SgF*ix2{bSC8^hUug1-rTGln|;E-d28 zRJN)@JBrgy8bvnQ&9degXPTl%7G_htyn8koRVb@67c*VsgLV%g%{4AA#nOW1+^hG$ z5WYJvUn#35wJ4^&$3G2wYgN`e&ueV0iGltt6c{kl6|jAKGw37fMVU5d(xS^-B-gWI zp5e&`6QVv>Dbg`xht2sc8(qoENo9I*R%qUMdQD51#OZ2f7Bi}f*e(S!ap0=DWRD!=j5q3Cez`hwzN;}HF+V% zkA7?P(@DxEHLLYR%dJsM+}BeW+hXcd*_PYDBfNLylf5KzB7i~GFYmm6{!|fi9aaa6 zAX6YYGH4+>@Y>T}wc|C%X`Z5m7IZdMv)((n%KtKB4T|ls%ZH@=0(DJj(IFzpVPOg6 zTB_rWQ1Zp;tpW+kTS0ZzDy2%26dP5tqD^XHw59rD{#Jbv-N!9BjCM4^mny}i>Mp6} zN>akH6K^nibtZKr_uy}kDra7L=_Qu=Y_(bNj~8y$8|7r+%E9S+{Y3w@Vx#|s{5(#0 zC;E>aK6LB|PdJN~@COAQ6dNb574IAjTJtMc22|+aq5MJK92`XLe^4crU}Zfi6em>! zGI;e+o^mQ+-^tU%B%bI>o zZ3>0-y;iY@eztM&B%@jaT#B=ECje-=Iz_Xm`j>stGPQrr^6OhFK>mLFlJ(GZ6p3^c zQ%B5zdMFWB`{ot#Y*(L*ukv90r15U|PLjOfj^_^^NL0Or2a@ptF>j`Rs6t=dwa*@} z;d1KBz_cAB5VeNTy8Bp)V?1+eWb9O2n7r`*Q{$-yB%bF*{Hp4d`731kz-t#KPmL8` zA367$S&TQgUY(j49l2-w z+upG`*Bx!n^>jW)T4!#n>~PVxoPo-~6=UL^A=fa9MIYste2yTn-k%m*K6drH#S1E_ zGrGMXR&nfV)%Zyh=V6=WV}Rs-*ZjWBR3cuwBTA~lej?`CQsB>FX^HP32Ez)63WLcr z?C%bkdXny%hiBkv7xM6#olyhc6Z1TUjg=<_HkE(5g$)t^F2T@ZxF!o}Zq!YFhCv&1 zWpuSBPbz$Q0bTZRl~=t_%8b-Rw7~hu6@`< z#y7G3?KjzUYHI3;MfwjU{r2uaa^gT@DDZ{6{h{yXkLJd905@_)tlUKc@_F^b+3~`1 zG!x(9wP6T#(;QuFW!wCkLw2C7@ki2(Vk!*j-n8(o)huxNBHuHfpVIn%ls8eIukNj= zOt6VX(e1t*&38Q_^0bhG$^(_~n(FmBI zj2vVT<~Kw)!BJ1-q_{*!Kxz?8lVaX9YQdkkJZ9uQgWcBfp)yd43{T{s zW-<$#R}FZLYzt3F$OkpvpjGxN)f&9yg8EjW(&S>!v#^V*F?QE?D4>xL!haxUf8&ieP&rUshADB*vKS%dLJwppny)8GRXdd`)3EMlII_y~ zFyWS~)F{r|H%-3I#vt@IV2`wuApKYx{&IdY0sGCuye4LR9JSqR%i5l3MgNsf8 zb3~g)AU-{sKY9dvrq66T@rED6+!z;CuFpY+44uvwVZg*#VB=VX3Df!x)YjiKn28eS zinoV~GZn+`FQ7Iw=GE}h340&3iH@VlFD4_34jZnw450yuKIRRuy3_zm^9ESf&;WnG zq5y5KC?#UdXNdg4N}QX>Kcxt!lZPVFEhbmp$Wc10@4R zCZk5xaIo>`#``P}>fqp>{UntJ^}EL2ba~QQ2+UC_vbY^w^5W-*TSAio*syKg^37U; ziL)19e>M|sKB=1jKEYQ;7zL@-q;O_z{Es!R8+nY@Zpw8rdR;iHcI8SMn9lIC0s2NB z7!An%JCGORw%1H?8#0j^h{k{x#{?tiqnMxwW;9d|CfoJjyfY4616Z&)W;cqKJgalr z#$P9IS(0kQl-CvQftVzJ*VDvi8`%FPEnP9jVNgfH=nk2|0^}XiPqK}ngzCcl1wh}1 zTb_UJJpm_;82fzEurb<)mD6OZx3d?)^<@YGa%m`*)&h=1B_fvoNbqStqlwlGYo|v| zx{#oo1jkj762XsXFnQCe)%CS5kzC zP%Ef@U}6!4k!OVoM+ZA`X5`#C!_Ks$gj_uY8AR*M{<*g*!x)~ewIdJ(tIvll8$tWf zNnV2CtrF8*J&Ee_dIjxUs~s+_qoy^#=%KW+=v#~EKI)BSrAK^0w7P3EppDZaf{=l^ z{5X?#i#}EI-Zm}akpq2Ui&s`e3!RNK>V(BO_|JDA&tO&?R%qUK?4v57(&wxN!jt*NGu=ZnMF zhD)l|Mzp;sGwp9&f2~?HA`Q{hB&DH-CQR27e?M!~$dvob8}=8Hh<`wVaE4*%#xyR& z#$&rtPl#~DaL!2!tE=I$<(KSjF4#H~N;Lyuw9}EXBb80LT^(I8++Cnz(2G8~4FB#_ zX@OY>Q>ZHl#-r?1ITRn`V?eY%bf z;l`iV*Ul*TYhqfVR<^@3*|P=5xCb>rLcmeCh9kqY!nlTMzm~{@FfH@rn6*A6OzS8$ z8B=1wz^`O9hy<{%3t)&bVBN;7Rg6W>P%)22J;3zf$R_SXvED2U&3Jg&C1fL*gsP6j|q%f2|Ira<$7~9P%AMQCbK~~F^mqn zM>I3qsu^_)ba%l;bTLDl*u2q&Al#KRx&L^^K&Uz5t8CWfLC~5t#6m_togn65x6c6L zv1r{ZmK8GS`?s;_c1SvNL$Y*LMj_>HYjJn`4cidEjt_-}Ao~>}0)kV*RzZ+mxx&(R zV?aue0(p8JMZ9||o2iVq$H61o%t&@q{%9rH1_Dt9WE`>Irl6|nSPR2Vj>bhuLal~u zoL|;Jh<3OJLs)@L$OSBWvxUXRtO@h{HMY*Qq3Q-%%VeD4zqZNTEi?B^UX!sVF#8^C*qzM31~%o zx{>A7LOF8Z89$U-wywbjm`1NPttqo<TIz!$iZjA;dA?KT~%#yhbE4Jm_ohC)1ae z#`T)bDQ&aCT+Kv?zo&OhwSljde_fNYju%n)X0}+eSxQ)6?Z_tLRUTHZFdJ1SfjI#- z7-Z>McqDFGT*rRsu8EK$pLtD&ICRyUJV$U5In8(^SSbv_i0bKpzZRc;;IcAG`LtuL zAETD|#|cs}H(|`+8Y32a{R)x=<4-7?u$hmv1~dLCl@cS%%4jB*Wi>h#EK=O*1X_2PwivTdCITjl(Wg6|~wiia2s1^!Mq`Duvz z*jUubZv+3YL)J{xrUOsEaQu~bpLlBjp}ik|^5DRr?cF>uaOLpO^Tna*ks-DiwW4kU z5x5KQ*!+ka62zLk#Z)lb%+EWKHvTHpxG4}095|3TyC+ySOIQ3FF_#JF6yx{h`eeyQ zX1l+H{|gScWwRgw5s_)QqZZ?qHT5jT96d6z%zI;RO50rAGhMI~Ho60-lLzq;s6bOG z^&$eLr4R{=@)T8`vULN$E;}>ysaiH=J=SMfUuosc<^Hw!ob&Wq!%ZvZjZcP+UN1JM zhmM(>P%N-FJ4;I%B+H}!5=Hg zFF+!BiF)IIN#G-|b-s#`kAIH*U!yVZB@*>+GS&N*7AeZc`X;XfO!(jeB2IubS$tN}OBZwhgo^6*l^Fs)!DkM?J z8sa>h3#?h~FG$uq)Fx+oxn&~Z$nZ(awj$Sv365-psLWlfl(B%}wIfgdD!%{P6x68J z8-uXE&E$TiUF;+~TM`&0$>&);l(8K?C)4)3teWpP0*uR4Dt+2tI_UdyFvR<~Tfc`- zhEeswxj?qYEsnnNjS0*1o(WlHyt6k0{Ty;NTr8n)f}86Pwzw>zWpoR`C_9=EpeZF0|@ylq6cr3ab{{XmmIpW!?Non z<4H0QG0=YvFholr&48~0SJebHLAKzuR8pqK%3TPCjjT35jZRx<(iR2C8Fv;(Y+?LE z3VubSwUt0b*^7yjGcK+rwYeS7Se(z2cQq5JDMM7Yfq-#hAbw0UxsK$hw=ee?$3~SD z*MFMFll*M^ZiOQQ!EA&bQ3c5=XJ<&7pZ>>4#CVT!tJ4y(sC7k3B!z!#EYbW@mB@)( zYwhj&C=MQ`|07>AlH+ET46lKQ>_j?-H=G2M@ZR}rNS6&rYu;guEDH6hW=bd z(A2K9Vjc*=5x||Zta9{IXPfyOi$c2Cxlk6ScKgI$9ZYN(+aB5l5tbja%g^7imA7$>-rXJEhX_l z|3yl<3nfZJZx(xFlzQUWVLU9+$Q#FZ1wnfeD(T(lV-OXyJQaJ85Wk$!7 zAqEBbL=?L#Fg*R<3|;|qd<~~v6!m6RhwJw zzD+MBO9Ty7_OYgBEF`vRzf5%W+5nNZ+P3Bi=4%~C0Amg&f#&91S@n&-3ccy+Z+6{TO<)EsSlU{fWH`wFME z4C0Hnp2XF)kDq!MXAQJ9vD%hld%mY-ooy{kXH2mzU;G*qt{CC2J z+f+<9k(*Aq8;`CT#_ zXfV6@X%MYvw~07-sQGk`!@N!Mt8K8oLk2lIR7jbuQ#%!tQp|9%Yz5x$qPQfzGek_f z`9`8SGjvNT`W)BuFvofqG&`mUj(>r6v^mHLTf7)}kORI0@<8&EGnGPsK7fWS3`M-7 zw2uGeVuoap*mM>x|&U3i1dm6#5uA)79V##_*Z_7f;RT_iw2~RK8XVd zlEL8aX#3CaachxOZJ$qmS`ZowR-Ceby#*O9dVVVwsicL*jm!8$*z6R^?$y-=*Zxkveb++BgZgoe3LFjGpQ;Af5VsHPV% zYLyBFH=g}A3Gx4?K=sD|yMlkG;CB@Ko`OFhXtmg44{df#ndle5sy1=mo4fn^@;w}? z)YIA5-P2prTm7endy-#rl%QQalWc~dW#%tMz&!|NL=e(kFzc4+B@CP7sfF{IF>E0> zT(6o#gGo_&CTTfGeh)Xkj1%X?QFkw6xT@1jLE1sc;B4~68J!&NOmpV-R%D+@InR+T z#Z2DAd1LXKOMLe^Gdd`;TrNr}d%nRr@Q(RXq0r=z`w4~;lIq9~?0z@bI+RY+dD}3< zR+&651TdQQIXmZg-cGMhS$QDGNP$LtRHG*LrD@JOaNZ1eP*?nOl7lu6@z7k7Z12DA z?XFG_hCz9d$b)RuCfZ2;X>;L2o*4=hD;-;0$mxwul#T8*XKT?oYh7q@v;>^ce};=n2NV#Qg{55WNrcaLt)&C ziovMg9Akd8i6{F{7{!qJK0tp3GIvbwXxwo)7uukM zt8_&tFQaVZqL{}cF0-kiS|ieH|Ln0sK6{iBj!R=WZmioV0lEfP!oj|-vy_eUo)?i| zTY9fWxDsZ)Mc8WIXOS)GbvN8yv(Zwx!N#w+*{&;YR2=c%Z@J-4n=O_CtGv}B+-$SW zB9DsEQ)Z4#-C+^Bu+t*kc(cnQ+g*^8C;V>2G^vJ!8IvlFgl`rR=4etOXEmY4+m?#a zjV76(fxgD*5ug?&!jhw@t`aR)x=%gBE#Q^bE_Sv$X^&@HF43*waffv+8?(UI!p;F> zhs4FAl{b}j;AjgHz0*9hmS2b52DRo<+dwC~OsN^XgPM=2rJfRMxvTben+3GdS#&2u3>?ZY6B4rXOo4xuAY%1x6kB>X5{qKuKMA(^6??#rE@Z z0uJ^eO$NGEecZvvVr#2Cs;#jau!;uT8W1$Cgn$)&;IU;Ldy0qK`@?|i5--*=Ryq3Q zqHlv;La3n@dZSBdI#S(;u#~kn{t?AQ?M)zALGn#uxx6*2>5nKCYLZaFZFOTENfAz_ zn{w;E9MCzThB9fkc*Xc@g7q8amuNg%sP|r-yeV`F zhI9juKSYW90oICsSYOQ?(00ncgPC=w1!ijFYNkbCFECqyR6e3^n&+!8Y<+;F7O1_% zgD>o|tFU|%#y!wy%9a3qoSrS{djjZNp_x-BTEj!2$^7?`)u`j;inajq*!o3BV1ILT1-Bx;p;5lPhLiQDjG^y3H98PO7I~S3My$ zLzbnu>k>I&#I&&vCmQ1XOBW_WHzLf$!cm4sr>3sgSEX{#1g^6#TV?|1uqLg3bAa;? zAiD{>reqG&X%8+Nv;E+Dy)2WXY|??>ccYqQG7}Fl<6%K_xd6eHV@gta8Pv-Gq~dCp zr|T357^AwrImcm+S@WC%=8M;KE5>rkpWMzerLK_rzWMIr=D{gfZqN$?i0#xhm6_4@ zlyGxKWOK=tHlJWr++blg84(yCih`TJ+m&4L2H?tcP^Re;q7!j$S7uonIxoLaKrDcN z<{iaE#A7Btiho~$!KToot3(a0XY!qSKh%tknXVP|J%An8%-Sj-)MSHi5=^Qg(b^py z+wlqP1uB8dmh`7K8(hjkQ4k1d`XU_E3JYNBYEGaHFa`7`LPo58T~XtrE#7Xt$uC+F z(}1qXhMy6K&_le}lI@mdGi|43gLw<8_iFwGIcTdnTS0p$bgFq8W|D43HExm>49P6MgV;Y~6x%p)cmI-+116nG zd&y>l-NP@*0O!7j*_?SU^9|FSaf1XknXc{~G?M}VxOzh_0w2H1ArTg5>db#5II^sm zjC^@f*CjmA8RmXfteB>URbfldxLuHQJ4YV>E1Ku}^S@NgX4B^Iuk`rUn7(aP)S5mM z5)9Y;s3y@CAtuRPD0aInTzel|-$|+nYs)v*`7~jLBEsS{S971NFmb*z%_Qh+Nfyi2 ztQaQQpB$uK=7uwRDl;5qCXA9F@B>TSC*$D$gM)3}w?0r}y&Z!IIkXMgS7Wq{EE(M~ z1ot@&lK8r)a~F<~wp)lKV-nPzQGUrBfe%lE6F!{ax!1Rije~abVi+nt0>jl5(uw$q zePp&H`ubE0+vpKbElIW;Avma};9FQpO$hM)UZRYlkbcV%Cy#9l?XfgrMYc_&uD&ht zBRE}o<^zeNl3$~O_~#WEQpss_ZD5TIwE)saSAAZg^)ne)E>~*8Dky;&`U7C9=;!H_ z*;pdX;1acVu?<2yYXd||w;-HjL;klwEzX;1j7;`#yt|Dukb={Agh6D{qCRxc`U#^^+2R}Qx3hWT!ht&F!S?yjDQ-odDhZi^$2J?g|k z4o9FWv>51~*4XS@ew~%jEl+m%Cvx$UCldE^wgD;-zr%w&jCEJe_8jAdf+Tzr03rp1 z$T1h@#B6IK8E(srrUTJLUKnEcWl65uVkxKGu$^$An($T79E0uhtgN39)wC1kQ`-Lbg z#-Z`yj^;LVzp>%#(=*@NYkH?vgBL#1p{2NkrMM4}9JdRgScR_k2&)h8FKy~_p`Xow zoc8!`GOx_0MVe+c#^18KhpGsu@e%H(s>f2D2B9G-F>q!rw7-?IUw>C`_;q#YlPrBE zTvIn!o%MsZwSbG9Rc~*vRquE$FfV!mhdOVOYHhl1ksI}EiACn>*Q#cMz`3ZhIA{3R z%IY`_NfG#Ja&e@!t+JSQl+zh%&BhWtZZRNX2<0L=9FfV_8Y$ycealbsH1#k%ICl)0 zH*PBz>`?12fp!PxE{0;!fVAt4@A(vwOOBvlsOMNHmyE_JkUexK65 zK&JR}3jTt?G=4U(u@t=K9%g{RbqG#3ep<;!OTJk#DdtRtIA)t0VZNjQJ+HHV&4st^ z-Gpg1$LnJ_v$t(}HOeFOzk>3_pH)unBm+N|>kPZ9q= z7NnpJY}(mwgl{eU^d>kC4vWZjcl1IA^`ukI()c6fMfjX1uf0PGdRT%Cc zTF#XqvAZnwq}XnpMQVMvU(HY+kGGpvkaKk)9YzetuAbIGL)vcz4RI0aQf&|WtvD_y zy$uXTz!AQYUT#f!LnzzMrf8gvE-svn_;*RUELm*}q8oXIPJ2^%%dp6?!|?)LF#Rn^ zLAG!6deo8@&I~)W22;r?V{Q<2C4&tb`!fv&(vk-!o65nx0Y6X0CO#RUAlaMuWBe&4 zpH(1_f|Z=5Mt21Sws;>t8viaCRs%C_yrz2A$HFy2;tY^(Z0kd=O1E>Z0baDFD`SW> z)7fla;sG(9`P8_2$kag_rK;(+@q?= zOoLyhwkE5|3xXo$tNN8|YqI)+*2a!{z}@@-+8Y1r>a;bcX=!s8m2SrHj(NRg15hx{ zNxO>1oFA5{d5q@W$1g~j+q{!Bt&T=q4`Uelqx#@G3LdVii8l#zZ&vUK!78BA?6!La ziW~V<)U%_do@q&jq8p?960H+QG7@VL;13$pmV=c%7#MAn&BcftE>bp_*Ky0%MYeIv zW~j$_L5cBgl482LSIF#`O;87ZWeOAxuG1&eleDPaS50Fghtn271f|I{*_i(S%91as zZ*e{4R>AK7^V*S}E2pZZAbC*}Cg_MBq#((b!4R1oz8iz4=t8nIWUPbmTw`f;)FE7! z0l0%`+;}P7z>%0;1uExAAt?Wx9~Czok^_nJ8)Uzo8jSwPAG*0TUs*}7^obSpY880E zOt&o{_74@!+rJ z9h6U?$sU+9Zhe(Iw|s>Lzs&Jg@3yphC$i5A$9Ica?-~maW2!Jzj)kGXuQ_F;c8HN` zF-9j~j7~)Slfg*rlWWdUluE1(D$PuJ7Qa`k!q}q2w1k0M#`VA&Ws->6E?8W!Z6LA_?+h*nK`yb1`|w`fsm zeoWWUr)ShOROv~Ym1RXBX1{10trQ*TZA`n+N1BT9NlFI20mY2P75xdyyAKd;LBDN7 zYu{=WWX5bxWrC{BEI+?Wrm7SOJbw~ueSk=8TGn<*@lrvCT|sACVyh`6k{7(e;e&S6 zi?khC3mxk2(T;SjzlIC7a)b{@`6WL>a39b` z-D{o~z#j?&vFx&*rdJ)e-o0w?fGaQt@)5ZJQ-GCn^A!PP_K5iwNv5UiBuC@p64hOa z+^!2nezO`HpRxCbZqoNH+lkM1KkWxReH^|TS}iB-Hvgt#{$@VlHb>Jw*esjQVFea4 zVEIX9{;UFt{HvH&^Fq9>X?&c5QRfzy*VqnT~n3?QGOc&!410Qq*ry$TEr{!E#-=y98Z9SU|Scuv7_ z1^-@IUR3Oaf>#urR4}UGl!E`DEb3hgW-Rt_*Dy`oX@cY&5l-&3(>oRRV)oRgi1z>c zcJ_4QqS{T^-LtM|YtN>hKAcw9_q@=vy=M!tKGM5;Humi3*-@fh#xv;)qx?)`Dvrra zq}mq+Q8F%4T6n!kS8BUYld(s*A-axM=gyfzW3D(K|63|G9?O_auA?k9<1>7#zHb54% zy{DHrx*2UbCkWC)vvK4G&$-0h#75Fh?|!ejz}gf6_5$whR2xr z3a-I9xd!W%yY*#jyww_uJrq{rNvi%QYElQ4bsHe4T7wMxqIA&y#WLTuGZEm?m^FX| zCvDub^=Omr-r9OJy#OxT;jL*NIVB-H8n1QP4oc7|3HU_gqfKqtpxj3rBbWPVW3+M~ zZJf2;M;m8t_tC~#dxLpNwk2cQQ?xT&fw)<$~tnEJ9IBUC)HqP4aqm8q+ z`IRfgS-Ug3jMuh1YvZ-;&f2_kXKlQ;-B}y2ZFknjYulZ*^O>{uH!^&qTm>9XaK(UY zXFjA}*nZB(2f4o{J*rzbB#0l>naM%*W&2!gE6Z_?)9~|2{a~S^!`Bw8v*iM3f7U9E z0aZO}J5w$;>bfh3Q)PzrZh-8mrpzXH>XJcEdS!+^Obx$$<;~%%Puf;Hj|nBbIW_#0 z(Y-gP_MN+QF*wg8LtGg8l%0J%SQ5CTKSP8kNB~^`B))AFjs82f-BBzMcoDx{asH+evGhQR0w$=N zCSa#2zC^@q+S2mMS_|djYvi{n`rk1w>F!zZXAk_xy<;G2Lg*_zMXOI*zVT~>t)|2* z;Z-4Zc{9jT;m!Z=)f|m~C36m<` zNV$wm?S^B${c&SaZI;Hae%Sm0y%wY*{&_7k(ZcC)Vgrf0v7Fz=am(&6VRpx^o;16; zmoo!;DEEVH+Qo$rs|K~i&_zyc88RGK4`5i~A1<=|uw}V3h33Zj4P(_ls7FyP@!AM|q-^!c_IlIY?;RgL^ScqlBI^K}Z?1x6rP#ePZf zkXJoW5S=utljOD%lbK0>xip6#M^g%D$lQV!EnGnhcT^m10gTP!9)lqx_yI;zZpNl) zN4S20;qlFxvHL)`?w1L@4StzEACBw7)-)rwaW>wzKsk_CS0Ul%-o823c;hL}ghqWe zL$;0l%Z4n7!M~+3)575_cw|GaC(+pS@XJ=xFY-MW3EUm41tRw`B6uSRwRMQWW6*q| z-TssuZpW^EBIjx%){|UMSZ_C!oqQ}4Ih~-YxM2baRMHmI4jalFVKK>cx6$^!{DjQ~ z_kNgK!(EITBxcok2J<(;QAA>;sXkbW+G1~ya%gdLAa$~t|F^@JmB=-oEVJ69X=7NW zmdYa5ZhXCLee00D?28)jwpB{oy;U1Lqfk7BH`-mFcGE}WL*`|&F})vjGrF9a9Bcaq zl-zUJBjkOL?h>T}XCz=S*Dk9RI`0GWb2%u#d~W#C7L231rvw&2kB>w(m=0!Udc+EBR&D#O=Q*p|Jnye$EIV z9v;5h$~$?zlHdROJuavCdcmgSg=`KEoEB8e!*Vw2^Ezf1pE|CbXs{oZ!KaLDgIw8_MHlTmB8tUQ3XR%|By5n;p_^GKUF?!1&B5HJ^ZeU z@%wU7zqpHl$NXZAf2U!7Nj3ED_UkOxN`TNs7CYByzyD)wrQej>+VQA3mfTMBVUW+Z zpHrdR*S2xBg`qtSzvg0;U$UOjYZ}foG++>e&_~mAcfKI#K+tnOj`v-Hs5N%@lJRnS z1eq9&3Gea9qBQ}*buW#tH=Js_{V1RKBZ7c&0w5+(0qNpQ7QWt4gM9$!xW?~UbvVjx z0H5#xYNi?!FZ6u-S$$~i>R?dT2d6i5$3J6v`39&9w?3-AxbQO(|1N=gE+K#TvH&}& zlW*v0vqgCou42}L~)yRqAssSv`b@h(Tx z3YH^-#TwiFxjV=A=eKVyl!vHx-M8&yZ$3iXKq4u0_>tH$@;a0FLf#mZ@WEKWOv)TbHy>eH%@7U_i<5y>N37u2N8vnxW$2~F^jcErObs# zoVHpH@9e}2-x2s61%D8|kSvDdBcSnys&&R7qQ8*VP0qtyL_e z80;720e3S|N8P=whR%*X9h>0jyUkB$cjs>OXVNs{x6`@N*N2FQkb|v{C%~D`G9h0A z)Cia2oVz*z$g!(`k@Gz?NUXc3;1TQwFP0M&N@0)09=tgfu8(eizmeI#XwTTyPv(>z zA_rCL3u>gdIdF`Ba1Py3@==T9nuBL4s|M=o$ELBl))POYlgf~AMeI=&!-Q{8Px#$f( zEe}w~F&ogar)>&D^nE#PHTKc?x4G76d_n1m{JJIW3syCLs(sFBq}5wjwRgEMdXaYP z&^M5gKU~7IxA7Obh21uKu*BdrxGN9``PWC&hJ*ClZzK~OCp!U?z-!2jRIc2%=XTlc z;pv%#u*J?Tqu7G4M>yg7m$o%7<^+u%TRpY@K_6+A=Ao*(q5AFjkaLzF&YfC(t#byA zL!j(Lwj)ND#I&ALWR#vQsr-{VR~|+M#|=p=;g(2ze!|&~hhRgbkMo;V%uJ>2=cX{T zQZzPWT|yU^=W5lZz7@G(*Y3V4avWrEx|9s3KBwPYQC~afHjrJ<>$Y#&>wK3^wD9w@I9Kqk zf)`=j&@lIm{Dj^ci=p%F49|vhhM+LUPdP3>z*}aDBVFuhOCS0+@6{G#dwzLNMj|~J zyHzM1rmU1yP~73JNnqnMw-wpWDeqqL@&jwc-LE#3y88uqP@_T@TiYH?vcGTpk@B-v znC`^JC_RHoie8^&lgaH}m~4xOjvEi2<(;7U5XT1`APu9$(EntCihM8f~w_@-^{<(ZUj*wQ|3SnJ8{>eP*EVqRsQ=td*1bMcjj zXO2`Oj;>sUxtFvxYqWul+g12~qjKjqbZk_89Z$G9P+W*O8Y9?$049buPeD8&J$B)* zWMddf<8md?LwP~wo??5`l>(CY6c_qQF;@YVV%Myf0{?p+By&tB@;%~7Ghf@FI0-rizg#~Oq*|5LV42K4|$ z+Gsvx|Lv_tYdt@V#&6|V6D~-IPudo}&2g*SHElJv)3lXM{&S8>NZIMC1$Aezt$baPfd(uw z<4!>s99nXhj!+d9GH?vLaWUdS7#cc4w-IkPBeQG)_QzL}5s?`uI7WJYU5_FyhVA_1 z#h>M|bsLz`7xyaYk9*uco8bRk$1w@r93{PzCJlH2$U7n3vc z4HJ?f;P?m@=iTD|Q65||up~Tf_|WA17X5wT!2KJQ{WS%jQSb!?rWyFGV)A%!^#GAC zSI#$t8nCENh+c+KzgGxV4aOg$L$@pQKb{eN0X44U#1l{31ybB($Wv&vuVX{UBe^XR zN9zem8sgNB26O?K#ChMTyt_KPJB4OR@9YFI%fmvR>oQL2e`yz5rt^{pQ6#gApP^aN zIZtB!9!CkP(9I-Hslusx)<1R-MN8I~|g1@r~LFEnD|@rZwyNK5rp`dWNP z6ZAC-jGF4}?my8`nn{LdC&f7Mq~qH-_1?* zC5VfSK{gHv35a?c3iB8OM+k$^IaC~ucaDU&D2n@d0nWVrf=JZZ)n`oUo|;vKZMpxF z!Rj;>3y(LYgVtkLv~V+8IHrG>s5aP1?5rJIx5gp5^Wg8(BA4BFDE8+HzC(enx!)k> zns^hiHF(B;w4Zd8ta>D6x% zE4*q?I#l4p_KrU@jO!AxNmU$3PMs#`iC`FeaH;mLY&XqMi<*OaXl9OLB6py5zS#JP zG~a}+ij0k*#i61eq~BIWoz&A_5tK(2(F7+(EDx=i>p3PE+H?C!QG&6n{o*{}OI#v_ zl0r97lquX8O?M*G?$2G~CD4Pl9Vr?jhjc6QMql^{;|$k8V_^ZHE2gH;EquhJ_w-PO zWQ2JMLT&r;HlwD@3Yso1Y+fdNNiWUMFwlv4>^bTT&K_-)16=^nP;2JQt8lHD6MQe4x@DDO* z(9Q0+mj%_r0&+bM3bg}TOuZ!G?;Wnu_JwF`@IUb){+ncp|28pe;Hleoxn#W-%eO54 zJ_Q`z5~Pde-LgJRS7-5>iT{TBpq1m|g_Kq4usdS>yQG+RS9<)|^)ik$LZP}LnYg0` zYm%V=wVGF9$;JSUqtjSRay7%%M@8+IK5W%Eog^`W+~|5S5vYyu@%q23qZ2Z-1N6EU zP9MSsstr%M4IC&a#GCKvgZ$w!bDyI}fDv1+Knn~yQ*q~vjLeXHa4pZQI#XG9*~I~% zC`TF)A69p|A{&!d2Y7=zSZ}P2OEQ=n2%`H@y>F1P;;^J*5c+kzrK@i9NpXoy{jxY; zc)ygy+&)%x*q+I?(nWwp^6507 zl;VmI9ru!*=96B@fgZwka5vLqhS-6|m@qNMQqOqzpgnDeU1=!H4B>}Ba9Y4avv|(Pm>isLx9O}7_@`R&7Z?)poZrTLY|%Q zB=c|!`n&Ct44{8)bo-pmB*H`r{bN^;8Kq@@?e+|4tP`rnYxX@RlBE>B1Wn>WEZb`l z|1MoBlbe#X03p&QDD~km;&IAJLs%)ealqnc1R_-<+Kzg=-e`u)E7J?C?54+I90+kq z^IB5mbQ~94OV=ctrpnig(*4A1w`>R-KV;Q?gR*Gp*_`-X3#a>B{~f*6f?G8^B+bu? zR+lv464auOtv2C%I(Fluv4LxjOZudKf~Zk`$@dd5(u}TT`!kv?#n;J@!R&av@r)!> z0D=jDXlT{hRFHW$nRZjbiQ45fKlS|0Ry~cnl{HJj=+VoHN6z&ZEPf?LP;SBKIBDX1D}3EzIF`*v-=-91S*Gug%yOb@`87V5EzC`6v}%YiX$)l{x%R z!x?1(0B>QYZ_F&}d}t2)4y{;OB{*chQerP!rJSjPO`|M4#E05HDuw#}K7@Z;s|R+j zc%_zA*3v86NV!rx{bbP3XDVzL%B8wazti$ah>M*6o#ay?SpaaSLXlLp$1skX1 zFWTlT5s3=*O3QEGN-wSnBc+Wk8ozvshUJ6qeM1agF^SV4huxIsQ4H7ixZLL zTe-a<-#RWvOmodoO2_yd2v{Lh3l-49&WL{?OY(bV_`NNsW>OxERk^}aXVn6rD-`c- zvogNycBtWmBRvKNvlV5RbSZ6R4OlmpZWWgfafFtP%^8sCsQ6-XGtbSxekq_PQ0M0g zGKyw=&R1tp`Bn-+6`w7Q_C~p*T#JbQI{k??>}^^p@#cNdRcXvO0! zTN%2tYM32tcbuov$fh^}jd384mxAr<$>%Mb94w>ZbRtm73AQf$#C{XVx847O}% z=Bym>H^@fqp#orL)PzE=e1iej(ffI|ft%3kn9A_+^IKQ>de*E5gYG?DGSJNr1V4!Y zvROr62IzW?GHg0lZ+FkQhdnpW{C5PR4+LPrlmqbpp_n-HRX}k(4=DUS0qjN!M!f=9 z?GMT&zniwBY`2a>BV*)Sf;JMEJ4GXB2^OyVyT%+sISR=$p;mUL$_ zMPs#HwyRivD(kD{Q#$%lfZDjV?(S|Zso{TYu6^s+>9(b3E&JQ{_7r=jY=_%(JsbFchRepd5)k(q>MW+6>B;}c(z^?6*S>gjIQ`6 z+oV&>qi^HhW8n<_w9*ZCTqS}q4pRusrSh@MXvj+=(Gsdw6U}yV=lzK3iqqo-fDKa2 z2yCU%>`UWsk{Fd~gG?q?z0GGbGUsh~=bZ5ilgnBysxGdZPS9X@yk>PaUqKE5^XeUk zw-w81rbkL&+c6^=KiV+KM3n?uc ze~28u=qj_tC2NvK)iM4*;AQ;X3RbyW#y;=hgwaLSr-uX1ANIYZSn}9NMEEaIB1Nj(dq?mT{UfJrXiqy0Fy^lZFe5EoB*FC0)m2M zOwlH&n2wY|YFB;AT6qpg%Eri-jIWaR?OZmQ1_0YBa{lbZ#M$xp6;7W$cWQj({Hem^ zsW&FAr`o(`YHIK-oa7Q4x{Bps+pTjks(Rc89^WJI_=gJAlGP5Y>i&%kPS7@Qiug(E zoO`r2$ifvi$p4gxFXGh>vIGo<&vbCPJ5w?x$xE74_r~Z-RVesHy5xw7$QTYyfcXsU z!_tJO0nUbKSn(YA`@$ibCosgi2uVs-qEw*dTU@NWe5!s?-B_te2`+9Lh?P_5IM2}C zJ&FTOxtZ7V1E^BZUauigt)Y|2taW{1sR>>eM{;vfGEs66t>9C<2?e5hDw7%2m)5;~< zWAr_=eWg;@D$Rh)P!zXjbL}H-T@928b{wt#j^ONZ9;08E0fc4@Z6Kl1`Vh_b9v2e$~P-7$;V^HbXvS~}#mcGuMZ%?!Zre@n- zka(S9Zx9$m6&Pw3ChRJZ7sWrWKqKwui~oU`jaIf%Gk%>$nnxN}7~y7Tpklk^%8PSz zOKm$kH77b(3Fmp6HY7=Qf)yLF8B47H+CSplmm2R%T``yTNo|HLT)YrZ#{WVu4I0dd zrcsagD>$LxB?T80>``FcxH<5>sK-|noL2B%8t3;ZHm+bw!J7oen4gWWrO`LyvR=(7 zxUN7psCZt%qJp;++*WW)!QWQ!wF_?&{D zSMYfSzog)o75qyDKd0bV6#Od%{J8Q(L8k)S6K~Stq&mhACmY4qDki8ftABwlzZp{$ zXV74q3<~G#cTkoVTkj1#DB1>w4~0OR+!y`6$(J6bZ1Oz>u%?jdo{kq;4zhcQXm3VT z>+b03#W%mRXCodc>mI}FLcT2sH64AA^gYrKbIaij@8KPJ$+wy3W8Iqw_x7+0#{chm zjpyAkz0dM@Q_sPk-kxp5Hgn8FZ_j3x>*?TWU(X|3uWjACzO=J5M%eDj~yjp-V*j;m+7H4}Sg9Szs6 znf035braW3Z^Eok7_U2F>=Cnx8Ar@hW1blEtLqJ88)kjd3{Pl!!^BgjH*MCZjdwSB z!A#hu*=?Hak?}kao1j1O%%_0VoiyDkvsE|iGp0LDcyU*xD=GS)LYr*%D}p0k>d&XnVoZHbI#nkKX2Aw zHg?|FIb&ZoD-Zt3+}-7K*T8)n@%_7#G#zV-uZnEW!^yVE9XdixeOy$4P2Zugjw zJa6`}?t-xwjeXT@)<+wiA8qt0CeLZ|SB#ymK>paXxCJiLW+ee1<~8FrWAQ;Ruy2`_ z&p?ct*~0K~^Ar@k*jP9)nQQa??sV$ zxtkmZ1FwjI*J@xOSyw_nwSVr_gLA)M%^iX@4lx|%m#Rr$6~HIeq!FqWYD*)8#M7!9 zH)r;byfnHIe^bhnuKInP@T_@G`rm^^->ms0x_;IdY_LlrO zrMYhzi_c~8<7)Z{^!z9H)=`FzNbTYx|e{ zPTC(v$(En?Z59?$n&elT%@32pW}9Kh`uU*O3$x*kX45bKqFz7E3auM=?)mSi=PJRq zhL@_z7yMqhYyHr#Hs-jWZu-L!ywOtPvv2umDfHFO9JtA=G+??z!MDLy&O70@6VtOR75_)vxFW#$~pWHpir1ZsUjG zI22;&cfvtVtr(HYkJGddL^du#INj)e+LLhpW&6-(!(tl(3L+K`5Y?$jQ@=OpY%lxv z>ef}^5q5h~0wPhRA42xS0xBq>8e{+^*5}*lAnsy6ieF~CKHw*nZj`6t#?9u(*cH^w z|1)a);lniQ5~RhEMvU5!$pBq=m9E{460DYH;bm;KE_(xLra_InoO>Ml1EYz9T|?E2tC z$1ayQn;Fz`86Y!%Gm6=rc6M#C41rF%=_5B1W?48?vl%8sKaYA*90GT452d)xJ%LCk zOh^VDR$30_c9t6)NhOY1O0{-IzEb%i7d7`y=trI17&N^>NR&^UTZAnS!=2(7WNx>& zEQlW!VYZdG+pSB>O?Ba%h2_1hQ@ah~j=HY;{+e|-cGJ$F2U^S1(5jY}ym?+2*z@X( z5{&fR9B{yimZK^TAN?EtR$CsNTX77RZj|@KqO;wWfE7p3B@fU+Lw}rk3*USS7mFy- zGr?MmL#-Mv1-skr1YBvii>7WIZ*d;nneiom0k^kr+;a+X?d^MUv~iEbz1klJ+~#e3 za{_I64#A^ne>_|(DB2%|{bB<5T%b)WkJsT+;?2?9_~w6yOJU3xaQB{h?3n_QLCt*O z=@t!m``3AO6V{44#~64|nkRMh*vX@!)w+SbY*)^ZFili&DSKYM1)^SE5#PL#;ZZX?2rK>$X9|!HtmY00O4{9@{%G6tXoQtO)NLW@oDE z!u^``U^SrjIGH)mqYEg96AgHWvu;fuU`!1 zZiBO&LP3M2i8@8Q9lXRIYT=-d5X-hmVu_G6nl4frJCsurLWk4_86nvX<_bRq*qpl? zZ_aDtJL4_Xrg5Eva!%tqUz_(jb&PWz#ppJ^`A;BobPH2vcgkcZne>B$NDhINQv%v< z=UK!!Z~^8URvLt6z2Y|8axTsf9U-&nhrmm?rH1*U0XxGhzyXk3pBQhrXmDgqgQ;TY zq){aYq+%uK_f^ROfJs$yzL+%GUsfJs1Oz?cyK_fVa%yh7pKCiz!+N-y-y+k-C}9bX z+VF5KPl##}JevarKjuKWX;(On!Us^82G8cE9XUAdyPQT5#~gUJCVd!=R(ZCgIy?#h zkX)cOQIQZduA3Ez--tFIsoA28$ywYP=e1Qb^8e%Zz<2Om4y9d%91vbgvRqyul+NQ8 zj*b(a=jCX}R$KI)0fR63ny4EPdO+zb7H}DFGje+zi}HN1A?=c;(QqqLD`=m`Yr-P! zMV&xwV! z!)atdE&mC=`5j!~CcWtzv=BNtQFAVHp;q@6y;B#!8Ly7-tT*8;c_+}Csv%}{ydX+MMlNU#4Z0mr z1)l?gcAX@Ic)_yXx!*GP;3kkvfVP+j4e9}W6>7dDV5#uCq*l#mvK1PRm4>!Xz z6%&EIXO_S|rw4dabJ0xTa8#C?R2KAaVbrl)vsd)k#=}twH~$EmeFv7DRnBLNWo4@8 z?;&|pZG)D*%=>PY^|415%h10uuD1FcD28p@2z9wG$|=_04j;N&4@w;a!ffHLah*FVu>AkE}y)M(i!qCd*B4Fs0s{}8={y++=0z@ z)Y(R*jWsvHM*XLUn#xeMB^2RMk?Hz_B(^9J=V{L(9Yo!Tg+Cx)siRf`0Rcr3kiu~F zs>5crMe&x|a8~4NxcwgqM{orzk5U+>&@j!qcgCBo$zf3(=t?Bte~*Tf?=p!vTk150 z8;mZ;TpsbM##|l&wN}9Clz`SjdH{82T7et^X+@PUltXpXhE(5%Y(u9O?NG~=g& zf&vIYATo4m#*|D7mQ^N&76xt>p`gn;{+8_>OjaDItONH`W~W(oVZ6#ZUc-TvDJU0E z_}^ld5YRRT<53yom)Ym@LX~tYUSW$_LvS7!Wity0LStx2?GCoK| zRi6UVE6hf|^tkf0M?rJ>sB#z{4tpX2fNWyIH$1c{I*>WWMPGU(+$3EVha-=q&=`-X z9^CTiljiZ!3Qgn>c#aJ+B4qfnAOfg536$6#t%kq!_O9@DXU2KWvjR3_9?u$7vv?9j zFSB$f-h)5(?gAk$M~>s5FVyznbf@5MUpJ4Bi8}wPGotONb4=91{^&X84)rsbb^t+s zq(Gf5F$$EzP)zGI_?bydo&2ECGwO;}FZ~u5?n` zNyQ1i$@N4GbpzE17?x>AsVhQ2Y>T?08Z^#|x)f$5a?UK5vrg!An(C}>2C{a6e?_)} z`+4-TMYHeM%^;y0fL*e*UWDkvk#rsEX{HjbFBnu*Y_LiF|S0#gD+qFYDJV-U59 zTUgOj8|wM~2T>z+~ikhR;7-~T=AE-Y9>?*-|77|{}zcTz0G+bi=r9xOhIgldc` zHfX>QZSpuc=vwOpL}C>@$Dw(_8!s>a=pVoP7w4wGtvqRO`1$8US%`3>qu-miZcAlv zOR}&;`S>mT=G1qqM@5Je0R1W6#(-FPx50GYkjMh<>d_6@48Ti_gc@|HXwbMykO)QI3Z+uSDIk>x{K^PL zro|2cl@sVP?{X;4{GZO=YMU&+W)122KL;0=a zE1JHDhEs(d5to{PbOaQ=zNSEU)uq40%LT!2q9rt4jr|@6@cpktEQM}AB5I_8Iap5- zGH;-J?=o2nWWW*DPw40I0q4YUxJdGkt{EiOf zv0o>u=3fAqd{U-X0Uv)SQRQb1SL}$AJ-}|y?xT7O5NiEGHA_1x41V@BtiDyiW=MsV| z|7a{9)9$gs0r_AqgFx2h_Ow=z42Uh|qQVXUAh}!>Y;d-ol<=89>n|uR9~2DP*xle8 zn0ZJndG0?MW4Y)#wIERxM2G-^sDrMPz6&AgD8!h|_A^mKMQH(zWi;bAB!24YxSnh7=gnZ7K#7+|Qw5jfji1L!iDkR6 zdGUZp`T#JfKTFV{qlnOs>UZ%3V>k93!GHC80j(KCaPEJ9`_v?3zTgwU5_fY&TI0vA zy5INMRq9kdc6E5K@Gy*=%g6D;lh49)^**xUE{Z9#`g*>V*{uMx-LtoM_c|!OAX<0N zz)5Y(m-+OhFU_{_ng!oP!dr%!4QP=hc^~SH#BqRMZjT5YqDUA4kD)?naFQ*?km4fV zmJ#pbG}#iOn{kS8pO81wG!EY7Y~>R4ots(uxy5^R1$;5=y{p7>K#vFY7^_?{DXIfr6^%9qg_{$+h5q0M zFW=(j7N?PfAL%_O?Z<*qaGMv})WGK@<%KFc7HGAeE7en&zv5o$_!hlt{=2v|kb*E0 zI8|%lAN!)oXKaa^^hJpJw@A y*Zc|GRjoSIf%R<8n05cP=?2yv$G6c0WI(IoJ3oDLwl?#2y;iR;)~A1Y#`|~0iI`IW literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/copy_reg.pyc b/PythonHome/Lib/copy_reg.pyc new file mode 100644 index 0000000000000000000000000000000000000000..40c56234274fef21ca21f87d548445ae7327d9be GIT binary patch literal 5058 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 Zw>qL7b)weodv~@)9K}($!Ee!x{{#fp_Z9#E literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/ctypes/macholib/__init__.pyc b/PythonHome/Lib/ctypes/macholib/__init__.pyc new file mode 100644 index 0000000000000000000000000000000000000000..cb5787184f97ea296ac47b7076bb6aa8df43ae47 GIT binary patch literal 301 zcmYL@&q~BF5XRFksALg*gz;oAwt5$F58nK9=s{QtF($J%m?ou@EcD`2`DVU=(?!^U z`Q`hVkD07~&*jhCduzmh75qMM(*?r{v1JxwTL@czkLVWRXr8N^wT1v_9xPPQ*#2Dz@SXx@22-Pwt~LX&#Zf encs`uu$7bQk|UG5)uW zZ`YdA{VC!9ZG85w5eY>$Q5p#g(l)XQ0)Itm7i706n?*6Km!w^i-Lh$6pHcipdEVAZl@jO zahi_*ShY^NS4t<<%TqaD-Y#y}e$##EmS-4(68+x3P8#9mlm_V*6^8lbPfCXV|}XVDo7AxbCv<2c|8LHQ%w> zd^>Fh?RhrQ%9I%E^~H@Q`Q%r`w}{VrC~}eKD2=>?TxUsdLlvkRSwm&5R^UhuUrlo_ zXt%wz<$ZN~t3W; z@?53zq9D&9Avf&0Jb{c*-!2^rO$D}!*&;V;)RG>0HBF+Nd!<&-86{8SEKPE<@C1V4 zK)ctDb0--#V~BP?4KiIKdm6Ndk^q%YY1FY2C)z3sF;)Cd;wzb+Mf8Ml4FldRgsy3H zPk9>Sm%dq9s^7i0@S8jJwTH{gcfYPt%RV>rCs@!x{Yez6N}qFvItM4{IpW>mNmRF; zRx95B42@2odZ6A>C^^+9w|2%&mI)F(12(iiuS^4JsW%H1#g1^=6O!(mU3a1)|bo&0_NHvG+El9S=W%E}iD zi(l5?u`s!T6DAO+5j1z|uS@mUZ^Jba^>wb_sd%~k>pTz2`PKl(Gza=f&klZ$3T<@| zUD^M#CSO4qoXsrvq!0NZ0BZf4C+oLpCEavQ8g~{QHbY39nN1R$2`M! z8Ye#8K^5ExY@`#}<$uJ2a@FLj=hZ$Z4<%qiwF)>zijl=30)qvFPQ|3x( z%7uHnT~EBXQNdyRR(+Gw2@%#I;hPjMB0eOFMhruIcGiAHMFW9i4kLr2+ec%oMA-_V=0EU(fhnlx2TTo|iEX zR`~k7W36yYHn^Ts%=g@}ntji`VO&49_g{5yY-UfG{h!g~{@-2yr8E0VR=cecI0j6A zmQ_u0`s%#QHfk)_aC2vQ;o-`If$+H8jhH$8W~tkK7>5o!)p+`@;(yHbrctzx4~ObK z`MJRXgRy5Q1M1~5Vblsb?YwI^$aBT=aAL{@I#v|`dIkR{%!h?3rAJUUix^SDN6cNs zXa9tvZ%vMNan8v81I7{f8Z-~HgP!4DfDqD(Lh!p@`%48j3|M+RtN1k{+oQblG8`Jo z?vq&i?!Ih5&+t}EY#BL^u0O!BnE;YEdjrL|ho5C!;Jm==3d%zW?V*v^!L8(pM?dO^ zNu6Z7{uMX8Yu0O~9gIkDF=|9!E5#*f)!B#|$~B%`U27`R74)`NB@x|3yT<{}Yc!T*$nhNG*XhEb@`Q{x)ruBcL?<|>*q^B#1@j5(c=PeQ>W zNB$GV!Aw7WCNk=^=cOsEZ6s4tg4%Y*C7TxmATWuMuOV*U990+a>*u%-mGrV6cD2he zrmDr5>+W6!RU=|;BQQZyj@A%_$({>C821K7rhAP1LyR%dKU7U-!ZOs&iHV<|p4BPAEp6xWZyujYjPMVav3?He^^|t)M zj`?+5p7C5^=NCI!h9pi$_LZ*5LVum^qsADHrrPy+$xutn^i{%R#}Qnj$++t%!(c1v zFRoWrXL_yOXM7k5qy3>QjQ;*-e3psXL#WO(ts@}lkI9!&Y0}4y6uY0wAoe5hzTclPbDt9v;J`)7M0|!NqSnnm!UOSQ}-0esW&SBM*P;<*hl7Y+l!BPQCsGEt*1$ z88H`(CRg?PF0iFuug!9}Cc5=7ZPx2f{|p=&u+%!RQrytzDowtaU*~Dsb}th3I${gv zUFAZ=uV{Y{&p90&#h>Fc^DGqD&XUsPPm^ZN0I7PPO!yiBiG4>AkMi+pD?YDpUG|w7 zf_*d$g=#wc=588x+R-g_^qW{=1o7w;e#eU=raCeSyDOSXsr$cJ8L5m_%hh7{_hj{S Qb+meZa&mIIQm&f+0?cV)@Bjb+ literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/ctypes/macholib/dylib.pyc b/PythonHome/Lib/ctypes/macholib/dylib.pyc new file mode 100644 index 0000000000000000000000000000000000000000..05973c2ae4b7c43843ddebca4dc95649bbbbcf9c GIT binary patch literal 2255 zcmb7F&2HO95FXN!Y$^VUouF`gC|ERwsHBjSs}b9E)AR>01cL%nBvsAQ-6cN%6NuI~Dph$LI?-7YA3Kx4jGS?h#*=9hm^e#Y@!$CLOpASCh##lJO#h0d zyZ5Hka`z4&Cs`=i-J|aPj=Q&gbiP$=q`_G2wj6vIrbk(BL^XK*V6Ri^w+CI`e5G=Y z>vn%Q>iR!E=ydjG+rF4ihr{^Iwar0S9J<%)v_cF1FmF7bVCYXF4AD!A&WQ!L8bwp$j) zPP;v&g9UR2RgV3B!lpc(OaFpTw4FuVpoOulX07J72ba%~aST!r;IlqQQj3*d+ z11ofqD}NTftJ7P!B7FtV1G}e7q#u&8=@(1%cp!8Aw-vqg8$2rX8*~~pn2QDOF*>PW zme{t$G#L}MD7pot#mL_($mI%hMUbm>QIiAzsKC}Lu-g=^Q#6PDS%Ga-V0X&X_};o4 zxM~&AA=tiq7u@thP8g3{7<~-=83g(Ux&*s#bJIY>J-4~fo}=5==^O-5z3(=F>`D4& zZ$gqTN#&%^%i3@%$}%==Rn)7?SrQYe4EDlfq{r#>_ymueuE(z3s4$RJxc&%2FGCRO zV)oS=Sclnok|?8+v#mJAqmLuB#eY*PKT^lj6U`nRZhf6)MPHKh4>fyusaq&kdVPj1 zYzqs$R_s=F5|=!f;*yn_VRyeY;%oVWaxK^H>pL@CdDsli7Xy7&E3a>^y|nG_S6vaO z<)*6E<&ZoPn2=e8*w9`H@+Vv2~<4i6r;g-TnW-AJTCY0EUr+T k1;q{h=E8hD&Z23ecBPKl;fB3zH|@q!({6s$Twk{S0dJHNi~s-t literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/ctypes/macholib/framework.pyc b/PythonHome/Lib/ctypes/macholib/framework.pyc new file mode 100644 index 0000000000000000000000000000000000000000..17ece65d9f9650fbc57df92ebc55139d83d80883 GIT binary patch literal 2565 zcmbVO;Z7Sz5S}yGfCC{-XhkZuI<=`dClQz5C_pWQ(<-Tp&QT(zl*@6qh70FA_jVmX zfL!vAyfr*>7iOXTO=di9hG+zde81390y0@c%WM zeuge0dV$`es6vTFFCa|N9)t=hi(XAoG)ZR|PEu5*Hvm^Ds)2~3=&_4sdm+U7d&W0)VO z-Aw-qm9u`-s5|Rh50fku{Myd)-G;NivUB1NCsLSRtK0Z6Oz&s85!LqLy~gs`qFW$V zo~c}8TkSIX^>DEE!;bsoy@uOZAK6(Q+i8pz`eJ_2?Z!vI`@jRDwIX4kQE?;p#ZNK%b(QEt;h$@d4~GNNp1wC_78hy0+O@b~j6s z>@ZIEAPsVKc~7s%at^?gB1Uc->q}=JpShFuR51{Y-;witxPkYsWKaI@E{v^<#ax*| zo@%?zM~}O9ni)QD8r`?E+zvpXexHM&ej3EDgG8mqHraU`qBu0p*foyKh&`)IqZlpS zzX0HfuP$9NZkKF~IWshLX|~|n>Qd11`zUJnrsZi($0(m4FY4AY}i2>*~1lf zkb^0GPOBgheJ?n+ca_9Zj$6dCpDT@^iK^{PGGA|@>pb;~Oq?c+};9r*X)e`=wq(|A497iFHrYV}Cvk9(<`j-->Ucy{s zOf*Z;9FP_xe=i}gmv;H1q@OS8|0?Nklq`QFmT%J8q&V=Ib$-}eCD=j%V+X2&d{iKD z>W=d!3*~M?FLJLOnx;M+w7o;-tclhZ8&`s&sv#Rf!{%?Eg}`ex!B>dwLGDTW;&T(CUTDnh|vVUlT2HXG@HfOt?dR zOY>b^Fz&XBZ8=jftQhJgD3Y#2?>K)h8W=qW^x|8m+@}8Y9g}WL)|Pi48Fib5>rHLH z(?W5I&jEUyogu`T0K}6H0?8XfQ)`uTecR0QEEl?Xd<|D814q#)ZO+S-ymYuwYYrV* zi_?qN@O#I)E7FoB-1hxm5U0K`FFL|x-;c7;_mOl&cy=*meLqMNs90uZp*VU>K&fq> t?9Qb2eNGP8g8TueU=t5}Su{x0nxxSUC~B42%1os;JyV&vJ+m-t{R66ydaVEe literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/ctypes/util.pyc b/PythonHome/Lib/ctypes/util.pyc new file mode 100644 index 0000000000000000000000000000000000000000..b5a3040a50fd6d2dca1d3e8c588153d7da2a27aa GIT binary patch literal 7914 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 literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/curses/ascii.pyc b/PythonHome/Lib/curses/ascii.pyc new file mode 100644 index 0000000000000000000000000000000000000000..f1040e365166628405b75ce29c9cf55e95b9f27f GIT binary patch literal 4775 zcmcIn30D+H5dLNt5D-sLP*E4-vEFBHqp%C85m)WOtDjG@Zmlv;*xffXlYkRJFR$Ts+GkY4y+NFRJ3q#wTDa64o>{D9#O$N>CK$PV~jke%?m zA-mxBKz76Lh3tVJgzSYMf(*j%gABp%hwOtNhU|wQfegbRfQ-N&gdBiB1UU#l3ONLS z7%~cf1acVuDC7uy0df?63{rqU1{s6@0CEieI79`-6OfaTQ;;I$G~^8AEaV*IJmdo8 zBIFX}GUN*6D&!jEL&!&vk0GBxK81V+`5bZ`@&)7u(?J0>WHFHKM;cTG?}GbSjjdnPEiiV4c_z6r|nfeFg?p$W>_ znV`%=6O{j~2|9~MCg@xqo1im#VuH@=DZ=72I>J?ja7%6F|TP0gg7Un#Wa_N+BC)7CuB?xwT5va`JaOgW;LT#>%ma4$@Qo;(s<#s^|c?jo?K=hu3yC*KjKt2O3Izmk3ZLIowax`He)(Y^wTETv|Z+PTy4!?-y%{~lKOrV zq#UE%7hA-ppyO=C61C!}k=|IJ6i=^JUX(|3bUEw|w1aWBow&PfJ2?ip4ej#QQlpmM zT*HU4&;s!4J+&>{<=oJf^$+ucJ}%nHzwUW&uWT+FB&}+#KCY^^Vh2pC#h+~ouqob-f2H7(1sD=nzTHMe3ew%n1WRdy7(F&!v7uX*n* za8s(y#~WEWdW0R_w^ZolRzu6V)&DdDJ7GIBa369m8#w8iK+x>>wvc`4@9SS$v;M!R zy5i>9bA;+b8oq-(A8~SJKKojs<2*lV!mWk3ZXV6QwSvvz#~d0rEg)Dw{U@F@m+IW} z6|IHyD|)31CB26A?O}b)F}pDy$E@9d$YD5C2#bvD74tXS)GuyY-u}Y2YxE0wanFur zi$Mdriv-#;>pQNJRRAxeG_eXGuD6QX`LAg|_Z5$uc)==8)^`X7^xqfk4hD0hL4VL2 zREo^8ETNd2lV)vhj-eCIB8eS%W+pDBqpv%T>NqRMsAYs^CrXY-k7KE61yW_kvEp>B zI2|ia$BNUj;&conjuodPBR5DGBCvpQtUw$qPREMVvEpiF-=_x1FtmEZZ# KX>U%S>;Eq-TgKG@ literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/curses/has_key.pyc b/PythonHome/Lib/curses/has_key.pyc new file mode 100644 index 0000000000000000000000000000000000000000..09d506b9c4a3200900977b5daa33212b8822bdb3 GIT binary patch literal 5907 zcmeI#`F_(@8V2CwBm@Xa1Eq!1HC<>!ODW#6v_NqjIZ1JB*Gfo8p~kUg;=~)40)#>r zp!>c+p=CN#<`(A8<^pD3y*i&H=8yT!1q?~-M`!zvbaeEI-hU1a{A207SyB35KfX`m z&%Os$@f%SMrB;-x-&WNgWhu2DQDfC!st4+$dZBGpAJk86gSJ!s&<<)lw3FHa4NyCw zUDNcg&wCKgZ5F6L;IK{Q_wV(h74*N%1{P0LuH^@Y6hC4W}$beIp`Gi4wR)%LGx4=%2D%Bp2|T5Di6I& z6`&&ZE@VU4PB%z?O9Ox3Y30U>Qm@*>NDsI>T~Ez>I>*A>PzTr z>MQ6Q>TBp*>Ko`g>Raf0>O1HM>U-!%>Idj2>PP5j>L=(I>SyRS^$T=|x~;}m?x^ao z>J}dGzbfmls@_!_J*s=V|LUf?fWmuh_nW$@ROAY7vO8-1clTiWTtTheR~CMi+UQp+ ze^C|&xUX(T)XE>q!r>okqgQng^jr7T`d?Mm8|iPljn|;otM;Ko9 zPcPhFg|5@*cBz#I%6gz?W-s38Us`T4BblSWAw|{yg?~Ax7u+aE^>^I+UXAH*+v#)b zSFH;kDyxoHQ_(#taa~bvd2m)Mx}?z+v^APljn0-v*KxMF0V+;;)l;>y7WFEtji|2N ztZH?ebv>xn(qmaIJtM2(&CHUDE4rd~)T^lJacj||UVvKEFNsNsKAl=LAtgz{m|$Em zA(+$=WSE#lh)IN)UnLP@5+NoLViF-H5n>V{CK04}Tq49JLR=!m{WcOIE)n7qAubW( z5+N=Tq*Fp7BqTyYA|xb2!fz}Q5)vUH5fTz1ArYi)QX(WJLQ*0mB|=gnB>i3zAt@1( z5+NxOq{)~>7?TKN5@Af=>a}sbb`$!0QZK69U~7$zcN?y?o0g}#e~;FKdvsOrh(^O3 zpxNEfu=VC?wl8@lEx9#Y9j~C>(YvSJ(Kl^J*L1qNPX}9td$C*9+o@~SbV;qN(b2KH zwlubE*+X*s+hslClriIVOQ&)g^V1rIGaAJO@3Ks%^>@~*up2spk<)#Qysk2q7rZug zxr7;MGn*}VRkQhdZ@js*SCGx*3KyQKa}` z?}v_@&DK}XdIO$aE8C?FYwHM}@@^b`_yDwb<3mM;Bg4JJk-~jJ{U+1-rJR2b z1~!s=vE8BEEh+OcatlT=sKFlfTjfoEC}SDBL_%ba28{a6Gsv3KHG{+%I2Lj|}n*`-Y}~R2{SlO#ulz zC=X2`)D@ZAZ-V3>`eC&E5n%j z0V+@(2~GFq#2@~lr=6JzDtHh0 z&3F?8NA6wV$Hi^n*KqOulaW>StGUen5!cyoEUPJNV)_dx*BB-43d+4@2D!!LYWhPJ z4R5jhj^1(vhYzh4?nEq)-`QL=ag&9vS2(4acq_^W%kdvgSt-+7EEMnJRxJLB4_^Ed zUqwnKyd5d!<(_)0?${Om#%dv{yRRuo@;pZ`$&+|{K$0iRosRqeJ@@LPq5E>fVw7F3 zw>Wft6m{PF2=!lIO5D5RShHQ-Y*;7UncK6N-C$pDWZ?fl|I-y1>fO0}u(vnTkJfwf Q9_Rk-j2!G4hzzNJ1JJUpZvX%Q literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/curses/panel.pyc b/PythonHome/Lib/curses/panel.pyc new file mode 100644 index 0000000000000000000000000000000000000000..84e334c45dfb0fe98acad123dd475fc26e67a5bd GIT binary patch literal 262 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 NJ|rBejc&19{04-6J0bu8 literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/dbhash.pyc b/PythonHome/Lib/dbhash.pyc new file mode 100644 index 0000000000000000000000000000000000000000..0ab5b9558e3a3af2a4e021b2915ac279e736ab81 GIT binary patch literal 688 zcmZ`#%Wl*#6g_q_uP_xwl~^J#1A=V2VF48q>H-N>Xu2qhDupDzo$*W_qu2}`sVmBg z??L<+9{|@0r7JAo<{l=gh)eNG*1xH2%8994!$RW^%yk4>#sl~@KKMUCs?xH6cl1TLpp<= zLNiAA#^;ewejY#Yo?bG1=-Qppq;eH6pX#E1QMUCqcc!RFnZ{9fm6xPks|u@ik*spN zYPZxR<~NTs`-~+_qmGm7=gO@}>B7HIb*n$K0CQCkHL9b!-H~>YPwVn>Q_+qpBYEq5 zi>T|`&V|gpxD!k|^OKh{VCuu)z2&e+3=UWe+yFO>61M?YZpw#umSZo| z=eRNz4W!DKJz>8T^EG;~51A#G?@e(z)RS!Y3$Of$!+HYIchF6kW|?lwEOTDo?rop* zOWrl6S>A89`{T{R*Wi5T-_=_#_p~qCOAPHAUT0a8*Ti~*c3xFkw(!OE4(?6<*J*Fy d)gXD|KibC(V>uUdaU=q9C=O&KCUP!k@()1Aj$;4- literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/decimal.pyc b/PythonHome/Lib/decimal.pyc new file mode 100644 index 0000000000000000000000000000000000000000..837ea3e90796d653eacd83211480205aa35d28f3 GIT binary patch literal 167489 zcmeFa3zVH#R^R#Es?w|Uv?S}{NBi2ct&%L2OR{CjZrd$emfdQ))$S{Gt0~)DU)8-O zl~lS_y7!hPb=wWJorDZD450%gA*^9m$Yhc<^aMge5)u~8z!1oU$zuhEWX*y+m}G#J zz+^4fFqxj;|G&@os8Y!#yF0KlYh>4V&v#zmdF-=aXP+Pkv$?(D+uY?9jU$|kAs?yP-JHanb6Qf-7+Ws_7M z;WgRh+U&+2zuue8uFI~BW|Ql)T8Hm_AZy>3y*-poZphAc@5)9x8?(!!S?{N_TCLWu zXYbJL4OzFAeVPVM(yT4nBrUrmo1}4Dvq{>wEt{l?+p|epd1p3BLw978v~_jX*^y1t z#QRmt+gbLFleB$J*4gRU2Z~s_vo??2Q^fAh+7D)(-Ol?^5qp=0iW)k1XVdii;UeLl zti3nSK32ruo3-~THf7&mB+%{A{F{#yvG--|19>F}i`cp*CbfFJh`nEPm0}+)Vjs}- zb?(bL_q%-)MFOM0DJ66s$fkjSLq!_>+?93iaq=D&?YQUUyRbH!d?=e4aUbr=o={ir zjh_$1Pd$5L^5N_Tvk`N>H=EqcOg>-C!U3w&|o$J0teFqE~Ylf+>bI?iSD${;k@YDOyKt#;*Y5M z$%(A}gae1N?uqQvQKLTfNTymI$;%%YCLARdc{F>cmQ5aVhGPy-WUtUVN*&JHPder? zt*6wNr;5Hjo^_67?GHM~6Io|%cIjw#=~&jGnYFCeemXDlOi|)VEy`5SvqkJvS^GnI z?C~P@gIW8zto^)ee>$6C+)rff7qTbXC$sj8{JfO4KO8@&`1wfI{)YJZX#9LEeopg4 zH6M?km*eLX@zaQ(Gx2jaem)sLpW^47zx_}op0!_bfG@n7 zwO@1o=d<=VIg;i!9e5#Yzn=H6r5G>KlUe7aLYH35Cg}_1&%6AGv-XsWoyyv62R@R` zfVDc&?djoCTBFAvrRc#ows$Swe13t9V(tbHwOU(eb%GRFGtY|Z4y^0J?CS#VXQ ztd`k>*#!`}*O&$oCsUd!6w>cBT?B-)>MYBOuU?a0@&_B#%=v<}*TOwE`)@9-aYc*@~F;c(mG z=N#@h%+Qj5+Tpt$zL0e&J|!eKc`@rS)8Cd|1`F(3lTgj2Y?67epqli8qCaf>vPlf zc4unlN^7=0Jv&ES_dnW_5uR=?A(&vi!!7d!QrI^9l>>@TEZ z&z1Sk%o8^~Gv%tE8Xc|k@8V!E|J0+8_UAjZow-48?v2j))ZCRv(?|8|4~<_OT$vpm zZFSrAQzuWJtoH{5TfKJu*pbH%9(wZF(Z$tuy5rYoF3-$&+B2>3x!#3G_4cSrHuD0b zqj?LLbnIfQU!R`o&I~&B`5q1KYaFi8S-O0FX3(QOvp4Fqt=@%B{rucQx7{BfWf;l5 z(3_v@cQj@Ljp~)T_QGsOgFBe3_ZQ~p=X#5VZK1ExoNis2nVo6%Mjz-;U7VYny*Rhf z?>tcNQIuJszZ7o0F*nn$_vfyp$~*NzZ)WQ9je4&`6Z`pWjn4G@3o6y`&rQv=226_E zeSW6f>fKl}f#dbM8{L|^+@dG6vcn`$YC{37NV9Muu8j4m|(e>8+{A`-MeqAa2 zP0e)&o$G^s{o2J&uT!U7uV25|dZRPixlU~XMGU~jmb%`l^E20OlU?JvY`f}Xs&}TV z8J_AK7@g@ZpYK5Z(D=ke{h|8A_@VlRnK$V7#Q4OMi~k*QMV(fA)RWSwN2?f^H2GtD zDKxQnA0s(f=ygdrf8!PqzmIADusW%JcrH5ETUsp)#xy2*X^GZORokteD(IpU^|9e!;5@gtqcee~Fqs)=$6Rljj)T+t^VDN~Ek z;hU-)e~k9kA1T{R>7&)!4v#-^bFV>Ik1sCv*!VGu)elxGIyV0JqTxAsc>Hi)ReR<_ z{h1=~p%~Tqp75KJ9xaj{+c!Ev8`D2e%!P8|_KgcuP}8AfPFlH!yr#z%=O6E1?G48E zjUK8*=hOJuz9Mz}=wpW`j!YbzIC|uXW5oS-8*L%z{dUE{?Yj_!6YEG~QS(7sz0j=ZA> z7gZ4TrfMExp-zvUZk?`tG9~SI(sE^EiY6AfYtgiTt>^o%yfE{IvH0^hCOf^k*ECO+ z&*Zh7?X{*l=Rt?{u`6@^0T^Kl#9E&MA%gAugMCjyu*S#77d;nO{Z#!rLongW1rBK; zGoc#DsqtvesqP!C*_rmo=b@7#vT9J2i6NO9pPp@9=)ZDPzR^_kc$*HjJ7YOyOzb;Q z0P4iP%KBwI(@J}{Z&wH7*58g?w@iPJeaL&dLQme;oGcx;r|J{MtmNOl)d=5iFW+rE z7tiGiJzNa(w;bNU2%`fO8(ErmhZBSiHaUK}wJEY$@wI zd3~xgFL;cKXQ6GKwlgdp(D>S-MddQ5x=_Tafx``PMwExg%+4&F@6Pq$AqQ)D`}iB3 z9xT^2Cw-Dk@it0Qe1*!<+n12sP~IOgQ1PF8cBIC<)$ zr%t~#SYPCN@uMIAc*9?eQa4xO50&4YI6@Y^mL%D)B}N%&OlRjn2~&yh86o1(_|b`( zuk!EoSdCYg>9(%W`31NGmq}B0RuTQ}`ozqIu1L%btP?!RTo+U`MSP|j^!E~febxRZ zDeta$mn)+A*xdZhC zZwKlHu@e4A0{k-!UgE3GB~xIg-`xub zJ2hAke=I(?E&kVaw7NHFWB0-V>X=)&a4`+aMVNQk|N6m$^%L~ve_XBi`MGg@`Pl;*uS(}P$63=5Lll-BReP9NY2 zjM6g=;7!#f@TK_2=FHJXX|)1&yJLR3>;53mobQOWZA}k4(cipH{A$nu-`Q3-#6_6( zMg1Ckk$$yTJuAaN>sj42>P+o!+)d<43w$+sqPst?D)hyy zHm2&l_M1&1qGr=Lso4yPlvk0FX0tsv)oeEIBV2yQp=FUtV-*>Hh(DvH)mvBBrg-tc z0+EOeRS^mJLuvheH0)$TbCQ-?kmM=aeSu}fxK1;sg(xlXI;%B5H#N1O)d&=8@>{cj zXHcblz2=xRszefo{4q&=X0Frq^gweE*;odsGI~r~{xtzE;nq92_$oj4WaW8^y98Zb(% z{eDMl-b*^FU=|p?g{g9y5`JQcdUTF2wLuQmMlrkYdLnKX`se2@*J|)%;5)^t8hc=R zZnk}}J$J4901~z)e@siFQP<;sJs#k3TL7xX@HhGMGFUx&GkC5@=O%#D=ej_PIrREm z&Z5_^0aUzz@}cVq!G8)(5Xu_VUjVTPfY2wDK`;HJk2-_S#%Xl`%2Wt2GcXIMiuqHI z51u;xBEm0EzfRQm*T)_?xG#TCVVKxz?Daajj~KAX%lmb|Ux&DK`jEEH7=)sG5D4#F zV1oBK)gmUSwSE9;<=IpPpWL5<*A*PAl#5~!U1=5L8Gt`I|x(J2f2IN%nvSO42T#e?1 zafKhvwmn7QO?0zQWCI6ar*>beDas*!hO)tM_V!5j)^PUbaCT`Vd$T4j@0r0Wm_332 z=@}l`K*+N@Cb%{u-h{PlisCfU|B1KMCruemL7Ggo17~{+oxuOoGuI&j-AJbECJl{y zDc1Oa9-=Wc1#Yst5;JK+@oQx5ujP@|R@e5_HU_O(vRH4Qq=*jvtg6)bt=_S^=5C&t z>mnma?|SA2isG=LXI5Ou|APEydpESmKsw-aDg+C*+Awdih*2S<=edy9^4VJu zoCMYfOZbIV1UjOy0NC7-fh2t;a3yR-AZZ~?u?%x?pu)uDQUh{aNG_P=sZ?PsP-;}Pg|@syY7ba_%Qp5TAyugXxo?@4}y zihf;{d6HKz$2Y7vpMQ<+FAe%wdqHqgZ@GNCQ(#l*bIA53ax>9xxw84WYhc_GY^?A`qXpss$$@b$4i1WO zi!9wXDx93OMy({#5Z5KJQOk-x7hrJ{b`_imJ01W{y>>vzQ_5;0k{}>PcNSeW3VIP9 z`jDzn9Z|9GQSr0IFFRUuqx~>IkH` zy9%fl?we<5L#Lf9374R%;E~C3JAAP*(C_oDuL}UH(f@}kGXSq&Jv7+L+Y1TAPNB{3 z_h*pI-UpugJt{g8ELvhOOusbd-gj!XJ69Lr8)k15lg}h9!x=A&s5F;3@h|Cd0BB5W z6`FgUD=@=il1s3?DBfmnu6_j}H`iB;1>bo-KxlRjE*`!bU@rH|_WhA#uVE0z*Jbj@ znV~-@CVw@Pe@A8VrN5FG$zFZ>C%pSSe=93heurE|`3k?3PyYLv@w}{XWRA?dI#)($ z2NF8-N?!&R0zaT(g5ONv zs*G-@BcTu`NFrb;Wld>fK_ev~7Pr&Vc157{j>QH|D3cD22%d+%d8=v_L$}fk{7f6p zUA6+2*JI_orW_2qbt!1XoZHl3p_@ei0>Fi(qU|C>aN?4#X)jtklVCn51sM8hlzP(K zAg*4K@L8jifz$xYS9XZ6U9<^TlRLG7e zLP2~p)U3$r{1z3aO2jN`dz~@;WcP9x89Am9U3?-V8f2H6zG`>?B z_?-1glAdLrq@0nW&=amXNX-n*shQl1ovF*6P}Bh#mVE^xVsScb{U?alu4&LY340wF z4q=w5)_m(cHW33fES4TUw}!Y`bM$=9>X}ld5!y%QoK`KQkusDfvkUrS*k|AZ#sPt( z?XfoGti{omqCy$ucEsSLAEdZ6#sbNy=$Tiht5Qz11-83j;q(By8EKqi#Ys{8M@|c+ zgZsMB!U^F0UR7qKxNh}(K#IRgvC|

w+%m~oByh5qWZWCkXMM`{Ws}7S*fJYh-hm$7Dc(FZ`V@xZ4nS8fuYOc^|{b6Cuy!C$= z7}KhkHmDXtW+9j?hq)sSm9Bm_%yFQdpbkx=Eb6Ka${8Lf(48&+*~ ztQRSaJmzpJ9`DM|3Otnx#cV9FMZ(5mfh?I(nLVn~+iF~8h^9I)M6t!3cOcj3^x5HK zXS_1b9%2Tx@*!8H_hm*x6&=d;J7^iDI*P6EYwS=j8Yk>F*qSXW%NhI_sM~6Y8&z#Y zbg~$6lt{n}Eqdk9%?&wKL5By}!U~x|K-LJ!#+6;0LE5lLDv?LK?CjWxcbFOm!H9J! zH1&Uj7gX<;tZE-vE03OOdL+BNI_vGp(66Jk-+d-D_cFJ>oM&Hc>+2VbENrPN*O1fK zX4_Tky7aQEJ)G@)dpL7F!!Gz^c|D_k{m%DRPg`nUb)>RQ@Z=1bGaC~Qwd&tX3y^8p zZbsH2jqQ4D)8l|1(ql9p)|n=Y!!yltth`a7ZQLLCJ%EY$N#w!KIgkMz9_WUDZ5BYN|&e`BT1L+@1D za_+nGJ|sJp%C^!`KGitJquicyX!$*=BV_!}yfStUh1jrZ3FEhBQb{zMQ|he#geTn3 z=Lld`$2J7}s~~;O1`6GeEAkTCvRU?)Gq5d7SZ8LGdsTL6wceX+w2PbU;vS-^Gwfco z#V;DDnb?aJKvEpU&Z8ALr^mF3(9mEuhV@WujBcmqu+!7fPtA5(y`~LQZ5kQXF|nR% zOku=K#B4X7B)=_dyo*~7*YYE^gWNx;ky0D7Az|Q+VZ5Vp5ivZ$U;lX?H}255uvtw{ zFAZg9&UN=^Bh0ams6L}3safmFR5~osR zDR)Y5FtE0`YULw(fYq&I8lmx2*|6Tq2V83qtGHW!QYG{cTd};#&{;7FGbkrn@-K9% zMzp~gaP1DJW*r36 zU@LGbrsoM>I3X$^WvtJ2A7o-`o|r?Pm?2LLW(NEZn0hV$e|$=Y84^!K<5`6~^u|}R zm}nZ^+|~loEc|437S?+f*3}9mSs;%Ol9l0oZ^(lwX>tbg{h$r?WC_}6$iAeZh6Elk zQn5A1hlsl!WbpIq>mp>Jq0^u0I>BH60Uq>|HeX)LDMO*kSofeqa3)EzR|)IjZ(?*} zv9liYwaAVk=gQ)gm}2L1ZLW{P&CbAErK~|;u_0zHF3Om2UY<`fV%NqTLaAZ}3Kg!& z{aJHS=@{42W|Zbv1`GBO;#6ba2CZ@Ug;wwj96n?JAAGAbAMuZUKBTtp*ma)+$z%C7 z*H|?QAKNE!Y-(`5EL>zKHqHt?@=X13QFoENr`}-8LwJZ!!O6`|Enu8y&H3zwIiI9l zt`J&gja?yV)(_VgsSGNngTpMUk?~m?W2e4RW)m~a=B z{IW2iaBTMAhHOJHMS7EL{5*gC9`v_UJsRA z=G;8tI~>L*2;r>`;~9kTHiz*KLU_Bwc4wl>@07a`1?<{H0i1i_5rmw(+%Wur5Z>)l zc>f@Lm%|(_Cw#ZVxX!@S2e0?I2+lnS-|Hk?aom?p)*bT!$K3DmeGWh1Fm6s5BD@Ri z$tE9k3@%HEc_?e!O9>7(RN)>+;$`F^xzWIp#pFK6Kj`@V4&$kWg7~i>Kh8-AA8>fD z!v`J4JqhvS4)1gLQHSwPLi|M5wnGwpU*L>H19Dg{FD7wzVV5M6_HPm1EC{#lkz^7_ z7kE&3!gKvZ*0w{E$)j1@4oD`CC2u2>c)B?3I`OYy?;n%+vv}MwPv;Ih@GKDyJMb)l z7Y-VLX9-+z5IAnn8wBtyVTT)&&)d@mF(MnI+T4b z>rn9dtV1dCpMZp~ojmEjzu>;V=g|$ zlueNEk?b9O;e1qHC{)A8W1Pi5`14xG!{pLF2U&h{y1`$mVuamQqq9Cy5uJMO@TLpbhuEqC03 z4~JJ>2@V`+XL#^NaZ;tTTaUsK9hw|f} zgKDSUHe5Gca3t;;E;@jt4pL{FI-B9XLq)DQ^0Fhl4$nF~m$k1r!+a)Z9^}Mn2gUK^ z!KCyYo_DzK@KuKg4)+{haJcU<{yZoYYyY&gYb2SKPxXF zYQUS0{EQ>ta`>|jf6n1I9scI5{gyL-OV<9J1K(g;XdUTG;` zT~P9yit-kbP#Qk6F6-S{ zOG$jHmd*b?5u3MGXPh-m@#`G_&qQq0*fkkS1f^2RYIM=IHrF>cWp9$US+PX!Qq-0V z3pWL}X5DYi>s#+?)@E-)&Y}sQt)(j0X7eAa#doOU5=6(}OtnW}H>h}Tu7plCw=pvG)4P?uL_y`QfYBc{>IM>0jy zANsySvsdkR(aFjOcDm|khcwY!QbQC*>ZVaV2}i4W5_antr%DyOT*ZIoDt4!0d|$ae z2&!n4r-GQf)FQ=H#=KJ3-Pz!tyuaTxqFHhm-~cWUXT6^u8i0B4P!*rA3D#ni==E-9 zx)`asf1|c27MhNptN;5hx3w&nlGP4(5$<6(^PugHqr=6_C>IH-wfXFH_tY)`>+7=X z1GSE^-~GaC7qhoU-5Q>imh}F@u%=`*8yUV_%jP~a3~NH5JCqI8NPBZ#*8lEdlF6k0 zeOWP=KA-}0v3B*#!&g5%tS;Y~n$GLF)GAmMsqlV(n00XJzHCs}oKqY~Nh9nDTdo7= z^Kqkdi&}enWJzW7`$lNm1?J$EwH6D9Zqw2osil=Uz2ETh<&nY8?9u~iLf#6!fJ#XTf2p;r)VH`6WrXXWw`ZBb%$slqY`};&RY@l+@JZ3Hl9l}K1N#P@kN0K{ zCJxoO{6wzR!QS=78czyx&MJnxs{VK%%3XX|Eld?n`+#&f65u$TGx6-vn;0 znKz%;(CHFGETzr<`DM1#ZJfw+zlcphr}2Vb1;n%QoxOS&bPG$kQ0siZ!Fz0@H_y%W zE;l;!vHSgzA~VqGCK#05qff~Q)O!G~UgpZ(wrjp5hiO_HS6cHfWRGJmZPHUHoid_)z>g#bUhBPq#Ajd zGQ&)8|1S{8c5WWoT-(a7k^Wm(Tdy6YA#GA@Aar+acWoOXy*=o-4a4imwXQZYteqz1 zT*t1z-pP~xi||%zjeJ{cn@9H5HV<#CZ6W{0+J@oPY=s;e+FIK-v}Jh9(A|ow?dA*o z4s947;d_bIK-p;aDNhRLW0$e{aWZMNZk7R;y zAf6m`63MHwZQI4GtjgA7DgraF@8cU5@!}tdJwKy%n@c|f7jnjjLi^)D2pTZ0Rw;lD zNLsTc)ep2Kx(Zq^P7#TWoSwrL$~)|dK8%;ZIEGWTefeg)FlKJsQ;;|^>`mvjRoR&t z8QRMg8)|v&(C0|Hu#J-I3L&;-oxYW}SE?+bHT3%fY#%T*4Ev%k`=ip1FRn5&$NArM z6hd`OTt75k^##|OKlpee2w^oOJ8jC!Knv8XKBmuhbB?K?>vV~pO)U9$rng-Oree$1k)PpPxuS!qHMgqi;CrYFr*_Nq=b)Uu z72QNy(Z7HHp^}o#2)&*j+r+c+2|Ywh8n5s$!fbNb`=Uc4Vbdv;AF38G8uMz0OI%0e zRTY%IRjaQ9+2SgoUToq7-J2OS0lEu=i#EM#oYS}X%f^Jg8fuyG3hT~0YooOf)V9=i)z%HI=DDSIKNxjnXiBV`u&4e`@YmPQHpqru z=H3wpP#{=BL5Crs@ByK`GaxxIncj~Gf1N=9E%8#1Dq=^_o*`LXGG4`uDNX<+98tK_ zfjg9~<>#l1i377t7Y-8yu!j}V2U?3P=0?n%m?a5*jFx0!t|H2BZlJVYF_~Op zAU))$keKnmqu~^sWNSp!7(V{i#9nsi4vPW_+5*o9E9!0sECP-tyESJaX#|Xq&y^SUThX__9i0<7l zx((^J;X=iF6$-V#9je-nY*cZ5C|C3%ceKB=EMdROn>O3>K->AiaF8H;trjRS4ZiZ(} z-@qfu^Mqz?nS6kKvW2Mwm&IhJoyv(4PF@h_pAH%n2Gq$Rm+RKDHlB*xsRX4Jhfhia{>x+cx5Fr`>{C#Q(pf+HWbQt|$;2#y}0 zj%?H{=nyO*D=(gF6k-*wu5BE`tZA5B`YYh;OS~{|EH{BkVaX8cSz9^v_Zz-IW&gb= zeOQ3jJ5_-U&|d-^z#x*X^M!pBTp2qWaHtO+jnaRjQn~~?1Cf&X5SrlvDg*3HZWyqrSIy-ezOHpS z+$?iS)kig9Wy4WRQH%0b8WyV!shE~@Q&SAs*nYVY`c4V|{oPD|IWlmdZ_LfUq3;Xc z``QCuHkHKcVmMB|SOTIVA$GB;0C1LTB9FaFY{lsYkQ2^URswn(Fy<3hPWSH%_+56r zKwfg#y4o-Rzx?m$GUP}GfPrG??{okZ3;GkRY5DgT)I<}Yx?IQP2q$>?t`5O{usjfu z;~k6Bm66tPT7i|YzYOYx($FTz-<247j?}5L(yGq7r3!U^n1;MZYST=WHk-SL>5BT3 zt+F_{mQaBO=x-W=KKgo76G(;zg|%m@p~whBgIKb`+^}zpq?q1Wxa@$!{Aii7S}ER# zzSOdQ%h^O=sAVYIw%*Akd~2dQiZl^1GT`kpm3^NpQzP<%iv5zYfMShlMDeIJ!pNtV z6~%WwQ&S!&88HMby7Jt$eW#>HibN6tlAJ+FoKqlmjXAfSHFqxF`SPQ+Ad%67GJK}H zC;u)~_iQECnKIM*id_0P8Tu1OM-nmlyC#dG?m=KAm#$ce;o=)HPnblun?@xSkjg1* zur1E^bYwaZ2*6R#Jd<#csyI~OjYKtZaTV33v!ketFc}BN+{SLW+l97C`&?cVihi)dY-$0e2X#tuLQ{JxCLSBG-6Ulu*z$oA`C3RTC7CQUiZ1 zp%U)28{bS+urJ?E==~sN>64nx&edk~b&a3Rbgc{XC@sToyzkLSW8~G2B1oel1kG2o z(~a-o8ABjWtMLUr)ak}|>fvsFZ9VM523)*l4+TR7DwT}gjQM+F{iUIJoDzepri9qVgk>hj_S>iDzh9#CjCyU_;P*WouqZ+DEd?@`h&(>S@r|ahnLOxNCxMwPH zhf>_Ll{hgM6jt33cixH`K01Sx!BLWBafJW?Op? zN?ig8X3Q}Nxf)4k8+({7N@YhG__ycGUnZR$;w#YEsitVB5_mn4AU0^wn*8j zsI6IHMa0=GgOE8TiE{WhZQ|kgVzY^v{nO7d-+IF;-}-?Qv4N?mdaD#Z1q`9yPu$&s z|Md^PI`il+jwHpGR8*lYJg$({U1IxYMQrnbTjKSr-yHvK&c?Qr6g=U#C^XH(%EC~3 z#J*%(Df}T{DOp5Ct+OuJnldYh8?Px*M#qD>P#SZEQqvm}p$C3RNdf}A>&4!lAffST zJswt?PzsK~**P_ajk9?kHL;$kqRmACAShzyS0a#NZ1Z9M@AzuyUN%bOscpWI5p;P& zYgTVyTW=IbaqF5#R;^`d^_lG#zYm zAq3eh+bt5{3GPif01^t>`LVROxznhFXbii+DTv)@XE8%mDNe>q-HHW$@!Ac50i^^j zF$&lzF_`?+vQ}1Oy+1FBw7o973`TR9J=N|>VXyvQl|7+epKuXsU+)k9vWtvnJHbUe z$f9jnj1N^0FDY^-kutQ5uWYPQ7I7NGMFQHK-JZ7-NxD0!sA@B1j(Ey)xxcz3HAHj9 zPi3)ebN|Uxk1rJO_gPG*!!clQN=$!iZPq<1T#Ct`q^d90So3e^`tG>ERC5BdU4#7| z=8G=BYsXGXGQvpxI}!VLV!^rd%-B{<=J)bQY9C<^bYg;l@;I8j!R@VG;p+}J z?Kt>kQiXV*z`S9B@^<%@HdPUNb9c$WuNP>=lh@+!m5Z}+N=rdR(uzKGD*^ zBiYOV>ya_7g+Q&Uhi$wNIu7z;j6U0$9wb`}m21xpxEo=r(|}ZGjmvs`gvUyVL>xi0 z$&@skzsYy{I`5aQ-iF#wjubF_7}`3#W7XXlO01R{#?YO^TfxGsF~qo&ExvU_8!??g zIcO37zA%jtDk>InsSXqt@@f{*&xV3K?+>xalU0GZG`fkx1fM$H3kL@ns3dE^%EX^6 za};nPx(tH{5>D>u^DX*%t9}JP{l?<}3C4kayM^zSC$>P;bzI8u?Z?78Q2vvqi;enr zGQjiLR+@1}o>1cAJej@86_{WyZ-MWyLq+6xH7@P=6C_s}@Cpq6CC1G28w$$5qSw7V z;?)Wsow{6UHie*}>WreMltH{3CLn0TTI(qVO8Ps&U;lGFga@GJV-7GqvAvMhur6VF zD;{P}SkhA`WNWXB@R zXT@)CT5Y8jg~#=FCam!#wMt{z_)#A3e`c_TY&Ji5iS}J5& zuo)!Q&Y@j>Q!4~%$aOs9O&MEmRqUGvb46(v@lv7`r%j85Ky+fSeaDzh-s7w-m|6ZC>Ucq|EAPFAM8y+;>v48s)ozK!RXi^yT2V6y@ z5;n?=gFV!8CIn*EY_b#p1o@U?1FM3rW${P-Va$LuY}*DnX)&DC#vzqWW>ZJZKUP0I zQiG!wvufI~q4$aozvw4bndeoN$lLIsPq@Tt9}D5!2n;OTAg(*8#_+Gh26P`3<5#Vg z{$H%=Obq!LDH=(Ww!#%-tr#s;^fsrvv5H*2Di-2@$g7I}-c%LQw^P-CV|)YqNS14+SFh5VHR6%U#?W&hg$$QC^uu|O9iF~l8Bz@AC5YMSaeiY+M`~Ez zD-2Dw7_<8QL;CQVY$!gcIq|0$DM>fKG(>=-C(Zohk*cpp6wj-hhMD)sBq60*e${YM z9vO*#RSW8PQ(iE-#;d;i*svmU7jO_4SVv!+VAYci-ES*ZZahB#b*^m6x#`v7vTg?Z`u1K z->+Jq^O}uG7ZlqA->J}XJEB*UGB_Fd*Lqa56;aWO23C2*QsMAzA_jY z_5_ z#*eI?;CY3ga&k>lNv;D$`6Ol{*R@)r$+DpcST*tGBH-8{G^1|n_66lI%#@Jww-xsz zJWA^3z1#On*l>&1Z2nzM#uh5eJTM~+pay$QXjAe*Izf70PUhcrfUI<9V&A2k?jQZs z$_yf|PgIu1-{G~wjtNX6AAta}WxYlP+&6pf(=Vw{S_pZcJlTpUgi868dDp&#{^u41 zTEt}}droKwpjegl;m3%AlKp~XplSudHoEThM2gJiS&9kr-2b9ULVn^F8fC&fEFX?k z7dc&H|L<0E0%?_;!ss-@XCZl7A%sNL|4p@FLvKSZ8ST?nV6ZUm=fGi5RJYG9L;a1_ z8IXMLyN9PK)N4F1k2lwA$CH%X! zA+Kd|fUb*@#&Yg(@ z96D`%RRyMxt8GU2=1$9%Y@A?04KEMtbKta5RY=}# z>?fbiHzH04<9wIrO`pvoD)K z!JuDIZJ_A%E8H^l0LmY)MC}+8(pYxE+1ZEAe06=1TmtUb?Z?2*aXP z*Q1tJr2UB5kHu?~Z$y5)qIgwS78?m0#oV#va_g$CVwL+}%?o+GX(^{l*mZ)pMt@8R zWjtign#I5(+hX-EEEXJdcZc~^V!a6^HkejAyh~MWLuHKW6oyanMR`_}Px2I8s@c!9 z_RN7&y)?o?^w+@|Ef(J2)f$DjnIlB@=iXSi#J|gVbd?)}B5aqQ?zUwZIw0?wT3F;QdsLt8Z|I z8T&-%lv_;WnAYG@zE6r_V~$|{)G=Qb;BWRX&P)$VB$ALzx`WAYm`$<`2&!2L!K|lZ z&RJr+N!yyujeMy8GI2S%7P2Uj42M5JA3`!)YP)UxwS{ALLOAP&_tv(e1&^nXsV8P(z8wUuMZuHh!|j?06<$%U1)UE7`TJ=gE! zQeS(qc;n4Yu3Zl@P}C&VRZF|<*ZrxJ$}tI#l|HQuqMr*j4C>TFBwf@l68Hgk*& zV&QAe_qC|6F3b(mZOn7w1s~i|fArA<>QfK(rB>#cxbN82H9sIgZTz?%@93dL-}nhV zEc;2w^V;?rjaB^>#d&F)ml)^OSZ>+%{qv;SScHYzo|&GmENO8sSH1JpGa6WF9h*_0 z6D<4>YYp$Ge71Uv*5lBfLpxZ9NL>7BeQvGQhwjBZa~q7oeLiw)R$!PC@EEZ=-?xCV zj~dQgYt4so?xQhNvajtW#d8JQj4vy8{7=;Ie#8!;(Ppz(;4-25s^}3oNCQ>$^4M*N z9uUe~Gdv<>EF=&~Xo4Nka?&znF@l9wf!SEQMl^4;bpM89LmL=O4$L;|8?2JoL}jW& zxCXZ91(sBjN(WN192`*MJMwectnpM^b zf|3dW#VSIOlo5tTvi}5+Vxis+<|r~-c1+6-Q2?*}r(fLHSEUjRxRKcQOeq7-KqmI} zMM5F!kHYecjQAeobo{au&X1E49KMZPwf4jEdI@u1lI&kn7E@wt<&DORnolVEESNKCFliaTFQbpFA$%BJnz;rx7R8~!7cbT z5mu>@O3<&6(lW9N`Wgv?w*h^E>*O^9T( z`GcCh2Y6o!$%5%EKrb92+C9;muOsX}#P?Q!UAJy|!2Mq+{eA#fiyo@tntxLLRz%{C zm*HxedO?ruhM*dY&kSNi2atj2VQ14(2Y?7DSpussE`inaH^U>a`rU@r&sEX_Hu*X% ztzZ>w4_phkn+yr;f5HrGFtesrVqgueXO`V$Vmb7G&n~fODMB(N%`_xdRasc%ZF9yK z^eG3-i<6z!;BgcaB5}z3YN>U0J|;dJk?}H2_BqSf?3ywfl-O31vGN<`o(|nB_H>Y} zp-|q|;i-@OP>q-oWMoOfl{B;2I|?>D(qXkJ>s%=v|5|!y6Na=x&^8;6;0#y2UEKKU z?6{1g$RIPaO+&=T>#@YHuSOKc@QM*3Hx2PPY*YKjhZYZlM^?NzTQmp~%+k3b>W44i z6|w87l8VIB;}^|4FcPVkod^q){ZoKwfmj;F?Yy}k40!j6gSfzFBe%G&^`H`E7#n=~ zqot4O#-FCP{@px^%$QTOdSkileV~pJ?e?3~ubXHulVEBdOuG17^Xws=vwFfP>vZhX z9OpfVxl!I;y_&2qhv-NQIvy;$s7SEv!W_ZDn`Ix@Ysto2qxTWTy`;xi^biNXEZ;6} zz~_Yu2^*{N?x67tDpjcU8h>A}zo>@<`IY#DP2^cTwm&UQGfA{DEc@Etkr~#(%{X+$ zFMBMb#IQRvtZjlj`Q3puE;ly{S2+CwB#B&{FrNyF`!5Lm=cBk^ zsGyYdu43oQvK3Diz(dR^pH`2{T zvaL4|#dN}1@>69q#c`rgg5$I}d3sERmsKY(2bBku*}x~F5lSLa|=q-qTBE}nPcR-H6j-*(tU$~_@rtBazDO&ToYaLNc_ z3bG0LwqOSej;pl#ck+!Fb<_|Uw`v7DZpFii#jeqcbL~=kNQ**GT7$k8;z2n)7$%@& z;DWry4L!a^kJt4uC|SAC=C!mYw4Pwai*(je#=z6kfqjjdz$qYSb8Q!_+f+VsYK=$k z2MEN-^`5T`+mZt#k;Kwtbf4EyNm8x(EXnhtT#TYB!BLg$ZwT3{M6~cTLJDEEhOVD7 z+r?ry$F}Wa$&0jztj~XsXsU;O&?No$0uzO-wG)2!nvGB<~mGVJp_Oc-ZJ(0IVd#aJh~jhZcnYG)=U2N4GX`z4oO zFEayRRvy7MUr3m&C+`)?$70!(uu?#hB(pMd6h}aE2S7p_+zf%oZkac-cQU{+ctF4= z?eb{*HR2I0`C59x;7>1*5!HY>9KC}Lm9|%MDm5pD0ND&JFxc)VZTQFc7d2!xt*~SW zol~xFuXG2t0b+-54K>4*FoZdE0>P73?O@!z3qzFlZ1`}Pd$L=+F00S~EuZ0ml{I%8 z(k3#h&0t#r(RJtgggmDe9tFs^IS(H5>Yp1JOQF}x6`Q!W^5zc5Ff zt+#dctS(V*Ew#sgE?Iu}%NwH1?;OmJ^}&?HQNKd`Pq+(1uRMfRWxChaXD?3DL5o1G z^IT}{tDPcFgM?LTv5NF$B*mr*Y!A| z$0zj=wya>sB^%{JV-3;ZhWUn_gqrg+Qg0b6;Dqst_@Ssb6`DomN$ba|Hozx)}Z2WEXM*N7j=!ZW*9lL7VhD{qp zABOqU%=Ar)SZOR0RtS^;!!y)lFl=B^yDYNAY6;`H**-Ae^G-bTnHvz41xgw=2j2Q|_YVa4Ex~Tep*6<0QGPEPOqg0pj zKX+>r5$coC3@CDaIw`!3_=Zm$)mzuN_|uFJq$az11i>ZE#cqnHh9A)}x3Nm|_rd#Q*^wuX z9*g^&y@b7RWBh|-`EByN$KGiaQ}1+Rdvjs_SJg#LXNF2CeEt-JUvyQfI{4#dU`kO1 z!=bKQ4PX|=ovR<=6w9@4YP%|onfIY=j__lx`Y@4=|G?ut_C@S+wJ-Y4Z>Tr?Ed`^Z zCm$hcX;1JXX-z&Rn*AeXC+W?u-Qoh6RxWT#W~OCliijChg;)XAbnX3rC?^-^;N^ zTNnN5-)4UV*r`7PpXgD-fZEW&f109zQ6LiD zc1<1~82;u71KR|a-D6=)=ioYvfZ6zt*yvIWlhkz|J8ij#LrN`Jlo63btipLax7b{5XH@4m+=h(}bu@K5r z;z38fM{4kYY}9Dm?rE_zZ(G*s2Dr0P6~|@1No=C_*I+zDK#}^HDvBK6vN#9dQx3jH zj@rejIw+JD8ECUORct* z+pWrWQQskq@by9y5Au~|8d2ELqL3p@cOACddABr1V5fuwWI)Eu=O&?P8f?peGD9Z- zk1dQZlG%TXiFr}XXnw5w#z79HR2k-EG9+efzb%O#iR&wTpqLw7d!pjf?9EMEPM1cm zcLh^Mv^NC|`a+HkE#lk% zv_Sr2dVE%oJ$jtxVYg)3&X93E^2qd+mZM}Lujq(6J?3Tf1(h;NdqJV&dWh|=uR@ZmNXM9@p-~$H2MyT*uE%RzjY)W4~pH5 zKY29JpUxt!sqHL6cVSC&AB^+Xnh}9;iW+i)zy4>y`ZptjWuO&A5c~Ha0syv(2m&u4 z)w2d7j8=oa-3TL5b7a&Or+UH#4C%hLgge-=_eBx7->Be@0&%eXtH}v*kT)>TKU|!Q zR!n#W8UHuDI8kxXRH1d$>i^O0E2C&&`ND!l)s8oxJw`u8m`o1$pD?z-J&D!yTCen0 zVm7i*qmmX_h~D=vR$>FcXiV(#Nqq|Q*e_Hv@u8@8L+`H$L;0uZy|p05s&*6A`)OU% zh7yNEjKV`36h?AqAC}M1Xa1M+5A_GBsAgiL22B((%u^9VaZKr5Y6nstyX|_%>cE4! zou3^jfUfV$2AqGy%-(kVFTA$Pw~}Gn&rUu?oSA%AAH&SuvC1250sn<5KMh2^LpMEg znyT2D7vp!<*AEqkxOLi57d3;!@GFSh%BFYR?N-W5yMLTQB;dE|vFhn>vr=+&30g_V z_>r%Q)8S|uz-DQaqHlSi|6EbiVIiFS9QjmigPh0DekXXbx_w_EI z7Q-k}Xsq#P^ms=PD}$AQ+Ca>7V9QsP^pYO0>G5av_;Y$#st}KI-Iq0mPDE&RiP-^* z5VbHAY<4ab8fX!-#^-pj0`ipP96ihw#Q>e>k|fvzU&Cbs1#c0~tb}=0qd<_0C*qUO z(4l^tSh;?cub2&1QOJf^_64~I^$6of9ej+c!nOytRiK0{6^x}vbd}GV)tmI>2-CWu zbzpV=8-5T41}co$px(u|3XFY{&I>=sf`;D$MZmxEQgJo0xNjiFPkF?)q1z(~9-mGx${cE{pvLzJF!McCDRLL}}_`-%7=p~r| z1)Bwa>zy_3E{FrKpgxdJ&fRZEr!4-E%CI8>XVG3C$LAb^OQB>&QBNaaO2MvZm+?7 zyX!5GBtKop<$JD$17z70s|{()P*!G|i350{O^*`S+da+30^{c-vN5QBzn&U)YB`Vz3o z30M&2pU@ak%D_g$hO=X|`s#NLom029oxSN@y8Y{}R66MQ((U_(%Wm%(Ufk`+{4VRU z)NNWP@Ztx^z>~N}`_p-$^;G0@Xa)pv_MSLm&07SFQsB?aM}R62eA36Ex3*+&-NF5v z0)CAIlmE-ZF|VSzESFV2D;hIQvGtb`OMltlEr$LroBL6nif!{9CWbrSgr={~c5qARP&RjBB<3h?32lx&rw_DEyKo$%Q zOa^z}#_;`?GjVxpF+A(Zd)NAB-`bvC|Cr9<_CB#nb+F{Hee_3nZA*3CnZ1Sbf@lmN z`QWitFJE1?s?4^X_?@bax=1*eaxz92R=tUy*Pz_*uJZ71mjoxNH~K=qerOd#Cve_^ zUrzWP!^mCg@ef52nzY4>OdZ@}RH)Jk;K=t2&R4+KTUc0HViqFXvs&Q-k@31bBBSa+ zWWdRrT(`@e!@>tQp)=A7bViwk&c>wk?O#Lycy2K0T$#6?O(kfM zW!Sjp;1WidHF(TfY(UyKxGAR7Ek0L>t53zwSSer!ABM24D=cBgQiUIkd`c}UAwzM8 zrYaD7h!ZN@$xXrL-l*fJ2q_tP`cS%K0?8d7@O&xxCuR?+{6&;ioy3by-QZ$NhP^kg z?H{@ST$qj8`Ql(MoenESbM`xY=&%D+J8kt`c$-~ZJPx^= z!8EHW-ZDh_g9@2Pwd{UEuRpHGgFMVyHoNCJd>^I@Vm}dE-~p4PyymQrnles6ZR0B{ z_^KXzl~Fnz3_LCznrP0R9~0kJo-HuDIq&CnYX`4S#ZP!syy2G{5qG20kl(<@KUSq; z{k%a09;Ewl`JA7*Ff(ZUuu|1+teLMjevUvxB2D;ogiFn?Pc_vO1a`1W=Ze4GYW#iW z`9&V?tUM!LpIV6vw%#?kV0Zkx#RUH&>d2njfC6HhkF*vc7~)a(K{)0LLp;KBGw(WF zcNc8$J=}kZ1C^mWP^NFWdlUO_Bg3kJUs&T2^qL!nx3iZg-|?_Uo);{5gZrJ1-J7BWeIpqB=eXF)^&BHt~{AFKo1m;`qtJ6L! zNi=mDK|x3VSD67JdlVpC7k{5cYB0Hxxikz&vP>TDVBq9U3zCP@^n;4DN7m4toLNSR zs%oeMylu|0Hz#T$LBIc}^r8N@o3~$L7kmb41dS5w2Wfy+;d>}-|GkNbFUIWsqQh1e z^nYC$$b9wJIi0T}y|ktZ`J!JpLv2P#wclwQ4!9dLIPSFxc-SS= z4j*#peQI$jymh2pV(O};<129Fs{Ei$8KUXGo!1b(`s2DHMV2Rf)g?(f+}SQtYvl=S z7fD!pK!#%m;Phw=yvFKmyTp`GOS{-E>1(zRF&a_LE~S&g@P_@x)$K$2OhhFUjB5I# zlBq)wYUW{$z1gDaNvdrwR%a{`Hz4IPFrRf7^WlVr6PFR5!RLpT4o*I3nrNKnqCwu_ zQ_u7aO3(aItv|6-mNGe8s@VJk8r9z&isKQ3-R_gkL;zB8yc5Gk^VQwE1R_aUeRX2E z`>YGx?M}d5_>hHaStNsq1drp47xv*!+Tm(WCAo|zQ0W^ zBg{Iu#QAWZD4ncDXD|jI&@f#6;;^6xjw-(K&PY@(iyyB~twhTZ^3$?0yHtlk-z33B z$pI!Xa9ixgg{PA5$i#i~a(~{CYy=K*y|{WN0eN^^cKvlVpm%X(@PMQ$q#$yLtwm12 zuf^M|?12J)5wO~>trL#NV3nkSGceICvf2;aw(UE5uZ+B`Zou)%OT@P9>bjA0F)Kw0 z;Hv05vS{z;R%wpCPB!o&lP3?8YGxW)8F0J5mxeQ(U|H1FQJ|T$kC3<_+h~1Ji~M^25W>#9$r0{jone=&8R_ ze+b{6QZ>C+;RnxQ*5rGba_t(9T62!J!aCnnVv&}!QpP5xiBH{Ed@(U;@MQ%97}vDt zUlq4}<$yO&rst&f)V`0l%;5)R5v02zlv)(e3&N+)&9yX z^sD(}cc`L7%=M(zOv_$xC$DzrDZa0$KXIkik}>E@b6B|WH?0*#?RjMm1~+HfOAZw? zF4VOsd*`Lmlthu6dKLQ9%Iuudm035$&65*5vqfV_`8Q_f;9<2@MMX=!?-i|{o^4@J zj|Gry)vB9zXDOBBo1~i+kR+D-K!PuG&K#lY4#do-O|hcxRNP$mHFM{1=5yx3qw|=Sazoht{fu(&P}3e(NOD5OLxx&!bGc^Q>~-TQrGHSd zl7iA*lW}YPpob3$pUSsPAaLt9)+_%;J;bBim~e^U(fFzoWY8A2d@2#(sw}t95#e>akvr4SHUt6*PCTDZ7n)qtt)L@aADzFm741kvi@nv=dL+ zQ-XEdBB1$Ii;N^AL0QevYCUW}7|N{3)d2#i!6D=4%3r z-f6|c&%lI8Tq=%+=Z@E9gmT>6JloGOI52L7<96cNE*1L(OAMzGOkFVcw#x4{#SuyR z>R*?rE2aWb067lwuLSt0V9&iNtLq-jS=nSCmY3`{l$MZ1c%$Tu>qvBt7q>bh!!|1l zd;eC#2F%4}R+hsg%BnoF9h2zwqinY1jVS7tdQ2H{!6}wqL3Yv~&(o`5Q!8S7Qh1~*R5Qa_9 zdq&yRC_G%_F!QWo0V(OH3|`Ee*=tGZKm+mfdK!e_&uRC!IiJHS10Y5CFIVFKvUi{2 zD2X5d(ZEM{snu|dnZ#Y*vjX_20Fi=i_56!^1<={7LGs;U$(QmrIr4TJawJ;@MS^#d zYFBrdwN^{{Ug3;jLxw)Tmd$bJDbW@gyd%&LONM9{gC%nW`u3Ln`B|g}tfOfFZH$Cm zPm?v-&cWz2!VFhHddTU2DQ_*kWo4>X4=A14#ookDH3BU?{rX3hoQz+5U*5lN9u9vg zHJ_3jh7^vL$2X9dnIZ|xAsNLN9KIJjFq#>NNa$6=Q@n z@?Xev$H)sWMd_F#y;C|LtQfmw^YteH7(wgPld$&w0AkKIM#Wla|jE1^V%X8DM!-pg)>2qzR* zGJj@#9#>q6GL1&xQJi_k0%e-rJSp$k;<+lgQ^+xnYxtajsOGhnZUDg%>VBmOCRW0p zDwU7s8$zDviO5#jBmtzU+pXi=`!4jIqoB@FI3F$qfY%U@GBP|yoD2~-O9A&JdO~lz^n~Bh89JSz*n;kM3PkHe1ta`waQxk6P%jt*JE#Y}dLiTuBQWD&tVy+` z9iIP$<55Clenpsghm(D%-fgy-OsAg_XBmR}+3M}u<#vh%L&<4gE{v$xQ030;LZs*!KbyLzb4~i^B_2oV&F<}G24fj~A0c)UVIBIqURf>b z*ygcvq5y2SB3w!i(bzW)oC{ZeO0cN~l&up)?!vIee6Gm1L`B2UW^sZ*3=9-{9Z+_n zlN3E5hXhJ1m_TuFyqg$F5BYkTL-Futt{^gSstq6#mnHto$s!3ZuN0lB1y_eMw)dCH zs@lZEo5JRa+J(Y>I6wc0f^R5yZ$({H0J#!c_Xl{b&;JuOqhJE1j{U#I0q86!T%T+9 zDMg>DEV>x9QO&jWXuofO@1qhZiGvA%Ks<+TQ3%2Za==9&p!=-FA{u{t`>23>sb6m7 z$C8vM@Fy4F$k^68jtk!5EzE6E9dO%UQNfvc99wd^iUB^r3{8T*Bw`RuDoTR07ipGF zekIw_#-akwS$76c>FA(!B{Dg~=>y^{d&MXNSVN8i3dIh)v`-|_=c0}zK31B=2-Kg^ zIG6@{#2|)arBb21il^w=Go?+jI$6{n`;r3M^2}cxb2iCvLP-EjBP`w<_x~Fe)6SvQ z2g~C9SyEx&crZxi5x(D2p`Yck0`j-7o?p_!dVtK?dXPIp?>4UV;ZA{({4kt+97rJL z@bfUags}DN1@}b)0&jK$&={lCHGl(_Tz8tJD)yir5kPO~9Z9Q#WUo9{hS$&A6hg^ne065>A&iYNFX}=Hw{5 z)p4`s+;lOA@++e2^Iv zdTs~cimKD`VG_#O6mDb-h-X-nRr>3M0`C(@zMtM9 zR664E_OP#o>j$qQ&SV9+beZ_p?+7||8YLSQbD>)^>Z^8fhN^%?!J}dEmk9`3K>m+9 zV7L@S<+nuj9uoX`o3$Veq6diI;QtRV2G4#=`>d+adrD*yI;A>rx%3P-q;UgulgMXG ztoZL1PDdvo_cqZW@1+6V!tI7#Dit*UJ?CUojQ!QLe?dv!)6wbzdw(j2V{xm3WzMnL zMYnINtxP3MNA>WAaFLL@;eDEO7cd;H%h+Oo^b6eOOu~x=+$cH6iwXb6iQF8|DudS* z3q}Bas%ynwAm5^zxYTc+vkCJ(og1mN^GpZG;=Joq^k>QCx>)F3oSC}F5h<{@tHmNk zA53yfQN2)JJ+&(oe`Et(AqOhk-J8fl(K-lLYIH?Z5$Eg$U{sylP`yB8wt81MBM*Xqbz|3NzrL$^WrQ5SwBdfA-$pg z3(k6Dxh#gsuZH)(gNL9tj0pRBzKo#72vwKSCu13zPsx#a z7@Dz+P?If6u(m9qzjEUFIIZ$*7^F47>2PLlS09#I;siw8#Zjx8#TxrXvl2%kH<2#ol4szLA?t`pa$4h7`pJ$* zx?oKU{p2$m_{65ZErolIkV0eFu}U&j8LaoYhrx~$vfpQhJA2SyD43>^sR`2%Rwm&c8IDVs(y$8Gw!CLp z6VANVvL+k+z>!Zt^zQ>M8zI#huOeWv!`Yj|3J}eTwLVtMmS{0d<3#oQI@{L2+8c}= zypFH>>-A^Zo?}IXAzk$jh~q>qRTNu0V)ZbI38iXC?7wVAM`}&HC zi8(g=+w60Cot^8Z?omuJok8MOxDr?lgi-NQCl>paV0Ft6D)hsuQ2m_pbGGq6Dz+~2 z`*RBI(c|yyA=JMTHWz22u{t7@@j5R?8A&HSf+^d^q18id+Hjf7mK__pyIos38!>NN z$2N{`2jfHsW@c+pxmfW+jIOT2k2M=icTj30_dskM+J&Z@8;Hqko=5_*zN~@mZ>8zW zC{-W_v01V|*Jl@c>yfM{^_gj(m4XxTnXx23Xpn}7VML@4>{NVKTO&xSMXWSV*RC8 zV{%fU1-Gm=(iHE8Qmst%?##FI>LsBac~*LJz%}8s6>*XQihUT{j`q9$!4b?6fxQ;U z3UF>uG~X{6m+Z=UCJ{#N!w$woE>`r1R9V}wPHF3a-~S&{E0Agc6{Lou=VnO#AnU|#f5ZHl zgox77{SC>D2f7+M4&uM7Iu@Z?&9a@zNlQ||*bF5B?jl7yoz+oJp}lmKjrb19s^u6| zJRLRuPZ|-H1Zq>T0P6p3JAZ7*Kcji>!(MU?#o>GHIdb7GATauX$W5G?t>Jsa8_8oaBcz_xlphs{;EXiar7W2wd8Q7 zsps~4_71s!Pd!^pAR8LSAt`cTzQ3Zm^gNCbpkv8Z(_i5&2Sam#+7-<8VRPp%b*2Ut z8u(nleyxL8Z7S!j5#6eTz6zaKr#m$#9dW-nbz@0A6lvb!C`5Kn*mO_{1<0mJ>Xe=ilYz`+gE^bTLcyL{ecEZ<+IhMJsJ)Dd1#&^und>v z)m(5Rp}OgfTlN)%m?HuL%;9j`=`gkQC10KhLYs~>p|Q~bhoNKcx}tL2rZUW@27B>H z(d!HbH!xX52{J3*Bhl?K`0ewE!?LinDlr@$rxQ(u_v2!)odvl z{wljhm-E1aYX651N4x`yClX{I&MbdUAfcdoT(B)oBz^@|J+Sh1`^rMkzTPk zq3w9bNbHPc^JN>G=kg7NyMT#n3jv_@BuNUdTvG<*>#_~Tn z9(wn76p42l|2a@JS)hrbJRcHA}uCCH+162P%0v$K4nOHC7 zUJ?hyFkdLc$Hm6>)wF2-%$OWKo3w@`7O4KC(HfyQ_uImU2%ARgZ{+Z87BweH||z z;HKV+q|2Qfl_cI)Sl8y&Hftq|Vr6T#as*4qtvD8yxPKj;+J)STDJ3^B<-fATLYA%k ztwAnW_8oaQ%I3eu5{t0+Q9gYuEb+GW^MNQ7W__ap<2h`pG#sf3wY@9+oQm~L)e-yl6!5`g2B10{GFbh1M zfms<(9fJ@Udn+mDEn2L*`DCo^<*2^nLPLF>7_XbpjSfCY(b7cFn@YFO18GdA)P9rr z(jj}%@{?pxn?Y9(X^>JE^2RHP?M5MN(jxZew35>k@AoasVm;r%MU22Y10C#~w( zO>iYzug;L)V&3sUuYT*V=b~gF?%qv#vSA47y{Xp(CNbN%tMl^|3YN|0mY@^0DLt;i|vtni}xukq`D zFO}1;bdIao<0$qrEUl5DH2i&Bh``JNkn2rrQT>nPECaTiAk|8GkjVLpzFp(UajqCj z`*)IFjG<(^FL;Q5EM@}hO!oJb8UG&aa-(>YcQ^hQH}H?8njyO!OB7i`$J_l5n{iTG ze0xmV^|CfB1lh5_xyCV_uPkeHHgehe1SQ|mywYgmB~=PCTz{E`aj7gCnsSxfzB5@@ zu20Rv1y*!2n)O%n8kAYJ{MEb`)OO}Ic5c@PDsA|&C_u9 zI2w-+{443`*GrejG~wIwfd;rb@1?2>*S^UXW;ms(T@qhJlmsA zTZ)r&PY(Iy9IAV1-0?v3+clk>WArp-F2No`^jp)jtje97kQ5Z`u3n6$r@P5%Jqi7S z)BaW-IlAcR_)0~~&b6vvEd@d!PA|{2H?)l7=sE%nC)I6;cwE(apUWCPtJOaww!pjr ziAksZjzV6GW)-9^55sIP(x1`mYkIt-$4B%ysE4!*!BVu5TpN$6=EwEeqEu@Zt^QWm zN^#7p!iElWzyo4S(7x2LPTgw6A68bIWBjZ_{?=`%(4A4%WPO#eNq0Jzfn#Fq5Jz|$ zUCoJ!HHT58KQVM4sPN%hedqz$51*e{rPCVsr1KNIIB$^@<+RdT4*eQ~j1T}_Ch7Pq zyv2MK_I9~`qL3&nwt!2FmDAHE9dt2DpcO&wV9VTJ)TY1?-^Po=Cm~uYk+BuD&56p~1p7Vq}!Y zk*GrX(3$M#mfrz6^ji{lh$TSJ$j)u@snVt%RoQ+~f(p}qV0`Zsd%r9j=Lmis@>@yzYg6nevg*X_f zv#eKcTGR40K zTS7b6C#JS{>c#^3-1~o39kCIZk!7yX6icAWc1Wn@fGt1ILd!%cEkDgBKUac>@8`Y$ zDKmf?dHve8cNwBd774d(tO-=tSjoSRiN?%ddRr!1wenw9(CTH8$oanHKv=e?jdIjQ zU6RWCsPem+HYa2fdb(>;fw#LTOlXD~V+lwBv-KD)a4Br;&~k8=A(9X3qeUrQ5{Xn1 z4cp?Bqm%!xUT8-rB1<9(bDRr*YWZZt}8!|l9(au3=4q98`nW6C{r2JLOd4OZ3cfW=cyhi!3#De|DY$g;WGB%F09fUZ?|lL zyKEsNxDM_!2>{-^Fg0RNEGkVIMX*cp2pFU)<@TWj1|4) zQ=uU=o5iHox+WOB$6McOAZbzXWLj^rFp{L)MN4Z|UDRyNHW{!R^o}tVKcR;^Fkmf~W@dIP@~NT8@T>{z%-1!T zs%!de*_;`z{cCn8ptSb@{_xv+_Tv{flhvttBBwR{jHG&Kh>(;|1{qp&{}Y~(I@ADJ z0@o)X3$FjJ45NhyJG8ZDI^g!sjr0o%w}&S3++L2YKJ$3B zo(T%B@8Zaj$)GjSZFul+)h8>J0!p;EoFIUOR|=$ntCk9a!2gqohLpvxSPta5zoV|- z%r@0X+rBwZYf1olJDM8W>%WK7^KNYCrt)$U=j>WLjVA6I%$%Jk(VaK4F_q$ zkk~SHFHMjgP15A9j8D_t``!&D@0JOX@v-HF$ZjykGFv(ySd$zPKBd0TBC&E|_-;M( zxQZZA;#jC_UeJp=YLXV#P;-D%%Lh;uNf6<+lOSTVlND>HTYz^-6+aQ;LqgTs@$Tg$ zh?5>idmmU{g2-~~;};|d$ZM$YX7m{ApnMSnrRfm}0wh9VJEXNy4pDH!Q;#VmPU~mG zgvl#LcQ9+C#0t03+5A!jn;mgfBQ3==6Hfiw)aU5;QdTd?hD!;vn484kx5!#1A3wz$ z>T?&*W+q-=1Hn8;sj2{`a>USMxjIxrdQ$-+Nd+nT(dNM5~UZt==h zIUq4Ps>wRoY9)ZOm0Et^8CRW!O)S5?MzSp>+>#eS?=lripiN%5CovZSoMb_)@&(&w z+p6R~Rv?mZ%2+ZM#M2NGgE~{gV|&f0xZuJIq=IGWC#4z-zu%y{{QTAn^7UsD_{d#l zZvHkR0=>b#`wNA&QXI8tTl4rhtW4iw>C#$ul40b{4J52Q!_VCO!Y;!|*2u9VhE7dq z(UQ46!o!O-k(HqE)#M|>qX58?H7#N6lvK_?K75RX%0C88j~^7D6^HLj6uzdhh%7A z=^PrkTR`nzp@@=9!eyUI!1e~qT8n&|dW1}AQW- zZnnShAO9U1Nq(4g_oA6@Mc8lXu_U)*QR-*CwDENma1F1Mnmb}pegS4U-Gt|uL@cM; z6K0pBC@WyxO}NQ(;ySMSru%d=3k;5ecA5kBMgYddDl#|+?8_yL12DJb9_W1v<8qjB z!HkrQt0v^#$ZWYJoVPBUn=kwSr+gP)Zr6pH4Pe%QtvP)!{&1iNsY*TD?3W%*s~<&z zqFw9Hk8wbsNO8%U&DJ%HyBM@NNqn9nNX6WB1C6ux>F%UXLJZih@n*4IQ518gROi4J zS5U&PFEMv&ZXAXPCVhnuM>V1o0nRlbfM9^b!z&-6nAY{KczOGF1mLz|7GqC zYgp3o1!J-CE2{o36+0*}Q`jFSzM-f2xuQ5_75)?PW^tZLKI&(M7Mfgj3xsZG(a+|- z`}>|wqj*JRh7js5jXD!HS%k<$I`9?Xgs2QUgwQx)Y&ntt!_DxBBa?rU02PZSRp71f zPS=S)#C;#F@;HaqiJFBCZN4#A_v#QAQ`Ta=((c=D%fN9_G9TCHtAE{+%DdenR$chJ zNe54^gbq&dxmh}xtAC=%ATA4|&8zq{jp~X9;wjbbgajmB5)zoJ|5i&1_`A&#pI8Yh zG_ypg?e8@%#IUI7PnN|1F@j*W+{@!jL)%g@xlf$@0~Yz|jg`NZiyCR6Gle95of`qy zS6JZqrzV~ez|ID5THv@z+3gX;%Pnv`MyJUuR>oRLO%1{&GJAa_p?${oh6wo8Cy;fQo zEKY5LO^k739K_EFncon( zBMw2@OP;crPqcK$Nz7M?>Mwix2c+MdLBP^R_YxfT)XT<=s-AR5X=II46j^7Dt(wML zk}h)4hCSXYP8O=-+OYLq$|z|{qMOo$k9)OUVUFhcTcW$0zrwr}=H+`(51O6!+d7ig zY`I#rxZysh&Hs(#4b~$DI79ko;ti;i#Tz-v zQ=6j@Zyaj0LL9#qe<|J=%19Ww$XNAzJG?QUa7(<=QixcB&PlEx&}l0)iE%`=we9+W zVCXSFv)K6LF0e!5Np_wv#JI}iyscY3hk-^Bf?VB{ME$8i;OG{P{+&CAdq~FT6gN%Mu!zkW~V0!#9gj zcHf`6(*5!s{FZ8`O9RQ*1}LU8`sF+$l1C0_# ze%3#6ZI>)lqtTHYgA2nucq+3h^>Ll1b3mqOKBaNi)^72uDokvcw+G|G&kKn>T_WBO z>PWF>F+|F~11coZGtNISJ}V`}`4tvKkVK>XCIbSP`G9$`fD$HPld zH@ta8G>eAtp>dZ+z|*EJ{;%K` zGvWhr9A&XSE}462qQPl4vV&^0MUBl4>G^aM8|A)dVR|-^uHu#h_LdZenK>ItLQk^S zE?6%8?3Ig2lwtOwR$pe$_cxyxRocG<_WmU;u#L*&ucfEV8fyrD!&8oYbSX5wArUg7 zx7(4m!xSA0ha3sbu+#nNsSKkL*B+ZX@@?~()!xV5`28x3rY>mA9@6RKDvSy>jn_0+ zWDeEZY+H>=)ah9Aqz&jl6R8~FVzeb)7MdQBt-=<#1Lx)>g7u9#!u@z^xDWJ zypbXlr2AR=OGN1=SVJ_#vabCW(jDav1q_LfMvq`cp5mdm1?nPmjDt6p0% zyz%}b37F00;lHSzZQ|?m@jn}A$O)SuZZ`MqHG#9y#7#2!bQ>$F`kmuloFG`X>phls zGXd2-mTEu^k5u+YyLNzK(j@cO3_mm_Wd!Xo`5S~b0gbp8Curw#zMHjV$ zh3j$4Fe!kw-3twewJOo+x_0VS$sf@r1_B`H11mr3AT^7*n&5vsCesp9AN(E$Bs z3>l28S$vlm#D(Fm&`xTEvx1v&FU7cr^@z>iYdo80t_7nlo!%5C)s|xI`7(hxT(GB5iX^Y?~i#0R93+?k)3JJ>u2~L6nf$GA+)b6 z>Q!Ne$tt;FEb2m6oWIsw?6?~p-7B&}{#PUW-TqZyAW}#AX)iGohr8YVle09)Kj|#D zA5UUac^hxAwGC)xm~$q@P^#?{wCflggR1M``p2`~E-dk>R?5 zu%eC8^$We6a4`G!P|>|}TQ7?#bmLUG;lA%euReticX@-)={byBwcCz!Q29QVq3|T! zeX$q&mlVI0T->xnU^by44@9$^@D#M+1`0gLNX`q>L>lN=5fN}~n^7uQs$QO+W|5RdFuLq! zZl{kV&wR6|EL_iSEWplmguW;#-+w|y*7o!!cF$VxfeEM5c;D4jwf0GL2HJ(8g&rr0{8n6f?G5m*2o}_V&w{uB838lAH z*7w_cwvvMRPJVkhSIXwCY?HE;y@?*`8SHzw=Z?OeoUs!qTEtfDtF7$u+25<=SnQ$2 z-+MXJKA{`exWFt4AuY3O*a30E=EJeo$PKv@iN|!KQJ%Rl{6Q|nB^CFp*hAq}4uUop z8mJtP>-q~Ss=6r%=3jA1B;0(x*{x>Ue!3p~fQk>P_~> zO2t>J_=t*6R`Ja$zD32itN0ETLn^*gg{D_*vJKq^Q;9bIpf3MQ6+fD}$4;```)OVN zSrtF0dopAY;kDN$CleTU692p&`2`ifsN&zL_+=HpqT=7H_%#*(FNN=-h5F*`G_Uw| zU6LN7Z7K+eyBU96PyR<0|5?Rvs1T~S`Jq41(I2Y#pDO-H#hBJ z#J{6Uf2m?k4~1>vt9?=9hgIxVaX`hWito{LMidh|{c=IlsAcwqh>z;dck99LQt@Rf z{*Ma7hm*Q{N`-Z8);9o>(?sd{qTjx_8dc>S$iYbrr9vxT!*l zdMwcsf0~N-srY<~lvM4gFsRbB*uUW6#%&brvfI0E-Ig!xe~?W;xAbq`QtH3Ie|`Vs z0~`3;@BeP^Kg6}QTMi9u9N0N<$CjM~Zzr|-Z9H+5{~ztYe_*}f3_Line&8;CZymUM zV156_{>|%p`$@rWzrOxHU<~wMrd-qCPq~2~f2o=K3)LSOc(MQYw|oppyKjG*R_*EE zwdI~I+jztDz`lV!)Lz%G_6_u(@81Np_5JGx-U_@89IqL$(*M7EV50xtfrA70_TSdO zd0-n5xAFI0{_f)M=)gXnyMJK!z!0rl+rK^pYD+eV{WgwLU^FnHiEO|ya4IY+z$DfJ zHVp^nf6)QjrP-d7_(2p^PxnR*k?fgz6;D&Cj0Bvnk&_y^?DMs_88junNtQ1tK@D=R zRx#hc6UxlfQ>*qV&fPy;9lbJ&U-sG@&&l6EQ^kpj^wc`|#$JilWP>7;#uAIwdV@{D z{G@>8f4mG`+w1|(TzGeBpH_m@*&@^m6?xiQ39qP6+Gm9j})nYV#5J;aZVIqqp+Mu;N_O~~Fg7axz)E{;7ll*MA zOxX9!%)d}#kn}`Q`pcLIy>@_(+h+%Bqu9syir~-8@!dCAuuz^YE3LhoDbYlvQ*&6= zfNtRx5G{Z78qUQkicC7~XO1jt5T7k~s)LF8H91KJ&T4&flC|&(%Vx?D4`$eUP}R^# z*ztZ*nKB)Ab_+wR-wrVOHrfFz946u!BdU%7`7X5@^&8#-qw3b}$iD#_Zr=R2jE}Ls4bI4h~0^gLZHvsvNR| zqfzCs9UO})N9^EuR5@w~C!)$RJ9spz9Jd3eyieG{si^X(9h{CTC+*;|sB+2<9*-)g z?cfO;`p0a@o{TDw+r=|cW$ zvwF}6op^>ULATUQ_dGqR;ikc5CzeLUoTu4V3&V6+l_eYD>bCs|BKH6xFt6EdGS8*^ z12slR9luVV15h|L!+7}W-0P*AbBpe>dziG%^9`PqO|8Rsy1i3)_bY6)Ii86-2{$mX zy*RRXkxnb^p>ya&`u zw-L3P7gSr+z zL9L$XGZE^yMQ2e^_~$G1>uGoV*#t(och^1~H}^bIP0 zlfpUDTpV=82SHny)d@ZENh-cnweF-a9azD3qcuT)1ft9&XZ=RvSp1eU>)(f z%&Ya9Fud}GtDsz9mh7Z{g z%0gL4*m|uIm$(^EsW6(=5IRf~F~^H4J_2;BF$=~w;;-h^;S@JpVA4mp^LxUit$K#d z1^St}9S4i_Gh7jF23&cFlN&CvfJSb+um*eqSr~B8=j3%{3Nrd{a%?i` zJtlhy`qEwEvzfXwqVRs3`vI23uaudO;hVrO3zV{uTg9}Dx>ON-P?piOX91bdSBKAf zX24;Kfjh`6{*OL>gPtL2(CrZT(hiXFTi5}7J;bLEHDdF}Mctrhh-ho-44XwrVo&i? zROgrUgfYXSo-kf&EUth98%IpLBmOoZw8I1eT(c!~#$9v;ozchDL=AeHmSlJ9HYF47qn}!x^RzL ztY#5Co3v2WU{p}zAhc2ljBMt7(pv4#J;QsDCw;?Zi7nr7Hz@C-N``pvR@1rUiehEv zyLskeHQ3nrnw^e|skypfO_tt8%ao(W4j{nA1Rz&Rw^u>j_`H~TweCEr3sux>^Y^Dv;Z6vZ#VVa!8viaewnSgHfLj0}m zyTXlqoeYt6uX~Q9Ozl2f)ew+Q{bNWs$Uzf_SAIXKT0U_5eznfC>T?j@&C>8G(`T?V z&8M-yH0}}|xi+iIovtb+wsXw;F`ho!gn4{)8pqVWsR#6G-&8cLocZlqZMJ#KRv%LR z?ppoZRCzShYLSgPH&C_wzK&jmOb8C66_CkO$uIGZ7ZX;SsEj4~bi&L)sZ{)cOK9ZT zW=>O;I%-n@sjnjs8n+Emv$OJaRBX$x6R9|X`Pl@dEZbK zw_P|p`L-9*Z_~8ZDFhY@)TB~TGreJv=E@~(-*U?TpH}e~M)RPPckfMm!{)YLCzTKr zItGViiDZ?jyMJIo@HB_7hRaCk2}F+<6)myVK`+QQn$gjHe)(H2cpS>VWY zf?ncnM!z58z;QJ=nt0i`AsMC^>MX4DrW{H+~(riOTx5u2t za^vqxMx?3h{k|KuYx6VJYs|(tEn;DA#4jZbeJ_U{_!MyN{FBdx*ZS}kx4dc8^6}0R zKZROi=n76IQ=X)XTR<@?PcziGp3Q&*ct)4B{4JZdv@AU%2) ztD0=z8E5KiVmy9Ph4g?}vcl%dn>LYiE`{IJ-EX7F;LG#Em)CTS-!ekbl$~koZ~`rD z&My}Bm{qp!ez0dfs|@z*e-|H`<4|`48x(SSEo1J{!DC0lr~VafX)~r~#*m+FW{#jT z?Uf9;RrOt>rS6Oo!|mQeI{#WAI{j@-=DTB3 zZ9^fVWy1$Y#}ADkK0a~e@WI2!jvqaKa3Y0p*7e@-kb7t-y_11m&@69`pU2h3R*A0^ zR$F0{US#vd>Qs69)za`aWk9vkDyDCyQ+}m~`G5E5;$<*wAy5_SDQ7SwKV&>bjsN%V*P_FLBl^ zrqdxAM&lOidboKzMv#_)8_-|RX`Ol|q@oa>0y*Uz=Ln3K0Gur zIzF^F#ku_T@XEGeM#jg+3gOuG&fzFH^l%G6cBgYtG-zL;6* z{GFU;%#j_iz&4yXzC@M9fcm$SYEv+U_5t-TaMB9(5vHkFHisrwtL7=5l4}oVB@f7} zig#cZlZ4<0{Gxs(-Zx8HnD*=NnVBh18rikz8Tu$hh)N~JtMQ2;_C5~ibab>8ejK+u zp-0;TKDR#)dVF+@`L097NHaP%VfWg?XDTge>_ibg9L$V*yEY!<%MYhWlE57r?*s^f zs<1BP6+R+GJ5wv(W^u~t4DPt7&L7ax=c%|%kp`7mMnsnl z?q_s^-*TFRu#X9@28rvxx;!0OA55Jj-;GJK2uG*?_CNDZ|>GC~hG{y&PWj4*EQ2hHz#p27Sl zK2h7MhtV%Wzv*NT_LKrAMh_RWWOpNga|s|d5b;TIDfNl-?{~tqROM?zzxNxH)UNau2&Wd_2FXl1joOal^&Ual%Nrnb7r%JqUiWcZLWSuL|S zjDIwA!|>3^_)y}c^fx8n@taD>V}WY&fE5U1MNjD-u>%2GqAmDJSP4Ug(65;0T~A-I zSMM~_x;7i2;X}lzFpi9RoHR}`Ao}PuyM;v?5P+F5Z}iE<@=O5ZD`xue#ir_}&R}cP zdDDs|AfN%87!8&1Ogc_)Yq%A%p%Ey@;RU*XxmHKhRCpn0M5mZkQRQSPmaIeZI!}`g z7T!BId!m#bn^Z+wW@y4gp>2MIf*w~mGND>&$-rcKt&jj+&b}=9p(vz6WeDD%GVmZ0 zz`6A5ir}_V;Ii^!rGSh1N7s<~^h`&zYVfLiVx+i>yM`+`9kjROp+mJOG7~$lpCHRP zty&eJb~;Y3MX8SAY`#=|_+mJE#?v4vVM;?AeZiKWd{m;sOuPHNe!CiBu>(j!Scv&} zfl;8lW)o;;NcsE%X{qseE-c(6hdW|nriQ1^an$NC9WGylrjT*ZxJ}^8Gk&R?1P_7m znMo{rW}*D5xSbruRrcu;-$o@Xg}oYCFBW)`=yDpDK$C@*zd!0*V=IcvGppt>(;WkB zMXAjUV0zRhXx>SBYAqIc9@m%6cqvqHEcY=Mcvfope0Vlrt96U%@s4QKo(s^`?VYy7 zMaRi?ZG-g*`%>jV`Wyb#CcGQzl#jI>F3jl;IoJ{qdU?VJ3+=NGdDkgvxMDe}hT9SE zQoUacysK2iyEH4jjG}Aij@cXgb6o57Os==!KO(a)UK-Q8(4gQY4g7XSQyK1I(+l!U z5wB`&%ha=Efvz7tnAO!9d<~US3K@Vy61hMR#x+Or^x+q?Nr^JnBTHLRXxY12+>Ey{ zonB*mRhzjGLu6;fMono$lZFOx`35)hyCz;2n326PWp3jWqet^{czojM=)t=2LU=98CK2%yKXu(N- zsLa4A9IA?&MOo@3Y&kT(Mk?o8>DYF?{ZKD~H-bC7m^1r3ox|*C@}qg6==3fJ%5qZ} zdialdcqN0zh`F!@KWGY~NSwNz(3jiQhE+)&(3d&)s_7WEo@h$upxSqOGt8uBfdurg z>lkLyIOf!iLJs+@T@PfeDhG3eCrw+wz#KbPl6O<>%-p6C=XFf@KMYYfoy(DV z>dfGspG9M3(H+)$8XsE9V}h?Ia}@!Sc8Puy#f_%WQEQ&By4Udr4+6f zRz@QPQ~}YqC)lS}sM4t3P^#X^-sUa643pbdek zb|uS_b5>U|S&cz&{!bh8t{HlM0=gCSBmNII=CXL-44wFg3|A<&NSVXy5-NsS2I_dR zjxeTZkggirG|%6{fbJIRF;ikP?Je$wL+xV+nmc!5^pNzUEa=hVz8D{!;6`_yG1dgT zbyUo%As0F-cwe_|R)?J1eEYM%e3NLiE2na$Go(QnR9cf9r5c)>IaQzs3Wf0(ZJ{7ir1xx&|)GMCf)&BHv!JU zMVu6pO&5@r*ZyGIjs$nru+Br#{c{+!T9*c0rN!x&zFYa z1zE9&2V2cgHHS?<0RKJ!%7VoTT~rI5EaD?8Jp`N|0R6a|xk9)eRJIeP5q@k58Q3V>^Gu6_>HL-jV5 zir>j}*7&iBW8=rNJhSMPqeqS(96!Xvt>B>I*`Fqv(DdnHyP3isNOr6#gn{S?Llr)H zVq$FK$mpRXhmU3Iq!iHX27Cr&>(XDVD&Ls1LxsBfY0cvqeho#Kv_fH`n~7=mh}@gR z{|}%tC5T)m!eeHk=F;L3*#TPmBWyfDXFV6p`r@T*h&t($4u zVtI?$o`yupi94SuR4!uMRtUvU97;ak%t!WxUQb@-79AyTp(YZ9saH1@LRLiEL5XQu zrfQS*GMR5F;?0+@l~dXR6;t*%ls7vuS_`otGx}Y^AL--;BU$un`+{S~jvYR7c;a|o z!5cq(n3-b8D1Uk6*pabgM@NqyKFT`^zHNN;;ITso4<9{vgzQNO(J&gVnt{*eU``kX zVrggbYZNjbpM!as)-4zskyOdbu;kiMwl%FO_AjBW!cg$T@+)z3nNV=cmHVTCc6Vgv zTBz)3SDKle^p=p(FJQerRgqq-FS2ZI$*P+W*Zip4k50+LyaiHvisai_m+u*uYefl6 zMSjFy&ACM0tRGE!$RcFRipqi>%QLT+Z>Fns!n??yCVwwa_!WeS$zzSQylpIH_Wj$2 z;7I-);HH$<9Gfk`0pHyEPbK^9l7p(s$21C>VT}4$IyHG92>()xQGw;K)Ukshc_Qhh zT)(qQp;05UMA0M$Ndu3Uo(`X_*2GvtU$9KlJwe)8Mv!ARlFj&iQ6J8sNMhB>q)Gtl{uC>&|! zBJYw>smh;+kset2NZTssWkboAbF!qf{9!51wWyj83+b?0GdJq6S`%6? zUn_%(xo&8!tG=~+mZK_z0Ufg%YL~+0Egc|Y2=-sOe7T+@^A$0gJcyRsfTbZl|K35ZGl$4+DN8euDyj=q1{colt8L-I$#B!(UlrRFSf;s zvIS|{Y9QGtUCN#Ux@oMQ{PQ51$iK6J$~B^y{&Qp2YN!RFJMw>D_vEiC&xe6twW{&Q zZHJq+sZOAG$OYbHV7fLP5Gu*jTou%pIa)0k6@@=oE9hmIC?eE0Sh;5FRmL@1-Ah6- zvN+;J3n^Uu3`CRT?9Jp!GZ`B>hfhK2$xQ17lU#!|J({hnSoY%jTwSJKcCsyfF1*~p z7SEyO-d_A_t?8OLeC+TTX4o=qSm6X54ai_|Xma*@TiZo)e09mEROK@Rb{6ufZm{zk zg74U2ry=F|*xw4IoVzkU)`HK4eqIJIo2rAF#WS=@AJB{!`MO=9b-rqjFNRj*oE{q= zo4_+b9ABGv7bEr3Ic?ZTw!4nDs5g4-5R`CijQmT>zj&qeV9m(z==hmBsAzz>6(yjXbzWx>@h*O=I1Bi-5+rf&S*WU_nMQZ&vj zvRMqTOkpHTEtvZug(kcHu@#|BhRcAOy~1i@2adLJe2qPmv~QADAZNkYdS&-Y(&4xo z$qJ6SMJ8?4&#N3Lansr8NQ#l9NPlD7ug2kvGVLW^&&rav7bQZv*RWaVHAYdb=!B~X3+ zV(2S|3Yps9LaylVbqTx`^6LYzHL}oJh)hPSf!U zgXo^?bQ}TNS{ebW`-TE>83ET7NNZg3VVsP&_}*+QTXT%dE0l1m7u}x3cSyoXOzO8% z?f6UEvyB^{NWQ_#-yFuV4B*vKVh%8%ZW-%X25@nUJ0rC zWx2;#$J`^^7t6Dc?qGJtKk_hJ^AD07tw=*wy}NEH|M*V$ht?GN%y*dBtX%aOK||6z z7ELrSV)ffSWt3r3OS?GaM6b4Jan0;Y*>)PY_NLXmOMTIH)>HoRH0M-iJG_i`PQ*EW zFW)@dsCj`6r16ol7)6iyJ3&YVw*dP@xNO&M)3)r#`1~YEt7fW~7e+`{9oC%$U^x1w zug;N2P#Z++ZGN3@W*2U|oNRtIJUzqHWSE{)sz3Z`ucdxGA1QisZ{qjMEtYBZrsXs1 z@ZOZW=2xZ^JH4CT?9DEt96-|PX7Kx@lrNk@&gw z97Uc6fn;?_QFfE8udG$oq7v6VFI1V)CzOdKyXwlm$*n!kM43dNb~O$GjPD=h7wfMcC`bHrIq`z2?@Sswp2 zO_^d)A_9im&R)U{^I)6yXlSJ>Es4cgq9l62t;AUe=#gt!%Up1s0?Oc8u`tU5YK?1G zS18L=?~Qk zCQ}>QAyr0LRf?Ad4TN0jZudQJhLIT9?^pAvWI$k6!IW|@8!p>EJIr}bFU}Y^jH0CG zFdknP+V3TEy2UBb2Cf89SH1mY+e9TX1&L9$bRMP!n_SH7!N+Fjta*jG zSpGye@9%T}Un`UBf<*mnW~I$$%juGL`2k3qotW`6)!8cxSHo^vS*t#yQx@W(@5R)P zaq06i=4>%y9vnT=R;gG5JFi(31D?n-%FdcRru_vnEgl;!&J-~=dbF*|wxrF?z(@G( zB2h?)Pez;Qtl>uvA3CV-&9ptaRPc&JqvWAEc=-5HwoPp7j7-R5_~?Ps(IQ~YQLsxS zY;#W>rJ1XPL{k#g;b>7G9?G^Um60pT>-VE#Xsgfbw*fFoSALb4ozh`M#0fTSm>5`I zH_?K7;JVph!I^UXO4YXeO?D2^J{_JVG_H|CMt(hQY4(s+M{WfW2b zgp>SfB8=(LLMZ1je#T%C1=u>4+zSk~h`@@VTK05{882ox>HVdVuto4#<*&pRHw&A2 zJbd!G{kGgU*WBD^7YXd*9!m+KIakB0QWm?C+_9?sa1h$tRvX`PUlRs9ByEMlhTnfX zFnFGQnA;(6SZ>fPk^DgBVT`cEyCwdzG{)b|VMHNuHG|b!3jJw^zs;hpxRuM|??^`o zYz-{J-@*=SjlMJ8qpzy`QVxAr>$3YUICqu@dv0r!DBv+BPnk^gB&DyhF`QX53v;iR z>y<`nDx+G--pNO6Cjin-l`_0sJJXx1%QD#ql<=x6OM(^`Yur7N8=!L-Bis9z|K-~sXw%xkYqUmIT(w%_aOS?p2L+SlQOC1Uw zv`p3HVT%)5A&gAI-r}gBCE}wsTb&hK6}a2p(CM zR3%Sdo|~DOdtFq-)|LF%I1$FWRI*G}*>imM+0#U!%wD@-_?5kKG0D7;z4$UTn>pX# zd|p&({}R|?fnuJxrLCNqBhUSfh2bW2NKwEEf)(UCc533J^=3*$Nnd0|+)!v=>WcRA zXYtxpwcZTFL{1)n`{d55Pc$u98}c32S?!`E5<~mLICKak-+GN|XBG3VwV{!2Y8GVJ z8XD=c;Z8TqwSJ_VzK6f(7ab0DSG^E@(#3s&RF*@ZrWv&%op)4mWW_a`6U+?Rh2>s4 zK9SksU@3;S=E3vb^I%ok6L|0=tL4Ez47e9?9xOXCCJXsi&5Myey494JUQ;+DMx8f* zGR)qdD8KBAR_vc>KY^8pgSt@+$lb_cRTEnuHAsc~RCYKO_8lm@-8s}2q#NtKF9sCT zsM`kI+3+hk)q+4n4vF$Kf`A*pE*zG{BzO7U5Q6&TB^bpc}LmfH=Kd;>UhGXthH#J%ZSgGuM1 zrK@h;w_dGR`Lv~9JFL&$TYAWM7GLoc$wz5TfWMHdYW9lDSe@!mv@8BO5o2^$h~5dra0;|}hDgu^(`KtYFpHg#XC$g0!gX^*OIti#8d zf9v(R#hHo*du~d31Q=@~trb+aXz2l(hRX8l2LOw+Q*(>6%GDom!EHpW@MZ(St!r}x zbXPBv3ZX`GhyW*0TW+-g#ibZ`D3;NnP4c2xHgld^wS|V!ZK_XV$7MVm#eA_j@&5E^ z6A&4fZJ{j5-@gP*9*P2VQZ+hA0rba-<_+$aKpG#-&jS}v)*d;ol>dj19$Gpt)AWH& zA>z5DDg|xC2={-QtmGvPP4%%%|4Eb-Ky9`_I|Ej1axa~4X!_#9h84FfeKg>y6u zQ_DEsih?FC2?$t%fK8!y9YG!G8Z5+|X?m;1wnLxgI$)#~(6(eVaqt|L$D#awCP$8* z8$XthAF+qnX^5+ZJ$-cI_%Ur#(gwlu*f8GI;Q%QF-vMn+XyvVVMg9NKIeRDB{B9mK=lufb(BHxatsUC0x=|hM^mYM z2%B$?-*!oDnRc7Lg#C|7jp~9^?yypLAb<;vMt_^C>Qid7({*%P`?@5c&Z&sZ6Zj=> zsRgt^Sl@8%a)6iXhyb%vO<|%bbDbntMA}>dFtzjDm(vqzO66uL^uFn@zHjQaD_8TY z`m!mk-Znc^dleOz24SitnS`*v{Oep$U((On(J5bEut1=+lddn4(o6F!0Zu9C&{t@o zdmaNS=*0RW;)rHTq$eT&aV7Lm3W4ojDy$!L0ldt!(Bo#?(K%NZ%j~_rP_~5W;@}Z7U5@5A${w$_Skbbg&iR{o$wU)>;0ub;ln2{JA{X$VrQlmom>%qs z2$r^8l$1gV_&?Ffyl^Lt&*z~|;kTd24$xP)b}iITUb@l+YynVaWl`ap>?~7C72xJr z(F2+}SwU2Y>V0?cZ6C$A&4oxmO=X|qXUZ+UZ4yJ^p}uJT^Tw;(ct(j0>$b~Nqol+< zwg3mA&OhHf2TCXQ=566-ny!~CwHw0)xFWAlz{8ppY`6a&2ma_D9oeah2K!b;qnDno zO5V!0iG`k0 zMZ$vE?<~tCIt1P1RxO6S0=O0em=XEKfO9i;9k*DKPZ`j~Qf91ed{jY4H}yu-wvwTz zO-~BL-C?^~OO?# zpxIWXGHgXooL_`Z`KqutO?9D7D3DTcoaHa*GHf+L7=Xb#U9O?Mnh-f_wPGzo>U(P;&H4u#r~ld+|E`RhR$1-w3}Yg#F&a_2igXh29CEp z^y1ccECiZ>-)c$F1b*BYeWveMEe@8vAjh_EflO$6L8pSj?Q+}=`mp!-cu~MR1KbUm zgsE#M^jiThvn4v<(xxQu5&4AnrGlc_*!g96@=A;y)w^d0)_}Ns1k+!&r~U$v5;eb! z&b(kr3luJ3zD^<&N(;4X)$D5Z7vaoVZ*NXnmRh_Nj+l9(a;L6JT`d5VTTtY+a=+?{ zSIy6q6{nvu6RgqR3%pQ%6_Jrd*O$sujky_x3I!>ocQ*2?j>32)iMCuf2%_`n`#=!Q zBqYA?Jcz7AIXL(+Nsx!Kcg=G!UJHU=q!K8Ws-;St5b2#0*cKo@vemFfy@w#-t0&DVjJA@gUm((w0cLgw8bG_H_WvqnjsorCO>)lzz_3ncmE=19L zd*tO=kfW#PjUJu8r&pngso&@0_)!vmr(M|+g3ejTxh02TRx(4kVu7jN>854MmoKvb z)6MhwB%j7?l(J8}UYF zx3}FYTATyA($+T5X1M8%lo+~eEGrGia0_N5cDn-*Xh(n`%aud&O-TR(sKrMa`8Des zqbsC5)w>iZPwRtLYhE7A(4R;mC+xjLkm&FvBEZX8C%$FRF)!PWK=4;pGy5zZwKWgz zP!=4dPgz>pL2MlC3QW-;?bR`IzLk&)PACcrIY6 zSnW#pZp%CJusc${yN20?;@z3rZQYypNJf*+u+(C%mw7e}N(Y^usg`-g@=EuT)$`46 zWA_=y{GZ}TJ%6)9SP832V8RlMGGliKGy#@=c;S?45zy8w@+VP_SE6^T-e(0Cc^A@O zlaTra=kgv-TIt>1vm7O!<*!F~xQONoDc0whTEdtwlSO29Bv~JlWRil8nf=nj*mTA& zBlPor-()?A4{Tx{%+il64d}Bgq_Cg4Jdz8TD$iVDzK(5;Gp{Jb((CmMXDG(_w&a?F zq0o{7aojdYrICYzSFhM?C#GcL(4ph(q1s)uTIJWsO=!38p`1RS5X%r(m*)k!Z?g%d zv_cA{?L+CSmgl~2QE*H62f!z@c6+lzpl7V2S>+`OiUa-dIVQ_`@SmT zIpd>;#t%)9imx36O^AnA91lmWS;0*w zsWbM?{I1k6(d*UOY4)=88(~VD%9{S|c!19Vn~{f_3Qf5+%S>Bkh#OT@eCXmr`so0= z!unGvfgoJsiB&>p;ZZSu+#~}y=@O;<)~)NMS7qHQq{`B4TXq)Nld+quuuJ`!WcOp1N)*{nuR;W8L}x*vIrq_+ZK$wJBlc?psWBWEdChr zO~NyNZvU8ntdy>QNbhSUw;B{;#R4!t&y{?fdsX^evOwffRxG%sKerW{6=*G7DUvOqg#}!&{(aI~mx{2K zDWuwnt7Sm8Rw3J|qRRtqk)Fz4x6;pN3%1eXknZuZb`xLAw3gU`R&cqs3c%wo(7Zsz zqI;a%-%jOQrpZS~j~zd^Uy{B6czScC9o_7UPlWSO(W-*h0%M|k6;xGzFR;Q@8?w*- z11of)SM69KOOtL)SLYQLMsV!xoa2HPjunuI05ewBb;k2jy&_a^$Lnn7;MVfGCXly= z*DVElOL*N9u&sDfcPyz1?5*QzcsdB3}39UF(3cs%*R?2@ztl z{K9a|rMRTxeiicB#gD7_O88>@5gk3M;-F4X=;+gQ^fn#UboAXSzE{Op>DrH}_-z%3 zbnW|8e7}lIy7n)0^aCnRs`z4EJEfyzD$c3+sIL8>j=oh#PwD7is`w!lKdx)fsQ612 z=XLEF6(cIXMAzP`qxb9RSslGkN6+c#f{M4Pc!!ElR-pwUu{I-*wY6}p{Xt{x|CB*hX(Hcs)Eag_Q`?5KDd2+u{|c^jkp^&G6*wyt+wkNZ2Y zr+=V-ZU6fIb?bTucJ{B~Xv4Z*{$JC-ePCPv?frM~x37Ow|AYMx^xxCJp?|ae9qfOo ze;0QKDL3`+?BCMAm7^{F+xUMc<<9=Q`|s?(tA9H`{oQ82ZT+SG9sGTOdK3NI243ht z0mO&<_W*g2XYb|yF0O3g=-&7hnmWzT{`65k$*-}Oq8ddn6REK_dbu~MtW)}^5B5Ya zlSgVz^g(W|jjG&Q7sVHc*Yk8dqT*>4!iwO87RWRF8ec%6$dAY}Qti{hd!uO5VnKAk zOWc*dXm(ops(6?!Vm{Ct)h}C&$U6W00>L7LjI39@h^wg64R%c3A$vQPvK}U|535>Z;4K$_#qV!tI)?~OyjFM<>!iG zJP}2YiTZcyK^F7(^LLRNu*Ga_r>Eg%B;6-D*? zg#~Yr@r(_v)++rdr}o$UG4ywYu#wkVW;n;>-@$48k_sbn@#A3)Lj3(I{)LKz6y%$uxHcd2 z714tD0wrq{F|9lQQf!C0v2lvLpavL)0kN^jcVxv6zGXj1L1PXx%A6;k60`TYsKFr zkMC=9HASW*`RZ)n6PJ-hk=4A&278greQt4NO?!~rHQ8H}6}LWha>i!Wy+4W2cpnmU zP|ccWdEJxdrPGU{HHeTL)_b(_!JHp5nga?!gT12(^i;cMgI(kM;7@8$HqWvFIhPIVGa;N4)2ZHce-N zRYH%9qPb1;^XcZeOft+QkIrITmy-~6!y1?~`3=kS^YytKEHpO4UkZ?FPt3BHViPB3QBp44hJ~0nJ@=ju2{EJxMe7H9wjeOJ zAS{e;i=PCg;V38I0poWX?BG8)s>TmQ{#=7WBi0|^0f*q=@m)fRHPJ3V-v1Z?jvb^l zUbQ`Bg4Qd{LU^mPRSDthL+z=?AvG0K8gcfQ5d-MM;7KR9zr5vnxsW8 zEMuXTuo9U;ET>Q9x9c{2aoo?n_$PH_QtjVx)UH#v@XTc0@eRLd@XOV$f)}m5Bkj(> zq95S~tk-oV>d_@Agnx9Wi8;D(hmLyHjZmU>qsX*TrYInr@*^btEL(3*EkW+aqpnvB z$wHV&5@1)*J(+${N15^J_)seC)h`|8qO+}T$qu&{RjWfK~ z^^HUhc!w5xHFZ->;^ z-e||2oNkiNoPqWRkDAy-PZq%S(T&s50%jS2q&CwQZuCWGUwJrsV?*-n20g2KsM71f z5o^#Om9KB;c}drKyKu*@UmRYi&ivPO=6S!=ehGVgZr{w@mEjwYJjcYe+utKuUF0%I zSz6aJyC`|eE5Y8bAx~#n*NRZ3qGxQ5wi8yBu=Iu}@#g{|XQ;oqG4_h*&1!nz5*Xu$fpOj~2b&Uy7yE(mu2$hfiV|C#XTGmw-KuUhP}bFtD#*)( z#bU#)8=i8Ver<93YRPXzIBN34^yAcv++Q3A+`%Ig40oS)0mrGcs+hymH91Wvzu}|GXp6>C)*E>o?|0r!iJCdBcO|Z0MWEd?cmx?0H99<730q`%Lc+ zM2}{kr+dE?F`%{drUske`rLCR4?w7|SP7pMyfi+V$_|IB8rNEd!l}6_3L1j`x{z%% zcPBxW@iF9t!k>p#$=Q=;N^an(_=t){-T3!95)vAgQE{?jNUEdpu>}bn9g>64CD-J9 z8B~p50^ENPmX`G3`i<+z7}-03Wpx{B^0wX`y>c{d@7WCY?r^v&ITbXcZB$^2; z)1xbW>u>P939|K(!QK#Ek9vgI84fN7*M!aAML%_h%|1ssc%Dd(wpjcL!C?`p zGtkUl3png}?#Dp|$5qW2QiQug+xR~Uf%j0Do9D7{U)b7)r^YW*<1dA%djJBW;^P_Y z8%WT!Z)e}SzI8o!_iXKZuourypQEd1MOV+ULl^F_Y1Pvo06E8XiG!+hTvHmy{U8VE zT)mMF*2rHi8PgDFI%7K>!A$&c9U#bxobG6zic(SNhs@o2P5aKH9UMrON4p>s8&NEy z#sWz!O~#Lp?M1Xtj2;}DIDG8zD1Wqz0W2jvCH7LSDzE&M+j79quaC~mhCsMcx=)F& zl3O@etwG88(CK z^3$9kyl7&fvy59#F0vjJA{F(1r->Yl^0LHM{mV@1IPr&^*|ijA7i^c5@ zTj553w5!Ae7mcSkP_~y^fr%*dULo>-&eexaUhOsQ6g2TlrqU-$BShS2|2pumI&*oH zUEjUjIJh_XTQq)YsGiB9#xCAIpE0a6o;#;VnXu9@n8b2EQgieQZ5(C4nL@IM)}Wmu|3i3)jp8F-XOv?zq`d5Q4P{Wet4arI$&}xqn;`JP+$T z%vYtCxcR!qf9JcKWSR3`VA?$ARI-K?b&Cp-fdcC?rCmOVM7c5+XtU}?irZ4>)pPq` zW@eo^%LG65$x{Zzn?Mtzhg{%c@&=#y*Bke#jgxH8!ImCJ#!AC5Yy(3h6Kf-DX6zl! zSQlVLGxr~J&rU>%jhLJg87P`3YyHrPP6!mNe$TYhpy?{4d=miK$9&vh?^YpAYYy=W` z$gRFav2uLbU&VHz4MJerV4QeRNNY1)>-mnxFVI_O+}!3qpoI9PI~6mrDV^!!|l%(!=wt+m?Y`QDJP`6avGqQfautZL>BmmriP> zb7&K%!9V1%!@yfC=qQB5u8>#L}dnER8SD%%4z7F@RfR zT&K8hQq?3ix1T;*oR?P_Uk3HO^~C7<`E?UW{}lzyP^KbO&>S6ba&oBaQL$|abIRTd}c7ksf7?Ej69 z7j4v4PK>xU9F4R;1S3z&vu$TF1ukOm@hKI}%{ta-{bNZWH zz3Hyr1W00V-PpHJNkS8XCzpS@W_y@8+7B0Mj+Q)OV8pM|Nh8RHj@pWSp07~3_>Ph3N6UR;ZLm|H2s zEiQ4*3`xf=M9sq@)_5aF@g^0URote+l-4PZpiq1&H>Mrykb*ov9sh)?JwwrsW$XsR z7mH=w&BM{wyZi3!6T`Tp7dK1aa8Idscklh0%I-C-yY>_h)efr=;M#pEq`B9&sxXcy z)-tVTs9mC$GyED)P)Hy{(o7L7i7f~|MC=zRFz}+L=mI0Z#|1Nyt=OvC*w0ibn;axM zR)&fEXnWmkVLDRDywkl zoG;@9VO3FLw|27r&cz3%A#jWNwvGV6;G(R3zUiPR&j{a+F$?cFMl+aB(L=xss2R# z4Z0>jXybdKL)qo}^FZkdt-)iQrv3Um8;Dwi=$yIBCpJEyhb}et8K)e6?1hsG-#Gow zk^QgieN4B~KM!a$=jJtw55v=AXrQ)Zw)uieF1-{UBL~V#)gFHA)TPRMFO6QR>`j5` z=z$UsGt=xshK8LYnBA|@L`fPqt=2)yr!Q6Z!m8Ki7jClE zqMv4)FW1v#vBQ@}1?(~lNex=~)CY23l>J^k>pwjY>YN~uvS`N`{a=(jcKUVFV(S-5(7__6!P_G;|hvv7~a1_Hh@*{IH+K44c*IGhRA z%jvQAhFVFroAcGv@2sA?{M41FXCKmw`63gFGIzz+O(>p*JmKFi{1tAE@RPQCw}lmt zila-tB_@-5pKdXD+Ak)La#`R|ciQ80U>lNbQ=KP3mF&igp$zkc_6w(9+F zQ3d7ME}fL?(KT;Vw0r(9qRN0bGAf%~warPZ>-&5BlU$M|0D#Sr0Jx*wmD|h|c(q68 zTavdm-WkrfMz5}8ex|3gEvbC{)gE78&);tK|3^;+32GotA_IM|e{~PmmjbfsV%Ot5 zu_LtY$9ps=cVs$7aH-8Bg0+K>;cTZn+v(1BxwBn-#8G>rhesD}?yV5UVYDL#c)namef4so`FSx-t=F!wgRhT4z)CjSPq+Amfgw>F!SQez zsysoSHMTis!!U766g0pcCUaJ^+aF+62oqBzl{GZ@hm%CIhLk8Vpbq){4j{PH1&kC$gEEzZ`aS&|&O z9~bG&>*bq`l5!(jU%YUW-k2>N9KGQ!Hj8TT8@Vl^f)gc7{U{QKnwD+|XA$0hpc_ZI z{Zt-->A1_NuP944!b4+2X@#Uuj??lpbYt-N@* z;7F^rw~8a#JdS~8mR87Z!P_aGyEQI)>OA#h_KpGmJ>B_zRpjn+ zdi!Vd%vlWJ#tV9Iheadw4d8Rzh?iT2^g0&6sNCAKb` zTezaJ;Sf@Clt~U2)1_)aD=ca0Hy;tQxK6ks3Y^@4epRq zU^ew``Rr_FQ4TkPf$f=Ha_SLiF#C_}=2{btui3l{vL7IJbINY6vzuRNHK~={JZCpq zF#_11HB%G6I6`nkbSLgV;N#{iNs~|ocY2>e9grc4zTmVQwQ^&$+Xp$=%%$2zD`kgj z>>69>ZRdDH`(2zxpfLMf=xZ=DmRBrEJ{ci7fNpF0=xzw5>1u? zRN^xgKOzVOsH6hyTHFd5;defCc$5;piAWhltZ*0-CbQ)z%$l_z5CO3daC#9YokY$l2ZT{}ieQd^HAgGX5W2w8K+YzRLoC%*FGzSu!xq zU76M1m6=a9xf~m*^wHDKDfMn0*)<`d<4T{W*L_$;c(GBS??EG)_y&&~i&gTob|myU z0Q*vr&>m_<8$~+z8d+?EG?E`vNBE;QGP^p>~UdFeWtW z3h$JxK3;84AOL)Ew zLM+@yize;Mw7%-f!qvw23q7`SIoiAvPPvAu^}C4r+TdmpHQ}c3Gi11%SHWiz4ryp1 z4ha *$K@h6+_JNwGl*fa(s2v*<(dyBCnyXTB8=Tu|Z9jb^y!P&qZHxmszT`PAovRR1qx*El+pB~G|)^r=!gQ~6WDSBY#x`>B^p(lLD$vVmTh zv!=MkRPYt{S$18sWCWQtdJ6gtp*S@gYaTWL%r9L-HnG|OVYP6zUak7M8mW3iE*mO> z(Y_>f+bOb}Sw|U&p|JxzcYx3<9<*JPG|*Rkh=tNH`7S)3%v%31@c=ObV?gF~&2p~< zamdb*OsrTWwJE&L{kl%P=G_pwTSA{swU%{lio*C$UEhUta}%-_2qbxB+$($yR0T_^ z&RdI&J6dBJ7RlOw6C&q*)V~=q(&TR=FJje$m@21Y#s)GK>MQSd*)SMcP zWj~nAwh*?`epAUWxNp;|P3f&QSo-0zWtmiO^Xc(FrYHYIU#Y2{h%lrz=&JBx3F8g? zf~NZCoH%_HrxQZdsiF0U{RHf8SlKQZq0~FP8O-nYMU5xzCX3o7l=<$@h*+!1=ko6e zOqPE~bhh4|ZHSJ@pT*;**}|Or&65Uegn?@HhXe1PLA8|R{u<-C8?!g@N7aAM-aHWP z4iisC@&llZnB z3Au#@sRIRPP1$=-GUI`jn%OSG`^MqC$#_9`T7-GIOldTUn1@@YmOR|k$68q2ljW@? z5JelFO;zEgn$3jrlc1Ae8Tf@2#_V4iBzUhDy}?h{$* z;aICUnQf!9l;fvbw$piSV)!!K(c3yg{2PvW%bTp;);tl6%p}#qoH>i}4?B8I&0Xe% zl1~qQ7qb%rMQ5H(yyET!)^EX_C?);{^=9(n_NAG3W=QN(S$(0!)U>o$SKv2=9Dga>r`9zlOqg`5h`92nuqO!lgre(?sLYsXAJ z1k}G4GqEKow`+mpw%)sY_Vw(BscgmuxSuPx_ZqK0KYQ6`0+i<_{#w0D>}GOOd&Evo z4qsC{_UN*-!O2O~iOEUhaFde~2jIlyq@|j%Hcl!@K9p+?hO04L$W?Sy)^MXedQ`>pDh{hSrs6b(bt7WDys%J@PwDD$70ggZF(c-aVGQbs zA9-(7JV;^qbHOI^yfnVT3}dw(KcOdhZ)9m&;_uaw1u1F;bY?NsujusGRcP&p3y1hk z9sQPykE>7^mBl*6ie88{e;$8W@W44t5)~R+IJk@+`xJ%L)Nl}~FW-JHe)9Q?=ge7j z{^<+P$LG#G!KrS&?ZWvp&!0UP|CvBuKjoTzowMg+89cH4KSmv~X(vW3 zBBNNi9bZ(TkB;{W!ectxrQ)=T1G-kCuvb^+@RK(d>{tgRVT_M(GbJKBDvr4n3Y?_I z;!O24Qa5TS-zdxgRq6)K;M==^7WvO4D|LvT`ZZw6_w=l@&B*cxohXZ&UEqlDS%6s$QUcAq(q#yrN zW-bmh5^4)UD=4Y558t8obCbfB7ibEt&J=jl)YZn>H*+Wu;WUC1tvk5U1J>OM9PFX* cI9b=$oK0i-L1#K3QlM)^LlFTw4BEwHKAzuM5dZ)H literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/difflib.pyc b/PythonHome/Lib/difflib.pyc new file mode 100644 index 0000000000000000000000000000000000000000..25ef4fc5de288f8b8624f9556b34ba13b7fc91eb GIT binary patch literal 61139 zcmeIb33Q!jdf)e500ar{qPR*L=@T>*zy%}#j+UWFY9XbOCK6|I$r+9*QsBkC7sSPK zFL=KT5wOJ6V`*mWlP*qDpW1QjQ|BbL$BoBJn&mWY>@JCWY&Z7lv0JCMWBbId?X+p# zOr1JSd)(judERfi7XU%cIQ40268P{f@BTjTv%k;V|Mgwl|C7J-gIB6i__u?3L7IFc>XvjjnHvN_C3a5!LoaACR1q9*RDsD#{y(W~gwV9zTep zZ@EtS4@b5AQSCtVAxX(|(2`Q#7E5|4OS&s`lyyLK{OY9&cyy0OscH0sI8xOx7}$+)`QY0b=> zA3yc%v9sG_{(UZ~$5-limg~)G{VmJhjytWmUGFTnoAE*;>BOy>xHDU)1>6tcZnbK0 zz1dp6Jv$tS`ihOIwwj&#N@q&_8m*j+r$arj(W%bemX(;O$fVPzd$cQ5Rq>w2jV7J9 zGHh%#8dOuPqS;$^*&7>5IBTs{ntEHk%7*S%& zp^Tn^y0}nDlHN)6*?u{mS*WixrUAUFrAlF~qREJtDh=RIlauv_he~rb?yN4=X}uSH z$;Q@8)VwaWf#s?Sm|b41G{@TYO0A+g0_@JTTZ`RAE;O2Tt4OetmHT>UaY1FTSMuvu z-+D7n8a1YK)&FXV(Cma2aJSK!jjOYj=Iwes+qgZuz^~Rw=OLEcn&r{i!dsh_&Q|Wi zWOw#(-?I`rgS_+JT2XIYnY#G;%jK6ZUVXJZ_36)D{!^WuB;f6vZ(M#ge^FcmmZCV< zoo!@EdumOwW!Lya{#_mgkw=~FT$+`|dabj(v{3hVYDv4!FxL|mP>H7*g>S7_`*=uy zFLIw8MiC(rQO9r>d2O>hc0WKLzABS|duWMn|Q=(#}#VAMhX(BiI<(bppg!B| z2D&q3H_#m;c^^VdjNqs!@bxbHN_D&KW^Yu!GO8{l{~lLEialTuH}E6J?Z&Z#)QDx_OU8dWc6;dZMHoG-H6>NUn0 z)G2IcZ3D-5SZ_0xX0=fV(XtfuHLj$Ytca!MY0%y*XbB{%CTP0iiBCR1J_3PRjmzNw z1*X-?{meA9NF*s8~xwV{R1;oknbT&waSCy#JXeM#96%WrXH|K|~oNNF` z%VVF3Ypr_H9O=ZBT8*Wh#7cK8v?WoCv!={KPb*7H3!q^ur(Lfux0A-Z^#u@K%SLFa zQD?=as6K6tb;DX;pP?dVAtY}L@mN`bXr_Zv?2EO9p-@BVNhe-y)E8>;Vx!qutSrR! zTEmOTYJ-X{cRYEg?v;fsPVY6}kmiL}Yd*FX468j$^%mFzd@qFfw$4}dAjm@;{^>x9(hOW{9T<_9lYfv?efp<3YGrvV;hdm@B4^7>`Qo%O23qQsHY=h5 z$HW-1j_Q@_Y_^t9Sus~>n=ekm$YQ-S3(rJ-bzXV_41AbD*bFse87A#r=LVf?v4Yz5 zrB)lnK;2EBe{~^+pHQ$DX_Gl!w}D@%R~XoLmlwo^fJ>|_s!Ud!)!EQ5CS!V`Rh>83 zwzULn22mc?+=;sri^SwkFI1ZI{)u*4NidgR%8HtGgHn!J6KJxx{gjd7(PM$fb}H6lB!Szv$4|x+H%~Ism1Nn*K)^bjG!`2RuvMMa z;ehq5$l|hpS>?1Pyx8~z&<Sg zL)GlW?G^}RG)W6S8K3d)jh}k{*=M^u`o>JW+FBlAEgAHr>)I*ZT`fJeAX}z^#)JtI zgP7v!DPI%}8PLe8tF0EAC1%;aYy6T^>*jObH3b6i$Z+NDqqUnxC#LPrYBM?SD8f`A z|HJW7FWtIUd3!v~!A+jw`7C`%_I#Rb;<;kF$%)>Clb=jeo*_?O;&`6WioDzcNNv4o z$dD2`vGJh+h!|5?h4nkHL8~m>t*r9L%Bn3dF0P&gmDHP~m18Gk{hj9TIKM_Vd)Ixn z0ybcDP2{pUQv<9lZ$ucac(e)J0b+n)I)DL?YBqP{0TDQ4#CIzI6ew`M*}5Cg@+;Ek z0)u)vgWS`}z=H8((@cdb3zdOtGXEou|Z%;gT zmibP(0AB}}pdyT2E&{^c!aA-7`7L7sgtv{LJ56c_QP?VCIMxW6@icTb3SoxG!|!UTIZk5EA--ejQa$DcW(*EI%mOSnT*pRg5dcGc zFF?9z%9qfcH~}D7?XA1sn1(0^)IqZ5a$^BvcN?_QO90|3G#PrwI2ij^Yw31oc_Bvo zG9OxXm6kVepN->J#K*^CPpQ4SJk3L=0WV5g0MDRa>w)R631^3|^_3-*J%Kw_B1p@X z9!`$(dU6RC1-w0F!}wVL(n80q*6I3e<=qB3YV{@fJ}8m~sbX{!9v^~LWAUtN0JLln z?^nH)RA}*K;tC|8Ot=^dfb1@|nlCUwY4@zVG*(bhX@~K7%Xp&{^-oQ~0(YjSMjMHk z_Vbs~vH&mVM@Ha)xjOpSTDl17?zESyEP>tu2_+{Wb-*fd9h5a$8L!kq1B^|N(x#=E zbXK8W>n>pe#I+`S5553fY?yx%gtsPtQWsvymWP(i+5#jeO$9dD3Djt1p~ZmAHW&}x zP0u#+vR@;)378u4bdlurs`56O&yqK#0+eu;0&a%xu1n3bh6lA*rVng4SR;rq^`zQH z$H)rFYAi@?Qd4TwRd$9AH!Aa)F~jg(g$7J*x=6%Fq2=jNW?*f4OREHiCNL)j6f~0J z5qO(;bY>yvgC=fD`=^H9S#DJ4U4b#0k8G-6Y$6aK{DS3ROtd0W)&$Zhw#)=aD`H_a zZDqZ(F!d2jO_?@0s8w%~ic|ACXepwqR4DrG=l3GN$+KM0@}TUQLd{%?26WeF&;8N+ z19oHAxh>KAyzh@t<(Ei!#k4-jlLHjA>55VVKC>h-P9&*)8%(BEDukwm8josS)#@{q z<%JI99h6dGjOt?~U6vG>%~Xb=oyn-o14xy8Eu<7)_^@r7UD(GqETyD3>d4AT6Vd=R z1l(xt;1LuFuMM+dG=B+os33GWXW7RQa~h`*j@2psL!pqd5h7eHPm>KCx3e}w4N`a3 zQ`tfVXCW$t#lTv{pu?>r^j^I{RwVKR=CP4o#k4l?s zT47)K9k52E71xo{x?9H^B>*HKNgmZ=)u`HJK0G8~NnX!QVzK?Vtfi2KjY@`#& zNrt6Jp*a~Hu1r^J;GALp)Q5YM^^&sjQ_nq97BH9nS~hlQf`L!AJM! ziL~lb&jq0^<X>hZCa@Hg^-J#$zTv$pNfr8(8D!PXKoP~97(25?6?rn|U-x{@lBwBe% zwrmx!O$n^zV^$__2lU*&7rj3i%?*Xe5^4Ex{?5IKpKG}5grc`;0KIYdNDK?HBWi!5 z^gedyQZ&CMz3+=2!B&0f-u7ta&9v&BS=G;2rv{>XJFK)FYQX#3qxpfT{Rh$e+tz8u zA4GTlz?z{(?oz!|yDg>PW4wmQj%su-H~uTG4W6ThM%_%=1_+&g9;YYgIz#-eqc1g| z6oUuQY~baMp_2)zS+n$fG2YBLHHrInGhbg#>@!AH`-^O4JexT%G&=Rg#2g&}q+p_* znlhB!NT$VpTBY0v_H9KV$oEHgz8nG4dNW`^`?ct^dfuZ~I9nX19aO^Ip@Dn*qWAae{kiwK+hIWZ zWtGn3VWm(h>FvH^^QnZNYviUEcdkd*Ru&`H34IWt-zx#}YLMSE0<2p6GpPLt%VDPy z&^Q4YD!`3?mSewwlZb)?Vyc)*70ArI`vGq83>-!dMV+M*UL+* z*WP%&cB^{%W;H#>?A-YxH7pc*bh$6@5%+1yX^+~x+pt4?+pI(Xi0aClf_m3fDF zPOD8j)aKoW{o$LBocdGlyTAd9y>C*RD4K-nC07xNcL(L5{H+DE ziIN1(+GykC+{yW4I7vVkO`NT~-8kDgF@IAmjT=Fv`g?os>>Mwpx5pxp@xv+!g{NN6*~OEf|ICtz%M}AFMt8I^a&m6u!`#rV?TpI@nrnTJn>ud2^p=N z=k4_QPaq%RDR=&vV}(&Jf@T2AlYzNbk5cE9?%@U)voWdFu~1>$L0Ch@f{gYqrV6>~ zm@lHrfK(c!pe>b;NxR`@DI2J!JJV=TOq-LcGE-j;W=lnwvDuYtdV!k9-q@m8kt>kZ zp0#NP#Se{fzh6vP*lDv4jLI;6tgANkg;=m;v6HG(J~LPHW~q9bjV@QJQ?IsJmr>t} zL|7%Ww|zz47^;|3aN{dC=8hepCS5#_qm1@w;qDCA}ZS_&%weC%TsyN_7LA)ZHRQR&K`PlNTZ@WVSxCraA~AB8)9tn~5HQ}%cF(4(dO;aPuo_f^#xNt7A4{7}X%!!OMbMeT!u zdA=fHkd~W}7w%1B>qBrvT!dAHqtvxeZ1rtk_8ZSU5Uu=@7|ixai7QMof?qGwO}TJ9 zut!{x1Q8AgqJbMon<)zp=L##-z9L3>jugmn(i|H@B@Xh}EFYqq-%}5XoZaGPyIQ0S zVy@w<#HbBg+K*?P=(hCP^Jb}>2|GlaLK$~HUb=H7;^&&$VsflBNCOB51Be0$0g@CD z0`97@mu|Kqb>yK42L9f|5uyO>y_j|JvENw|1Fz?O=`+0l!_jk;a_6lQU)n!Zf^k=G z$Y^P2T+9w~1G2!wV)l1Q4DnpolnoAf!)*S+W{QS~@{qld29cu4hs+_#HkF&)Lp|Ar z+!`3eZ_wT>y85bgEKptfa==6eZHv^ZaCb0XY={X?NU4WffqQcHvw2f&nsc4an@)#A zk&t|>gt$1gI<2Nio;ib7F~XRsF?dR<9Svi;K;m;0aJhb0`24f0a9_=M@)Vp)L*A@r z47uM!4R>!;Az6#9Fmb0b>}lMDKUF(&ni}l#fo5pi|t`_;?4ZX=!^OxYMYfD=HB?R=6SX}0l{x#;DALdw6WJuiAm%TR9qq-dPM5FXSK;8rD9hHCVV)xefY* zfo!lE=J-1|neNkYGl%&DWvf7r`;7@<x-za#rX&KA$LKuB*F=eNoVl6 z&x&$aQUrl2n=Q!M2=4mwc)!~~%$FX(Yf%xB7#iA{GB;U3B3JoB7n~AgyBSmQk3vLO zC_VLV(`ewKytIJ$GlEMXG-l##WAdil4}&8>_-Y=uke!LMbCWq17-2UZLZ`B>m)E~y z7*##J|1M`fy>k=i&(BS|PyyDgR&XlJvW&Q2sa28IUud3xmCPyEQ?-5q@3G#x^qkk% zpgyL+2-4d6j22jRd6%5zdf&6cg|REB4ut5cY!$+S37*dzs(WA*Rc!%KNtEb`kXjWtD46ITh z?_CwAfRQc=$U=aHW4W|~GELAxedA{*ZpNc`RN44he8mfnYjNg4JaP66UnKVJ6$qO@@ zR@SyVlW9T=Ou+J<*{zpk6v;s4vY9;0u2nW7c$ET-+8NGrlR`$EtO#}=+{IT~w5`&x zKhtwg8YNlvs{xhUn-QQLBohG&Fd*S2`8e;QkBRVXhuAzeI0#`GLLTzpL1d!?{ewtE z4b@Rq{Sp=RTje+Ty^PX)03m@c^vPuf+$@Qv&#=8| zji^k&$guD_NWByt7Hhr5Ub(0fUTqb+_d?EzpitZZ#phN0R{Cz;Dkz^JR24=*4yl$w zdqoSVs1)f{sA3?pDrgn2F?mQ_8H!eZN;O=%`M08VYY094cTDCQhz=tU&0{g(dB~`q z83Z4!4JNq_MV~Ku#l6F$=i=D(X*dUM;0sl$ua+t$lm7x5iMaYdmt>w9648Z_GdZo_ z2sVnsXznB#X+Ce;|F=L`#b+eH2tdSdB-+V?LfJPVR2T4;lgm3gyZVB>#__*`GMTQy z9pUAp=&6goeStz(@UgW$=U_2Jo!ji4Sqj39nb)KAV$3d+B=~&c|<$G)8V(7oLK*W~&<7M8_AX=eueHmw^{goR3FVMna#{ zEcD9=a+iauS2KC$>?FG`sK{%Hvpj~N)>d*RRI=Jzi4-;{PB*H`$HyWPjP@AjM~zxl zPEH@QohLR�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 Ov%haB9vawL`hNiZ(ih?Y literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/dircache.pyc b/PythonHome/Lib/dircache.pyc new file mode 100644 index 0000000000000000000000000000000000000000..81bfcd3ba840a58ae20c2d43f95ee12ce7cdc877 GIT binary patch literal 1516 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 literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/distutils/__init__.pyc b/PythonHome/Lib/distutils/__init__.pyc new file mode 100644 index 0000000000000000000000000000000000000000..da916354cdc5998f5839592b61a3c43d43e6902b GIT binary patch literal 380 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 QnX2H9tZAP?Jj9RvKU%^f(EtDd literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/distutils/ccompiler.pyc b/PythonHome/Lib/distutils/ccompiler.pyc new file mode 100644 index 0000000000000000000000000000000000000000..74c07b1a93e97253ef498a3f1b6dccc9d8bffe69 GIT binary patch literal 36549 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 literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/distutils/command/__init__.pyc b/PythonHome/Lib/distutils/command/__init__.pyc new file mode 100644 index 0000000000000000000000000000000000000000..29005876628c8f91d003023b83f99725e56ddbcc GIT binary patch literal 660 zcmah`%TB{U40Ky4B~S_!IOo8j7kc1=gb+f43m2%w0jY{)w(F%`v3V%#@c1wOj32<8 zK7bR6;>dHlTu0vJndz_-BBy1lckvoH09iTovsZAgjA)Ix%--yMLM@zv$wD_QE7`_Rk&Qy-1*Gtm%Bkr zvbBFi$~7VfABd%SwO)2Bi7*_ZjD|Q62tUD}2)#Z}Mjt%Ov(vLg=1oG+`UI23;uA!1 dz=%UxaoG1onp5S>WjGEW)Y{EQJ literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/distutils/command/bdist.pyc b/PythonHome/Lib/distutils/command/bdist.pyc new file mode 100644 index 0000000000000000000000000000000000000000..0b14c75de2b59cf7635548717b0469e7fdd568e1 GIT binary patch literal 5129 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 literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/distutils/command/bdist_msi.pyc b/PythonHome/Lib/distutils/command/bdist_msi.pyc new file mode 100644 index 0000000000000000000000000000000000000000..53016ee53776bb8aebe3422e77d14d37077be1f4 GIT binary patch literal 23758 zcmdUX349#adEc7_2m&A>Kp+W{A}x(5Q37RhC5pN&$_7DDqD+F+02C#V?0T_p01U9$ zUCsWWq8yIhByH2wNw1`r>pIQhw07InZBskxk=QvL$8i$Jc8)e~)24^> z|Nr029wg+0PJa1?ARgX*eD8bT^}aVI7@OhNH3Q|&U#-DalScr5ES)eUC3$ISG&^afMiXqJ1;Os`A#m};L{?l&|2 zF1^uIH<{(lW@fWX_nPW}S-#24+~m@IraEYrhs?~7OJg24o0*$6c0c3G!)9jKEN?M0 zTg>uSGqcsz+oZB>W@ejN9x*c`W_i1r*>0A1n3)}@vDt*%%^c=CU|uoisxi;c>@@Z! z6ZR-~u$g-cmp(N*M2Oshp#S)CqZ%%UwKVb5h0ve1QIeLHlgO{smzT>mTkMa%jDM4( z0G~;R5zL2asj-?a)N7>|!Z?ZQHCMI~W#g`q%h-gBI9#s35SG$73|-~`GN;lws-(}h zH{OcuqZoQ6jjGA1Mv7i1;+JhjeEQHJDw3pHF z;!0SnglRVm!^`QYB7I05jpDG9*5lQbGd>oU)0H?>`=e1Aqo{q^+LA4&uCvptuB3wc z`o|HE;5T^|K?tM*MPYlJ7y_#`Y`Ka+3I$qIAJ8`*YFd(E8Q#YJDYr3|m!8<9apm%c(XotvB{FQbWyn zr5eWj`+fY&a;gBcU!U`5SJJdzOCIxQ%ax`5ehom{?^ntITD9oAEhty3tLS4kN|(!x ztao))4d>Egg(yL=685L?n;b@v8nft`E5=;$%&VU95L*;rcC2+Vdr`mvSgyFFKy-Bj zkhmL&xq;oxB5<0N=`Q>x1hDBE@&>vp?3cg9GPCI?6c*Jmu<6+jS!#*@+$qzl0Ds-8(!%{0J~O;_g%kZ$hgHo+psF(rw~F zlGwEkrUs}K7;!KI5)u`Kvp~QdIH-Wz6%+%93+5`JMlzB71cEVZc^WWSc6jpRI3K-$ z!}CrLDmLr09mP9O#xVHpUqP9D)Z z2tl%3dv}QU`$-+$;rNG`2!_Bh_Gd#M6r)~=%4uk^P1q}fDEa^cqE++=gPRd(cXSjQ zE6IZEGf)9xscj1gc>$a2auKXUbhBJZ0RV06T(vx(+`z`FLqhhA7$)gOU^eu4eT5!R zBaDkI{ps!QhcKSoT}J@_Jn!#)Jeuq5Z@|3ub~V_|f;TX@mBDQYZe$CID-L`QA=bHx zJg$>KoIkxSY#mUJ^XGX3zX(|US!|&2VC>qh(~gm>Hc9GZNMzL0GvI=Z7f58cg2e8) z>N3RTcQlz1Xemgo$SKhz`8dO;$&6bKHOM1}3Ohuq;X|M%V-6QozzKw&M_>&U%nxat!3H_ruaRk4~VUWDA zQw$GV(eC9 zw<$iNHqg3IXNTfD6~9ICU5w8|FLWY5Iz&GsW*(X)2H$P$8;rfx*xQWtjlJF2J;vT) z?48E$HTEuJ?>2VS*nP&{W9%D^-EZsxV~fV#Yv!R7LQ%Mn8mK)eb)nDL`xWUo_K+f2 z$peaPHugb9FoA~@!MYw+1Om|`iVRWPc$8p#7(pe5LIladKN(fxdQzWD{o}PHg(!l< zFj|CWxDQfvtsF}-aRN9_Rzh^q4jr&jd^kCXWEw6v>anYtsa!r3HeW;VaPpK<1eO$^ zchZ1bcYru}SORtybHAN9GE+?(ZT3XLROvGoIyTV|Pr!l%OOm*e_M4I_{nO5Nhg%V zYV`wIw@?)tSgKZ1(MoLHuhmm(>@4u1I`{w){#4fQkJ5UpzdE$-<>*D%VLc&rf87r2 z{%Bs^?pt@Rgf{n7XrMXT9d9B$YU7q=%DfbVY?yLO67uj$L<^ z2s{YS@e1^3Zhc1;j5Hf!JYa6vUXYM(H{viyqvn7wA^+G4CHadh;4yPi8>&+20zznN zZKGxblxwR(YValumkkC*!1t#Yz_7ArwGbV0`!VHAspvRUT^RrV;(dwxdocTZfA;rK z_V_Zarw$_jO`O;W0^{|q^V2j4QF75PQscyiEn+XRi+$#5!5M_K zrAxggKA~dmCj`gEZnFlFa)VjyF^jTYK!8LW?zv}bfLbqk_?mJS`^@I}MYZoYi+8nvh#6O!w<{i##R&oH1KhxRRCHvULQkOv~AaA>wgk^Q)<$}5R8B-fJ>7beo z87JwMTz_tbz${Fp%PsO|6Zd=UW1~UiY(B##KJQ&VmXEx}9KEpDWR@}X?Uue(!m?+U z3MTfw(-(aY|If0kUNs!nbkJjl$J-np6L}}4hKmyiWa^SD!L^f6PXr!WGK6f8D(4xI}`)=?3Q88m*p$%w02o51g9%SEWc|HB}=bU|&5;lp{ zD!5vdo18-{5w;VF{k!)jcdPE4xG!j$L;6JLw8K^o^ZuH)y;D( z@t~O+C32_a#0jk2VE!T4RA_Vj56FlD$u_J*E40`cj)>)sO*U75nGcp9$6Upq2 za_Y>7i}k1$paT<7xDM69VB=977oYlFb0m+m4qa|03A)V#6_#~jb z6p)KcX3t~y!2j?z-N>XZ=*)d8jIl&1P*p&qAs-&{`o&i5$9PJUup2!SXa<)P=>0vJ* zKFlwe5?GCkfKs7VFNqC_&>tz;uTu@%=m)btllPev3}+)dc^Oo0vsr{x4#w4MZU+J2 zX$I{p~G&lSwbnwySHmmGP6Nr%kh&1P|!7Rp6vBmGpnx06C{Fr}@cklW1S2&s@; zln5>e>vqn}}$!xv5S#1sWQWU?zTygN( zn0I}vxuV6cHFIvua^m-U9Ny28`NjZ(x0^MPI7IfCH9(`!B%kz{yn{*ZA96nD*?~NX zqB}JSP~MwNy4PIk=L7-Sku?Vc)M%e(zlk3#K(*tP0X^K05zw1W4IKaS-hK* z1D;=T$$cE<3cAD|Yr&;^RPBxG3Gw{`9&|;_0DXeltPN--2TbF=1+JlJ*08lVnfQZ+ zD+6ZnUTT#{qB3SI7@*R9CjLZTyhZKrYp*e2;x84_gV~_aM$r@bO@`X{Yu~uGL(SL& z&Dev@*ga)fHrINZ5J75qChXol#zWAqZqO@u2_C?LRL=*fM=V)eVmPbL5pLN%oVgqBr z>G4yO(_`b)BI!t;2~HfJJa%gA$f+~aqRFS@dLxX}Rn-@tq8^(B_h2+l8d`wnWaHHm zRFcuhQQ$Z`;ewnd<00jCfW*xKrM3)~;##8J;Lo@@)VP<*aZSP|*PhF(WSqH_8XQ9+ zc#?sb)J=$uB?;yVNlKyC9y?`)=FYm0t$>` zX;E#i4$=T~PA$Q;Y>T~W{@6H-uW_+(Wi2m}t4bCTD-=(Lx+NK%+?*NNhKDiwb4CKq zxjdVQCDS4qUdG-f>T;!q>%ApG337f}*TAe&Ucsfelg^jRQ7y$UX2V_J7&!pCkajam zA}mc@RLGrQWd;P7dWY?zw6YRe$q05H-~s~q6F5`lGt8S}(8L-^SGm|22d7b}<^TSj^ufUPX0xS z`xz(-vGN~(o zJWKQe3xjY0R6r5LApUoTN@&gC1>i_M9`8u;A4PpKW@3mQbNR`sJFRTORjye!NVOpjL0#=SngkXPb&rp%M z5LC8mdD{#pgXMu+b5-Bwv8$~nDHa$(F+wnKfE4?m$psi`&@62<@oTCCp00tr*H94) z*EuM|?a3uy);7!5Kj**RK_m=RPd?KBrZTHqAa$xd{a?#ghJ zq7-_^YTW#gAo^)?a~lX?P7ZC)UW~l9jk!39RDlv3Hj68i^g!dvr05nIr1+y!(__Jt z6VpeJ2TD!VSK>+t?;a5@$CyP@CqOuyr4aiLN<%wS)?4lg#QbD8f{dTf#r0*s426|f zK-GFhM&XF`F5zixa(!PF<8U7HidPd7qP@u#$OgL*I|>YSLU0Lz2>STgkv4wXV3|}=k_G9b0ojmrM0Kc%H(3(R zHo+?h)K>!>o-BykBdtwjGvI{vDm-Z%tLEgQB)3E@mzTnl^gscPvI1;lwN%UnIwbVN zR-QVp&toxF*RhySHIzacoIuA?UmbTMuR&8Vm{CI2F%T|X^Q@F-HP5(S*F3vXz_=`i zb0YN-t>cbEurFuc&`q{lX4e1`ENqxmoDTz6SB3Sss!_N~_MC)R5@(+oER>nnZCw%K zoJK4+V-6x5wiaGuFXTAXqVebJb@X`$nhXLhlk;p0elX~5E9@eF04KNwT;V40he7fY z@Q5DocIdyzg>wXX2Y3tk#}4q4ov67B+)5g>w;e60H4lM5k>|V-y;O+%WVb{Y@smLy zHPmA;lgkAie7Ig+_(P9cE(kga6LauffO)(A#D)0Oyl~0YQEcg5qHsP#*^j$Oni! z$xvI)JUA8z3ig1s3k{^op(RKws1O=ZCA+o~h&85qyI2g!Z;#myEol23SPJI7C(i~E z%d@eFJIIr$cWpxUh-%M+#dHh~3XAmvEFRep*%+n(Mmwn6MNo6D1Zj8McwKWSP~S*% zIDSG^2Yl@=-ZV1CyGTcJIqVzE!!&vzcB@$e(hX5w1$DnTWX@t{Q=@kRIg$jZGG;A& ziRu;(P4q8nT|&T6SVzG!E^<(Yf}BS3M#E9Zwj1+I$BA$?cl!D1r%p{4PmYa0b$oK7 z_+0UMkXf5&pP8Bnly@nr;%*4WMwkmlVlhVZ-aaR{x=akqm4&83^Q#QrAwCV|NB3M=56b`trd*V^n&quPX)3DHHIsHKt=kbTJ0+)e z!yUsSPrA-@0ny4mLmiCjo6DNG90so;<+!do6Qhi%sEGdt;rt1*(0bfry8Kd115rh1_bPAPS}3<#J)1&BD6`}}ehS<#u}&0J0y z?sit5Ai;NN6a)zsrO8v%tqqCD527z&29wb+qlXY}1@Z@U=2-D(@{_Ys?V$(6)B-W? zgUAakf>9D%F*dOeu}g6Z$Rt{NruUSjh>|L2J6Hmii-U6al%V|~FQm4kJy5Aq94IfQ zLmnIp*_|q6X-W$~u~L?7T~*T%P*N`x23SQ2!eM%~5#9((dpp`r5S5=s#BAyT8_Lz2 z_P>1v`uJ@Y^P;*mg!p#++zRDsGg8~z{_a8#Vqj#`oTwPsGZ=(KAHu_vJ2xw?0Y3&thy?BQ?3sISU z^qBah2f4yohnWNFuX`|BbHN9}%AmPGRY1SeTzG*5!Pg~NL%kr&=`MMh6p}WE2c`tQ zX^=_@`a~@J5Ml|j?Jh?X_9ll9>8#6_2Ue%7eQ~zz9GsFJsEoG({^31)_Vn*P=wGP1Kw_&Fy!LQ_2ajKMuy4=NsG?f7;u63DB}a9#%_p-JWB|HT2P{a&A7tV#R%m= zDCE8J5QMCOrM|Btc%*VzAO?Eg3OKynIQuDF=#*=*K{U{Hb)#kbr=ANHrcXu!dhPcpj@jK75cKRdBOv%LODJrdO4H)Y!+2eUq_| z8++K${hp0b{Dg|%tm3z*c&u3r!hpG;+aru%B*@H=6=7wu3whGb)D^$(LQwp5Eaa)Lwh##ZxU<5J9Cr&rVx5H`cb$bG z7Ylh>Ab;!iAV=|6p6Q8pke}?Bsht$=oHEw^KTSjJ)lD9+d~mgcVV}{kfw5DH01>7g z{9G|+h5bKc?6ZoX_-uRebIN_**cmxa;8>k&7Q+&D-q;JO@fTF1WbE6FEt7J)|G;IB z^8l!h8apeLA_A?4Qmh9!pc0k>)SJDo9&=oO05U3}OVm4cT|MRiMWL|)MS-;lcWZtX zW3Av7w&v%q!U!p3qUMM|F(*6Zyjv@*MT5pJ;A-61MPrwYt*UsLy}*??I~g@MJy*MK zY@@UG#m?Gsd+mg$x1;a0v-V1R?H7!_)L9#cwS6X++iS0C#_jV4h}&zw*k1c3W3P1f zz1CU#o7!vtMPuLISsUBZ-uF9HJKKtv^R2jQ>?=~-LG}Pd{U_OjE)Br}TLHAg4uF9D zC1d}xVEsMlbtn(J1_@0 z+|h(HI(@=e{pW-sv+uh(O2F3agN3mSpqUwHU8x{I4*3G5?b1f=7=eF22c()pSw;Et8 zKp-&h_6DfXYJh_dW`yJ4;z#JF-`MwDpX(?kdIQ&Pa+voT`?A9s$6@a3go0z0=nVgH ziwr2hVmz#6{#Cb3Bmk1{(X26F#NQ$e`CbVOm<(*r@V*u=L|sf6Y_(&;$i;-ePXlOb z6dz!_b}aC(8T;3b{Tni)g9&FIR49fxvX#;+MErw>R`e~DJ09+6`Tew?kJ!KI{<U}rEtk!t%d%~f2!f$xoz@Q4+< zvjmgj^SYeZ-w5B*2zX1K`Kxu8JIDio?dvv)NT#tii;0i#&ON?x_5) zjKw6eq<_tOA}=fZH!Az-yzJk)GIYNVy+Cf~@yqc4qeM&l@3{Y1-?gU#M?z->t=)TBuB{!UoP&e^1{wzHtRn zvAy_XD#jk761qY0$J>iRb3wg-QWoY%@%GbId0oPcA%Pk{tN-W_rx}NDx3NDbr1(!Q z)M!!l|7`4kaie?d5XN$~iDg9nPY8~aHW|6<#r0Asoy<8BsK{gU?NTa5kXc8vQKm3=BN z`&Czl?%m=|`{I#{#UE@D{0!qhZ7h)b*ND_@821@te_gpjd+ukA{SD>5tv&ZQ^B&;G z*23A}Qts!B{q6Q#^!s^Zk^6=A+|L^OMdkiZdoEUonW66Qw&#vZ(D*%~m`208-1dF) zy6pq$oErTy)agkXPNEnpcC;UXo)4Tm?YtT$;Q?{M#~baHM(f>fFoS09w$Qz5KXd#T zY<#j29IehX{)jAo^38G2=T+#^)p=*LjqCGqm?Q^v*Ol2qI!f+Wqs$tS$jo|@-Y$4C zflmV*!y}xMGt|mV6NHU2?!IVQJi8E87HAxH&Q@b5PN?5$II&KptGGYwL8a;PLLJ^K zw8cjFb^a~c^!aZ5k%%@AE%Vv-*W{XRmZKNwT56UNg!a*hPz`>HjX4?Ej2d_~fu7}J zJPFt1(=na|R>OICh{4er7F%1tlstNwiIz?1)qM2UYS>3nT{heE%7Wg^txocsR!`r` zo@j}l3aj|uME0GDguTgth32iwAL~YCnxfi3P0K55(`?hM>5okw^=YjRCZ^7uoMpB8Fof%9MDOdjb0)HGqoV&Hjlfa4LNgMQNrvPzO_(wo?YCkWAIu^7IYQS ziJ19hVjuoSfF|sF`056{wW_P~xO?2^dwlnn_;z#@z>1h{G%jK3Jq+XYLH99%V<>VT z6QElVupJJwKa5!Ch`0t?XEl86)s9P}>EVdn8t#$H6Gd zjDNJXviqa&<5Fni6W)yDYJW+M9YnJyrMy9-$x|gwkQUwTHP6RH&1R<<`)MXnRVR}t zj0t`Cp%YBaUi?c~HqUGvuQY%X$#RI_(0jBEX6!}(ZlTTY4-Pi#HO+0xq7u)zr^*I8_qEV2gbbuTS=JxmB*XK z^FKWh945y>1P_UvU?^*(q@d4^laHqEfR{_3(%zsc#!ts_e69+>Kb%K?0v}f=?OWTlw%Hq7OSLMYd&l+bIUB4_G{* z3$=4iH-QT--Sl$1AdIfZZYh!}T9x5gmiU;*v5B#1__dd&CQeL@Pfr|`ywG+@Cm$}Y zlK9|Os_Qd#p35u}$J~-Yh^Fy0TA%(Aj%OpNKAjOJaKD~Vk~w$n*cWsT4(c`ZwPl_2 zdi;q)I-92ezgTY;K`~w+GT^f|a4ZYs8VKvPkQF(ZsPSVtBCdEMa7j~ySAH||DfANk z0;VVT1n0OwQ3-XHcouLF+zEcGQ0p2#z*;`Q1tbsJkUTkt9;UI^*B=5rOV3`_wI9p; zV@tWnmcNoqiqV7UDxohJ`&)?S7w}n%1#*!W;Gn0+?eI&%n}B_O_DEY#Ai|o?N89-2 z7vL<;Wj80#VnNprE1`+x#1HX-F&uRF-8OtysL9=OH=Ok*rKf|Hg}N9`OR@q}Oqxr> zQ*<0q`UzEi3sF2AP4=msn+;$$H;01(!Uk78&?Luk@|y0TJ}VfA*YHl#CAn?PiY&6C z_b}LqZ$Rli{YwY$zi;iOhdY1gQ3d}#{bosSV-{pAqY}xJ$ajd&V=72s(%IHsBZ+Wh z@$in^JWkw>;*n$K6craE`h{o`S?Ah_W&>gC(`TlpPfkR99U}!Wuer##mh2xJPL6R7 z$`l=RrY`9HN=r96yay$Fq~ctIs-%KW)4R|)?}*eb8sm`9BUqo}XA=P;H2b;#ntqDD zUZF3SA#K1z6s}ruX~EtCn*1bN(GgI5L2o5FQJ#h46#4U%(vPVupWu-){enDqL!V~? zyYc>-ClhLLp6Q58wk|0qUy<}nfrgIuVmY>IdZcbwB~`qctA9+LQ)g=KHJNPATgix` znA%}>7CQJ!Q4)>QeuJ`&>Q910;p+?NQ$9o5_`6(rC;YYXfj)~E-N|`Sh6%#E_?^Vg znvUQH6UQf~rm@WzlG{+TO+f_v&UNv_d)!caT$>zV2QNsRa%Et6ou&6*5P6KX&?Kvw z;kuqaoeL&To_coTs}0PV?}@lqg0j|z!J^H~;jTLXCK2`ChzD1^Y5kQv{=}Z~g>r2^ z+@r_3!Ox?5K!WX(pJ4Kn&EzjK`Af~@FEjZo&E%(;{MBai(@g#vlRTR0H28JIWR1w) z|EuJ)ELI7H#z}dyxHiARlHX(-9?SNU-)fdnrjs=yLc}-^l+Pjd^&28w+uvr}8#F+; z9zM?=);Bu13SVG_8?rOF_FqJM01&_%B`tHlGaS(QrV}E;?=bjX2E>5%J|85W4=Mtq z7PsM88P1l%pX~dV0TIf5EQwf!Pf|93X6~I@jYUll9^o=tWxjrQp-_Te%#%9LlPa|U z@1C5qz1(qLWGygWb6MeP>q|^6zj0U)GRJnrU~hpE!>P{EauOV12V5&T0^V*zVdtS> z1P*rkv?wcsK4M*rK|O~eum`bhnUcjNyig7nr2u!dkV#lwvYx!%o!1bhtn9d!oWnnt zoKimp^=!U+YcK0YSq1!3(13tnSrGTqf}OizBO|XG5th2zjXd=Zu40@Y04$RqAwc1C zM7MSP;HyqOU44bF0v~VVr_c}IBNy-Apje@+s|(&ocv{s(2lxTFxR1a)X=C;~B)9lx zZo!pYlZ(1T=y$Vv-qzN7qjxKML}~uZ2j!|Y=-pN*dTl@5938!P-3frp?*AIakwuVdyL;Mni& z84yg+W)Qwwy9*PFh1&{yy&<&VSe)5z&7LbK90v<(>kap^3_so3->#9a z3e{I)34h1&s}JTlpRaf?FQVYw!K4d;`dzr7ESMVX;<)6>%iw&-T!_-Rc7Q)VTfpP0 zpvxgRV0FO^-i6*LDdLfCV-y)9N?`w2)QWc+UB(;t~1#?=#3 z*(+LQ5HtDF>45knDXdi_f||GwWDtv*CGLSS8Ba5-sQ!grmyoYlxq5P|@6`t6@9t5R uxQ>{a7}q^0xX~?;eDt{crrs01=qRCSyaz}%gomTeANXGG_VyG;4*xN>mwI zbo-8wSmd8wJ1%ejom3@RC+~T5Dy~YU%E?12m4`g#IWKw3b5bckI?nf zP~*EzW5_i3n#H}QIcye(O>@L7j+o{?v$#)7^qa_&(S@l&_TnLXQMYkBt~cyVHEcF3fj6_nq;k}14h-CAwiwgVYa4Ifcn^)YVZ2S_Ju=?=#(QkME#rOLc;7MJca8Tw<9%Sf z4~_SIkM}>W3VMm+(nMr4op=Y?F;W z$d*woE>)~QYtJ%{kmJ=OzZ!?pri0mXghD;2IZN$&BSvPIcv;Q_1UR99;ogw~1lBrJ zp1)jaHz?_$GmgsRPCM}Y$SD>(+`Q>D+ctKVe8;x@YJIuxd%_Gw{`|BwOGb)dbvC9* zdv=cBjC0U#wPR-)YoZ}tryyIW9yn86D>EdETuEC-(~K9xps_h^xj0nFXYD%-SKf?{8G9 zv6D8+lxjPQpcnh?vz#a!if`c z5f$^S!m5Bc+QLQK`o*P3_11a&CD298kr>9w#(u?f!eyt1Yz|@~rHL}zCSp_*-3i5@ z(uA{n{md!8v4$aM)=UVv=aJXfkbh8;lA_M_;eSe%?gAWKS(kbdZi7;9y!ZV*mSHP zw_A>_M)g*FUuHAuHQKzKw3())ZB_zoTxj^x3PM?m}(&L@)F96KFXU8GYM&0)5okGO9Yt>3Cpnmt`n)d!WJhB2?r+M$HKEXi_nt5?H7 z2Q-~;rl5^F`_dfoHwterrtT4`05>Wz9#SxK_6!EUM`B^{SxiTt%Tl+M%YC0U=W zM-_m^mmBqJjEco48&sK1OE?ef)IXHqwBcdYpf>i3o#wgwZDTuY9;-kKZ>K>f!X+Cv zpvb_)nJ23^D^O`^flqXuwS%w-kqOa`W#eAxU`}T4_M-;9G5D+sB&nTaZ~l zsA5QE+OZ4}u9TytGWQ>L7W50s@ad{}~nPRuZQ)oG>ZC^pcPBk)lzc1^F zT8TSW*ouqGjY`eh-yngo*}`U^V~u9Zw{E{%zIOBS^#y1UKTs~X3F_+TXvGm_XFEl* zlnh4;Is)iyQ~GjMDN^BSdy&det9hXa)dL-YitO|SDS%NFA>4GBne8UJ{h`J4T8Ubl zmCiqqos6bjF zz(vO2n>!JcqB~REON!`5JIF|0+L0v6-YM-&lbx2PyNJ&2NR(arG^*^oET(KAcbw&` zH|H;xo-r%zG>nA$@@7VB$4Pl_-o0_{8y#Yl$4mkReE^MC{bD7mKA5%VK>ZrySX>U1 zV60T*b_Br%`m$psxK`RL+{L1-GrRZO73jwv&po5~~E9{N?exil1c) z!0%&Y%3^dd0J}p|fb%ublLmUz0HD5R0qSc2P+tRp`WgV#*8rft1_1RnFq8)Nrh(x! zFp>uLrGfovU^ETDLRC5k)4*67IFtqsr-37B;H5NhGz}a}1IN?Ai8SzX8gSCUNgDDT zpK;ph44g^>r_-#7wD2ow$|O@3rV1GBQXL;t=lD-e;S=}ZQwo7IxGAYwNHZoDwAE^s zvj|~b89PZ#K&SXy>Hv->R;^f;#K&cV=C}iSJ8{LR8YghTeo_`(8xyT{BgZn4hRB?N zM=`n+uqPZSs*|9CBH=hiRl*98kXYbWVi}^5E)%~9hg9!nRmw3{t7z#ofvYf4I%yKi z$Qn-*xaf7IrYY<=$d;3uLYB%VOAsB20-5rOMaQv7Cy5h7=Cof4z|v_+P?L5mg+f9@ zxleJ86i88sjskc7vfu^|IENowVHw+bS+;Yjfs_knZkjT`L0C?JicUAxMwvRpu4^_#Vi=~!cxeiIx_ z%X}=Y^mVlYJ+;fM7EJVWgE{tgOVdMUO!;6-!zTJSsXxL1x$IBsGk2d^*-xjM{e^+2 zjqQ!5ENZ8RvQ8ghxtvF3L5VEM`jgpmxntUCd^W?jx)-?8u|L85Cw>#(2Nb`@@bO2syx6!ws&7P+R0 z+H|>Qrnqm30oKu$Peio{HE60d#du94QwNa~^8-DL6%W%FR-~7TzDrc>a{S%%{7_V5 zHVXZ~Fr6C`SPAQa%!`b$JIZn#bGvC}srvB$wd2YXj1<Hd492}Ciuk=!s= zasj^+d4`7bgBnMyfImaI{md;4=LYj5y1F@1?B!Kb`PXf$JD&+UW(L5bM;1-atRO?z zEW!nbm-A*U)dVQpYd*}WTEN=slL%yzi>r_BV3dr0YBuJLcf!owzi75{28tRAUKxZUWQD?L}0xi+WIoKT;>y8}CA{ey8-H{{Rk(at7N4q1( zvIshPTq2^HUdGIpTsr40rShr%BKH`x=?Aozg=ATQIG7S!C!OeV14Ap)@r+?;}$y5eOYE~$oWsM{)+ z=^7G^P`83ff~v10LAAh4mo}PviER+w`5Q>H5`@bSjt6O}%+rSoT2H-2E=NW*M$#Oe zP1G{lJE{bs0p;u=5z)_x4P36_f5*?h#mdkI&;YpuSoK`@L%EZ=m$2%G^89mlm+H0b3 zB?}wNo&*31WX;sXsa#NXL~s(k2Q?tEy@fE11V!47F3IYY2D@%68p@FE!AhR zb3}b?^$Gb=6TO~;`lz96eWrZC1Tde5J5kn${gY@QB{68q`&fDf+5ii81gv97(1|{T zb_>}<<}s3XXX@>+iT)**sLUf$Li9!Sw*tjb8qFL|E3Ba?%qX-WsR<5>kD3*jQmVC} zufXwEe>&JOzeH)-o_yAdCz>l7$$Mi-;bcaSn`k=!7|I)VnCh_L6=~~b6J1F&RG$UV zuv)OA(i{_gPfEd71Di)v9>#@+Xz{TcHXO`u(%>m$KTheY&Py^*o9J)S4Ap6}3pMM~_so}^zO{W=rb27myJg$@l#N=S@J32*`Q4LO=LkJ0Ry!7Px~ zWPXp6+l?P{wC3*r&}V zwf0dD{@z_X+6x9{tL08svfK-oe5illDa#?Yp5Z9`o4zRER*i6HR`#>h3`dlER%VDN z@oWciX2q^wxOK<9I=>(=f8qB0RSk&~RFErdiX@YvWLKAyLh;b@texKF$q73tG%O*l zgq9w~l}JK0h6Kf1B7yAuLTcgA1Vl#1?4wPYbse$2NL^Uxy;Hh`}QFe-Ztn2c#z|Xt<+~Mave5UBg zbh#Z1Nb3MI!4vKQX3)?Q?9g1LxzoWXF1@sBAqgbnP*Ws1CL&7-PcC^DY*KDkRso~v zmST?t2Z<#nM`LpNBJ#T&5Q&q*JwyVW2!%aX&{xzBfWG7cN`}6~f4Z)hJrY+_*xHoF z6gIvCA}(>2OKwG?>%np;7MNRNI$^9BdkOrCiMiNzWeF#D=sz8{;%^aIZiN74Vj-%i z0bey>K}u!Ci@FSOTC2-|i7lBT05owFUAAzbb#9t)!m5qX`Yu})7U6o*l>-hQ2EvUO zZI&?t?iF%Fc@}q3GfX-!%+L?O$(R!CEEtfzmhq?ekn|y&^d!1;ISL8M6}y)9pslRK z8t%-Idza-nfNG`76ega;Zj#leCt1OIl)z?b4Xc4pE}6docW=@-`@B|WC3Yoj$5KL# zepXN;I%$Ul6fI+%DZ7niv@0>LT2Sa)o5^~Va+Vd?@e~t_2AM*_XT-q590q+a8nyq# z`uVWAM8$rrY?pW?%ZlGr{Hzo%1U~UiGT|GTRVnEYu9ugCI0Hym;ax7oS zjUcxlKzcuNKt(7qr9bCLn3RWl`*H)hy)d#z#N_VF^&vcnZ%^(p{_F$g5&Zgc#|wJ^ z!3od@^L_aD2y#d98_bO&HiYZy2QUuw4P%^J8-TJ#0b~Vj zVEbASUqeaNOJ=gDN}$GY+xT>h4>4$7WXLI(Du0y8Kjp}iS)&dH?r8i8-@kzDs7oFm zL~#G10s7J&ATE9dbj1^A1A1^sJ$@`Jd4~Xs+1nm=xT_RSG!!W#56%Y=t@Y8ZfS~~F zP~QM7fSSSyQh-z8W66duQoRENrznni0?)PXUTF|DfSSlGYz0IJ8UfMvnVJGirtLBI zS7~98#3+pB5{e45*G6*zV2w5c>?U;x)^Z!)Hr^G0nsu5#FlUhkwF5^ba1HVaMKHl5 zGUDak$51;`GX=s(g@$EDOk)15zNqTzhf@QIX3G$VeG?t+I*^k!P{WfLDZ zD@V)v)HBe8Q~Yyy%p`Z4L&k zL4a>seTiuY!{qPsfYpzCVI1@lO#=-}J|t?+cxQ|UG~Y{%>b+{bB5gQ^;nuolyz9n$ z+juvO_f=EtH?Zh7KB5sfcmD%(uV7%;!Pnz&v6BUuB+)OWi)aa5dXuKy zp~MJ6kti&1P~l6%w4XFFI)`>Ik;cj?_8K?)5avX!eMgF7alkpo_%HMLdsnNIHmv#I zOh<`B1RLrflPcaKswRp zMMqjLp+!JFg`bw*=J)g#D-%;JD(SA?(qeiBOz8w$5GVV&j0k}1CwSVL0ZyM;dUW2> zclP`>YLA5FoAoN3QQ%W>^L5@kLzwQPE4=dKhGER+%W<t&+2p^%64sgIL61h>Q_5XzTPiJXCVF{KuAK=gxUCjcq>=8!J-7RC?`n3q z$LYA0UO19FbrTkhSV1^rS#Qju*0kmWe=Q{+WsRG~0xl^UpIz(3t&s+8 zN3rZO8n~@Uy(Fg=asnVml#m1k&Z@i0HYql^dg@0m_ZRmjKVtHd-?VtS9X0f9Vutw+ zKOHzs5bR#SM{Ha2*9e2!HYTaeTq;Eo+DcSgmqR|cktWf=lsx+G<*Y!A^C`}Rob`3g zHZiKnHm;dB)RtPWG{ne+yq0C5mU*91sxV2Es*Fss7{v%<2X$?w2cbIPdOblI#V|=C z7XmK9zW}y(%V_3fBKp5V!1Rsej=}O7gH1CwK+C3(8|W3g2R79REFZ-4{jhvS^9Nut z;og$`8OR@oC36av%!$Im+;P}9hw#(yDTHW|k=E$&E1&`EXLljDt3bPHP|}&lW6Lof zT#7}t7vC@B5A-BFz^-#Zhp_>)T}^GJ%wGB#m4Ftc+(7l#Z^er&)Tb5sa`4dLn$Ri1b-nPwd7b7 zwFFS1jvQKmwEZcw(a3B7erdtc{1SoZYk!Voam_((Xaep5TxWCJ$IC74oCL>pv$hg~NNS0~|A$f))Vy#D7 zR2+f-u4pA>G6=X_M6D!m^S;ekl$c%MRtF3#+R?B{q|(rKLD8+l(MPM%-e^Ac@FVzA#k<~eH?Q=0o}ef_Za5T)6p!jVl+yp_Llk9%ph#b%ls?~c6eYJCQ7}ZCYa5XrpS5&obl$coBcI`MixQzQW^YtnQF%1r^x~fw7teU$ zqSa{>biZ;beTHW)N`VsdiMKAL&-K_v3DaQ%*0?w0wwu18QTCqi$xCN^KtkWWl%Dh9 z%eJce`bD<_E}o}7f6)pYOd5shJA~4UK7vtlT&*gt3icspuOn$8xlCGl@=?tWPhqz4 zm%TSBea;6lN|lQ$u}(T2=fUMO8Qt*-M5phxIlFkJ+4fA5QuaCM(saTUb-j=&*-JYT z{`4m@ona6zGAkMLMSFB-oxr`FzFsKiqLvhC`+wswi(xmRe z0dV?qru0HjXOt8-Bss=+xdvYJ`HWo57Pnzp4!z4|IrA(hw{;OE%iSIc4vYA&pwObs zww7HZ!~@1kkfn*<^lNxIhZ9|>Cs$7D=TKj6;<+C&^gH~}iWcLhV-!i~xv%}pJ%IzD zV*df3zI-2UrqRAG;6}~1AJfv`t|TvwcbD%@ds;Z9|72d8&UVwhG@SCnG6?s>Dj&=b z<*f2m!QixM%t?VSv|T*@q?w;Z--;`TRC&vLz{C-mHKIyHU%eYYj3mYWKCmjih(V)}}RUeYV%Z_#Zben3n#4vX;z_cryuRZJvAX-J|BQEB&dUjPHl zbPxOXkOT#mE21ikxV%b!h!@^C+bpt3XbGrvaMp}q=D#38>+~>Kk zbH4MqtpCSc^H+C%x*bdTSI6%SeC;ohBqBRVJ=yUjsYz0oUQKq8arwIJ)T{i2>`Z8W zLVAG-h%WOWoHrPrkEMo#gb0Rmm*I@ezLQ~#cj7{x$;L`dDj-hqT90@an|ogX|mB_ zRrsKrc2iq4o45Oep6Q#kuzs;`{2x~R{q?6huKVTqcl2 zlQ)#ix^i2R4M{Fb@@+}3NODz@wd+h)kAuJ7B#mRU!kNbUTgu zX0sqC4D9!qmdEe2!7no3^gAZOYWzKunjCDF_`BVnVYBsHiP?>Yz2Y5z&0ew%j6XDH z(B^uS=Ape@*69)k)(n%ZU24pv|2m_9{rS=;uZ&$mRw&3>ag!MgA|0El{|epv&GKa+j2A${E`>&bxzR z(|*VuM^<^7TPoWff4WXwcgOhoFm+7&R2R(DF__Qzi5YLO%OE_+O~vq|2|q{ukB7b9 zk$-O(^}wQILd6Aub#-ZDvz8M?DI^=LXCVeB7m{rF{)hWrTMbJM2$E5;WJoUW?x~9> zV&h`-b`;0P+IF0!MV|FG?cbrnNzIY}F<2#9xBf@(-tzaMrg}Wqw!fZcsaeO7s^D*? z*{Ja?e?1x&+4?4VhNHT>m3V!i%B4D3?iObT1x5DCEe4_-oAu48_aHj5%5)$Q6PEa; znz_ZL9U%eKAB%*F`OEer#C91Vw#xvqT?TONGJtEB z0r(44IG3^2MIx=!NQw!TaT*0h(Wxp3pOy%tAu&=*1jSH6(E&{804A&e#=%5YTgiQ) zlPJPfYPp!fOuWjF6H&~Z>=u*As>Bsk50r~gr9x?xJQ+HsQjHI;4421KH&I$Xb=z`rJnUGtA7PAI0E;6fP(-JG~`K5JeHLq4re6)nKsuY4>U7TWhUhSeBj9w zPaZ3O98AcuC*g#ojv|;tTMuUBaZPY@2TeIRCC6$~Vj9PGW#?J3|3FiNm9rIvy3FSP zuCrpYIT|1+;tr5`T-W+p$$wL3j_Y!WRsKebc^WJz!f;&qqNc>O_X%OQS+M9Sc~W=# zUBJG)hd-`nTa+JuwkD5tK?e)f>X+mgc918BHOW`J5ALma_;-gB&gj5}YC>gj+F)DC zOL~F9izpY=5T$KeAS?EL)+$?88r6@Z6mSka1K_Mdo{7Bxo%MG61hLnBck6zCXcd`C z^=y)WhGIa`P^NmCFa7m3yRKlit2P4g%<-{Rc^s()$M4S+U6*m8vEv2TOz9oTs~Rz* zQj0=S&|a`Gkzt}3C{vSE{2MHwC7>aqN2OaRc!=X@i^F!7Z7CdK);Um;w02cDLn0Dl z0YyjU*NG2RQbEkgtU}EoD)u#Vkag35i&E12kqynmBJ5|$5Q-r{y##e8lq|iz^1u{5 zDn-|#Km{)|xxnOgcBaj3_hGt^0EZakhO5+T^36n_XH;!-ba1444T*RQwRvx;zU0l< zmb`PdhBsS#5m0c}tK&0=QUkx!^@g|Xo%3dDtW`+hN=K0J&p0LUCLsW<4w<^H%w3a% zIz$lyH?a z9{#x`uK-1E%Ht_1&dR}ya?Cx;W2_b1n^zQh;2qWcT`?WqFN}3Z-^~OIUzMIO{a58N zy!K<9E1(s(fx$S%*R<%asjKMUy49vad_qrYUfn8(2 zH-g#H$bhj9+qLo{{kO0BL^;@9eFyk7sue6s_*Ipi!=CLHp&fQgc(PsEV`>8x3?JS>?;F^62umbKe!OquL)d&U%x$-hPU;_Qtl9ROEm+22op~_K%_xt> zRr!68fteV*iM|SeNmN8?TwlJO#=T);E?-omNDVFme6=h~@F@#4Utz^#PHMCdJ_>&H z-tC(j32`P4k*UV$tg`W`K<Rb<^Jf)H8bQ;%J@{zVyCaTjyr_uVZh3R+_ z`r&}m-451}57wDbdjyw|I4wt(3suXh0j)*ex#}FmD$+e=&Ea4G(t1Ruh>9W)2>iO- zZn~QR84(3aEtuy-ohl7nJO=6!;u>_}yk1^XaGfNonA0wNG36ar^rJ%)mO%zxrwh+O z$C_Xj?W$n4L3vKSF`X{LI-$U6%uuzLYzKpyU6ef6t-h%CcY(Bk#(zLHAKXCFqGEGu z`6_eQn5eGjDXU>p*-d$H1y#DeLvy4@bwBD2%f0bb%3bIgk7Q%CS)M3*XoK27N9B$2 znx4bR4?e^&MmX&*33&7Rse7}~-V3!e-Yh=U@AJ^ zPkGbcsoJvFoLH+hYt4xTj3TYs+KQ%A-jcUmTkz&UCng+`%_$$Z@U{PmnmyS(knH{f$vPNa2szkmi`TJfu#HsA&$pmOW zC3(MUhXtWEqXnQeD}ygo!6C114^0Ml>btA(B|-5 zn5xHw-q7H%bkv}Mwsr)e&dbH|ps_)iAJ}&d4mu6qEp-7th36d+ML!E(C0CG5nlV#; ziICg)st%zsqRayBaQC_0BGzxYL6)L*ItQwCV#lFV3GzI~q!V*I@`~eWw z1*#vXYE!j9#T>y7SI7hFW$9ixeyH3XP+ZlG-a6wdxTP-MRp76wZxzrx45(BUp@Z|x zon`Vd5>-$L__`1fb%m}^aXQv|9)DPQT4AV~vBgTof9;5%8(g}Kb$`VK$R8j+vqf#2Re?O0+5D0ul(e zD5?VoXmz*-moFCx4FOoO0FcR{a4!(&Q1AiV(3qbf?yx8FK%Yw`(vXFxidL6b2cVAE;p5iWUBolGow z8g7%@&b;K8DCXRYMq@CnTr`jleVVe$_bQInifXJ|t11@{3Iu@Z6cjh=R1SP1>=F)+ z>xva|Lt5a364^y+u-d;ePO4l;pVzld@lM4q2ULfaeE& zrgi35jQXI%M6JG`u^Z{fyL%Li@yIG{JOx)y;sUbTL#$jQ_vDr`EuwTYB#RM zxj4@$vB4*x@Oymq?M7fIE!1FUd5bj~So5_hjz7!Qn;rv)taSeI5@&D?p4EaTE$X}i*i`I&K%E6QS&5%sH)ptpx)gt(B*lL zm0bB9z?9{>q(;=Md*^X@E6(nmLG1|7PM3IABcAmk^bjma4)6qL!Se&6^vevk%qZ1( z5mD;*cslG~mwWfio(W>aIQT??OY4DJ4EX?-s?Ojnz#&XduqV+5NQvoST}|mM|5z2L z#YY^9k>Iha3j`QoVWYHbNeQ%ZwLl$Q^Q2l|yeZH}6}l?K0a_oyh@GZwh&6BD0f?|P z%aZrWGmzr!Btik@)v4xE_uD#ZuWnqUX2ajv8+*I@cm783ZIm@&pt6r}h_mHrR+Ith z_S(jkUB@W_JrDJs)B_vo+l{`xAD6ys9{fEz1^7P8MJm~FcU6peuc3NvP|94i2bh;vE=f1uHfw+5_S0J#v-G>TzBj1olUc zx5%j%kwHwg0nwhI$21S2Za`lzO}_>oY^rtv9#q{sUE5MQQBzri&H9MEWv^f~UF2`{ zp9vf(p3})wcX{9e5%GCm&K*tO^a;(%h772m{=nCBN1p&qM$z2|G*7h;s5Y$-K~y30iBs=AK174pS`fVcWj4uguXCTZ!#<&lK_8E`{fIlaw26!y)^fh zXEgxX$+Dh_($VA2D;&eHOaasckT!*HQ`6}( zWi7tiTIN}<>hMm{n550qSZcHy+l?!;-))?B?|qyg43jLzad5+7n49}B9`WDf!r)z0 zxM(J)S7=9k7D4&l?w)EEH4IPGPmKQ;5)j-qpng&heGt+i)X<;$peJpH|9#H7N4yEn vNAJ!>JqZFQ9hHC@MO^bAa;mC~uDdtH?{iLd$a%VS;%HGWcndImkkwkap z`=h?h{_6Pt1wQr}hD78TV<5+YBsEFulGWrG6F;xZab4#P$r>_Rk>eE!_-sY8ri@nQ zc-60)lC8<8CC4qSSLII-yDrI^m{l1-a*LGbBELP};2B4qbt>>nDv(+?acO4v`^9L~ z%ai@nNtz|=>z|FrnHibf+0dPt@RMp^xThQT!fL;5K+K)bk~`^t@ORh=uymUkhQ`I? ztmg(rIr7w1P#^naJmEDE=8}Isc4?7+T9!qr#-gAaIqTfw(J)=QDf=d`{3Ck6vo;a(Ww)^{b@ zm*fFGmvrg2WL<6!5CZQ>^1dWHl3bJIx|jx?d4mrgO7ejuKbGV}8E!B)55+YY6eehk9?AY|vLE670iYexmQZYZRmX{R5)n8x?JBbat z2u+IQD?@v$;;wEORz~RZMmS+fb=xn~v9kx7G~QA#T5q;t$>h$A#@^)4zJas2E@<1C zrRV&X*W!`gyf>P8X>94|%CaFJPn{avCmrTRX~F?OC3NY?AbLk*T!is!E=+&odZ*dUGRA%g zYIT)Cnls?QfeDX>8qSpC(qIh7J!sfbqX9_nS)#<5$;RF4_V#s9GK6c`d)iAgoub`8)Di`+O~Os^TwvUQo_gV`}E{2sV)NfP67Y5OdY-5R!6rcho6 zW6VH|s6{l_XW<}UCa9D(*+8-WDuC~N9rN zlyi6vJ6Gg3u=vJTfxtc>Crx=?lX4@1hjXcz$ zRc%I5@SFefKQ=@3%^Aa1#em}B88%t5&)agoBjvyKfGrihEnoOYt=V#>7HXYmJP3IC zWwo$#aniNwr0W&K#Wxt%X@P}dDkZO1th*KK*A?q)%CSom^ZvWs34M+_O!PxIM+D8$ z6MS_QgB1|NA_r(Junsx?B+ZlJnGHJ*XgaY(pS}GD{URTvLsYA<+hvyTfis*I6W{S6<Rh^&pY|ptey2edBgTSSe^CHcoHYgF3 zB4Vqhjo@;Lbsi>NJSvh&W^BY3FjA!mZ<@)#*Aazk#};Wh+Qu`@=~=Ng<<&Em_f{xg z%GY0krob;jJ7}-8gL<%8e-qzZ_}n5b*u`u!XxG{eT`BF&T05BMG7a{aa;VzHZ4Gek zP(S(It{~YM{1^j9RPe=?Jke+(W*_?AbmrRFPEOgjvKzN*uX2)Cge9BM>HSfnFn4up zP;1D)z?bh?o4fu>RYB1!5woekUg0^jV4-*P4jyV;A~Y1!E9d%#nhw0Oe$fMP<3Or7yiYRK8&fFIh%=`G~On?XA2&ke04mr-O*AZ*RXn7h658HW35m zWn1utOzp!XqRkcCa4*UinRzcB(d}1n#XDN+2)D6f%-cD>bZJ#1~D@Ad!M{rXn|24x&4 zMISb!W#YIrPgAxQaU9(SA$kjgqr2w6vF!8bsR)$I^gdq0B9AP;072x3oy0RkatB{3q%pquO>*>ba+ z?kdV=A}=z|J|8fPEVIaVW*;D%tnw9ECE3jfOwPI0O;XNFBT+2Y>(=AmQ|I2Q>X#Rr zpFeuC-&4h36~8~g*Zdkuq|^aYPaSwFs;H={l8QP&2LCmcRMn`a4rSOdKYhEe!%Yzo@*>7LqB0lFL zVq+&ZPRwpE8;!y=+U-u_BT}5xI=q(k!t)h3-U`ZWRRkTbD4FJ!Yiq=*1 zu8J-xU03~@8UVj&y)2kpQPCC2G*om|GEEh|AsN7NLoz_%rerRv=$d3!Rj}WFkBhm7 z#35)AKe0Cc#5g?sbZUnH$qW<55XvI6L(G0?X|k@UEQ)j8vspf!1M~G^ZMGn9^=Rzm zt=YyXr{u>I>$5{fKo>CYPItyRAl$RYE>S>tCj(i)z}!H&u&n<)wnJYU2XQ(8`1@Ht z3W;_RL#d}ltZ(i^jODnSl(Xn#onzOOY{!E%%eCJJT74Ujw6Wo6Y;K#ze74+ep=SgK zW8I7UPykMEi8J3$$J$(k#84;WowC|oLrsE{=!eH)oP=FWF>C8ltEUdb&rt!y0RJ6< z4l_WHs{vwM25@nir7}}5GXRYz;sA~71JLjo@r>-nNK~8PwKbNrR0nmI=6I$xEI000 z1}L#DlnRdNzAW96~_9kC?2gSX!oee z;b>gxEC!;M_e7s^?t(Rx#W=xL=4R>@OPbRLTPX6l{+}*1vFoyEDYIB`&9l>IX1RHT zoG)pRoH#%G29|2H?Fb}*kEk@4fN0Sp1?%W4w(Sjd?`g-uZHixGgG<~oiC%yin>fXh zOmUp)4B*v7O=g_L))Lp55l1x+?a=74BYUnykS595$=-5Zfc7b{{fN`PiA2>KUbXlv zSJnWxD@d<-mpuU;)g&&H{l7xuKnGf&i3>01sZm9}1e#8OMTah&>{nUuLoz_x9HYRt>-2?su_Mh*_3-g~>JW3|znu5zf;s`< zF?dCJ&wi&K6%dC%apM0_FK&u>3*sB1>}F}6434oIALc3Z;_`0(t`t@kX2_C z_VO%XpkN8E5~Qx)a#H8hXVll0=?NuSgOFw#jvVbBhsng{WZZLsjd;ecJNPj^5|UZ1 zy6zEKYu-g*Yr|WsY?wC-(IdfYY_#jjA?-;uEZny29FU_``II1_-{rxo(hi@&hx z;p0Ei>g<0fIMJ)h| z4%R$@&-^$w6ZmY2f$4|E$7cN^IA(Bz$QUMyquplHFaDksEc1ko<6N7`2p)NgY<3(o zHV%y+(myk1_noKlw`OqI+MSK`vmr(R5QbUg3xP3~XE-hqc{p3n{T+nJi8kB*^P!gY zV$D)B8!AL~yQDv&Yug1vz;Zu>!|mDI3tI@n*eu)`<{`Kr_az_!JtB0XZsckpDnP(L zmHFSF&3c45-Omxg=c(~CXfS_{f#(}EccJNpt(V#uQLd|@rc&c>J28=I?jX@&Z|G}x z!|`E}#X&?m^h>R9jy@xb#r`5MgYrVNC~dxp{__R!dc*L|nP2WiKJ|B7qP}}(6TQ1( zR6t@XZT{9Rv-N%7+~i0h>M{#^r#8e?^T-rlB+Nquxke%;iCc|Ezvzq$C1cGON*f|( zVTjvyfjCWjd#^1{ofjZs7IA$H2gSXK2E^edIt|`Nb?`3Rsz|Utk>J1!93?K5?Lbqo z#m@6Efis?mq5`_T=bV$aRn0YczeeSvcSC+#U?}>-rgukvYu;*6BmS@k39jb>zUCt& zbYI9ie~5SqZm@7KxK=*CzTll)IOf8xXYZ&-V6lDi?0a$}l<>iY2=p=Gc&yW?&G`b- zbs52ShzBDPDRd&G;6B>VqY2BXWB?ztcvj74s5EqI3K3|nQU_sQng;_jn*J0W+~%2r zso^1u{cC9;NgpiiA0Ad{93AO%%aGGN7S;w;E|FUMP*6p+@)6@qusBGyAXMlJv1aL_ z{X&5>#-8|FlTC0xGNzB3*N$1idnG5yk-5F?Zxte2eu-={D4sFoaiOf6^MdOxw<@uM zLp$N*Vn410>J%deJOsfulN}~<3TRlll16iki(z?DlOcm|voj4Ed>6^Ntja?}tGeZO zIJWr%>daLnyzJAYYl8P`rCEV-$#g6D^0Fhy{t}rN|8$P_Z>Mc2H;&hB_>lgM?hY;$ zPf3Lh4{1|AOI6h-!a+L7(m5hplUR$M*tu6ki6Z8~v*JX--EtDtx}t=FFWntvMdCvM z2yg)Q;8szOnU>WFu8l5q#5KsPy+jQJ(NUxN3>@oMid^*CKk^Pyur$4s?88E_#P9< z{RadFgs2cL*>fJN7MELhMI(m`HS}^FTHV1-#l}67gxucRM2c{dqpZ`24L)EiiA4@& z);+@8ia8IC16tq~ z+#AjwApiZH=k+n?8;XP}Z#n_Nb;kFexu{%41Jdz1-+bIqv}yT*@nIk_ z=l^{7*^?WKxS5VPnNCL_*Xg*&RTN1Ukv6?NmiG&}mf-m z#(9F%Z@Xq{5Q_EVfm{N`Bh19)$jXDQJAE8@u86biKy3Mev))GprJ1N GOaB7&o1`ZI literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/distutils/command/build_ext.pyc b/PythonHome/Lib/distutils/command/build_ext.pyc new file mode 100644 index 0000000000000000000000000000000000000000..0f280ab0f85a4a187cf63fff710327881564ea16 GIT binary patch literal 19280 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 Zv7(bOefk_jY7A~8OkoN4mx`5v{{_OVO8@`> literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/distutils/command/build_py.pyc b/PythonHome/Lib/distutils/command/build_py.pyc new file mode 100644 index 0000000000000000000000000000000000000000..8382e73389256f5f55567f2128a752ac48d691d2 GIT binary patch literal 11218 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 V@!}9iX$l^17Dl^(-PCO9e*sZ^LhJwl literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/distutils/command/build_scripts.pyc b/PythonHome/Lib/distutils/command/build_scripts.pyc new file mode 100644 index 0000000000000000000000000000000000000000..ec07c2fcd3b171eea58c065f4ce76deec8657ce2 GIT binary patch literal 4429 zcmb_fUvnEt5$|2evL(xZ66ccK7Pw=&WMw5!{qYY#~kTjIEB7;!&(eeF?>{qm3l|fa8bFx1t0q5pqP?O=j z?9cmgO$G}xtjm7gkLP93kl~{2FZ%I<44N`rlKmwKOhx+3lGf!FmR*swA!c5BSbtIe zAo5D&H~Xu!WUtkvnK8}GtQ)&*VB6hdIPBzU`(T_6(!_SlY~*aCu`?VE%+Tb{M()T& zk1qJ5%{Le~qYHUkh1xqi>7DE={Oz^^4Bb4My0T_0v0U2@G%8 zH**r#d5EvwLu241z=IaZ12CX-MGn1hs&WVvt3(mt!953T4#l7NfHW5J$c2bUcb~uSbI{H(Ry=X64;Zv+`p{z*74m+pIKQ zSCnUwE20Z^s%8rm$F1~=vTIbNXMZpqX9t6`NEJo~00N>cKa5)0VP2F5iw{iXvZ1lA zGaOmF2q|-Fx?|Tl7#P32vG+i=Bh$@#XOPG{gD8anIxZ{nD9fEGN2Ng<(K}t*%x{SA zrxc|vz;z;$D8TFhV^2Zk`wr0c9iWQe3-YQe0jYuXLj_22*=up5yXsW6A*Op{ zdPg@JGo)L@*Zx;<+cz-sOtavyv!0)L6ENMwC4McQF!v5uF)kVBse$uNda-NAV@b@) z>;Sh$k;fz`&hZL+_`VIss}R#Ddkx{cpv@4j1eIVum?6wiQ-m1;9^s4N;ne@pszbnF zi!lyaqA_)!R?!RcHP+k$*;@l2F`&JhUxE3x@TRm{sA%$1xVUYW1t~uca9*)l^!wL&b}=>jQGgSCUgs*4s+6}vc(8wi zXPP^~&H!G;A8r^l7t(UvY{xM;QvN+W{Ud$-=*2|N;al*pO8MmlMyoP`_4MnrkaFuf z4#aK9yGXj9oMTr_Nw3O79WBWO|4lirNC^Rt^BQG9#1t=4s=2KsjJ;+kf9hjkucf!x z2JVATnRiX6do)eONW0dV6j?0VWM*hjZ~M(3M_Dh*+@_6&o$?qQ9UFBT(e&>ZT5DYB zfH3Q!U**|pbkaGCTD`2aPBS{BUH8b?Xj5qkvwTvT&HFP|nQ2Ezza@&Qlgu4O8_#dA zZ)jR1Q)Jx!HwKfn^I^~Ca8zrB9f-n9+KYwY39 z?xUSpvw??&Q(6oB`fx32-EG|go0b_#k_|@%3erT48XmLs@fn(FFs2QTw|il=eBrcq z`UM=o%H*J9P2L$AmG6v3CQp5G*POsgMK_R|gYltC7GTkR?mT&1mROs}q~%$HOFm{M zSGA?-qznTUIq8(S*1vBApX$}P)ZSrPj7Q3z<-G#8DKN2#$2QUOL)lKs%o(jbaFvNL z8Tt@OULtt8zH)GFt1)z8iB<9LpgUrd};^m6}kn>3bE2o0C`)8O$%si+;bjo=o8l)<7Z@g8CS zEvuUNI@J9TUt6M)S~FM;YWi&kcY>wxJ@)4+!CJ6{EL{s4VH53@pcby+w-($CYe6$; zU~UD!!l`oOgmT!Rd?tc5p%W#wK9w3gE|qYl-_Ma>#@E;|U&J@q&~cYe*WNdJGid341xhRx*TPzb^=rL?&pbYrdacD-jj<$2 zi!O}k4U!;Byv!_YPm*|p9K07w6Muvse@=J^W{(!U*)gg2D_<#>^wf+JzUpJj>(RZO zQ@UPNbi#}t>+Qo6fS1q+CpF$iUw86tpwRp2C*DO5xT>Y4fF!($@SlDvE8)KZ@H^); literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/distutils/command/check.pyc b/PythonHome/Lib/distutils/command/check.pyc new file mode 100644 index 0000000000000000000000000000000000000000..fd49bfb45739abd9a9d6fee4099ab9717b025569 GIT binary patch literal 6045 zcmb_gTXP&o6+Sb&y6oy|S(fc02}5pLQ?^2d6i}&~MIxm}4g!@^!)T{h8hLhR zJ>6?tl>CD8%paim7yJcy6>kl2Onp6$!&)7|Itozva;*HZh> zd%xZ7%II$fzwe>gf8dje?Bg5Aejr&WSwo6Y`VHA{NWgYeil+2uWPirDXQY^w{+#U3 zNpLdIDYH_{OTQ)iEl)BhMO*p{vcKTl^HMBIe@XV2e7mLXW!Yc$?Y0yv(qEDN6|@(` zw4{fz^t>o4CL3@l9+~0Tb@k2AlZuS zc2;@P>pW?0-O%NQ-Rf5Tep+T*-6PYz+iu_L4+_&arL&PcGSQ7OU9_nLo6(rQZJXfp z>aFb6{NMQN1ZcTAe6D+jzT+G^KKvxbxS$S0Eu@Cf0=ewP_lF?dRatH8 zN&IOk5_d8%9WE9xu*F@Zg8_^tW>pQto>*u4$wv9OFY^u}1 zf#$V|%7XgM>n$OFnwM!1t>rzz==I=$yT+pAlW&sEYjQ5e13wZZy)7$3_y`? z(W6w~xb#|xQ+-oO$S!zP2|pbe%wIqr4XtRe2bJ4t_M99@&%9r4OUD zHc@Q=P$Mq4!Q~pfXHev6>AVwTYS**2YFK-DQAFlp?xF{|JBrdWQrF~KsXtWIO9AR# z?w%#&eo%BaeMj-fyH5gm^F7|JFa%XL06erUH6Ng|jWW|qhlPvor^V3N2vUryfy=AX zZYc!jTxeS-#jl_m|A3#@@NtB{1a4760v?rPI@8orzmt)=HOwK>hh%VGb(K*+slEIOEJ>Y}RK9o7&!kEc)cJkO;?cU^&`QAEBq)7vDD@|T)$2EP3;>R?d!J}y zM#lgJm=VbD13~|28it(G03SlR+hh}70E6_DAj_JN7_rDQt%!%E_x^E4Vkz+3NLsS0 ztGP`yf`JIAQ5ut(%v-E|0fe6xCbfWqs;*7fMJEWDWBRRaji_qK8Xy#E5Fb1?sFiDI z{l)vc$&H=spWVLo@vhqdQ&0FbIH)tk6rXDB`Av{2t%v0Y__1^fX|#eRSpKYj*P55S zvS{`!s;s}G;+2Ka`Y2!)@+g#t?+|=%eEya^Y6zk$V=g2eO7%8%H)-0-jJk}ps)yj- zWx@YF^o_IydtN^BC<%9eY?8_9Yy6 zG-Z0u$=TkHUb6~KS0j7n4CNUDgpEyql+9=?1yH{N>QTSn^=8x`S{EId3035(%3k|s zuG4cr!I^lqIUW0-+~4|o?goJm!u@7#SVkV`>04D1X>@=3WIo|m@T1`E9Jq}HAHRuu zN3%#Kwaj_z`~XN(l^!Zcdz9MLxmp!=2*5x+zKDLsRn_Nl1ryOUR1Hdj*kFLRGpB4D8a+fIfReWTAF(j(I6s+U-MUAhmV0rwDzPYc# znm=OV1Zx2MfE$l3uvuV>{gL{3leZ@LKSlxS4>O$t_|TYemMqx`kc+Ex~_Q2n+YaR(vf$o^IwA;r z5GoL8nvx)Fw6y{S`^r4iMd%Tu$J%p@OMq`KQn~D3QeC66OjBUbiac&KAI%8702_W)m;tqxNQBL=CxNkws5AvM z9&I#ca;y|186?0)yeh;zm-hQNgvql4Gq5MSk|$mn{NT$}Y*83m0IbK$@;a^Tn9q(Y~ zvw9Gdv_~kK-Sgd}1rPEUm02WgzSasB!%M+x&JW(+Ec7iYff5!n9^1^nL4V6^Zn4+~q97+$?k> zK?69^3Rl9`T&vNVX|1+iYAtPdnDNJZ_^78P@QnMw^{T{~=q!^*F}$(XhN0EF!nB_? z5A;;xv|nAp>W#s38eM3%^jhN|0ErXhi_Vs}V7pa=AN^m=cRU)?Q`Dhib%uEokm`0l zG%>R{RRLap@lL4jqfbB|riC?egyH9rr0(Dy|6KJh7t?eV@(fpD@2g?M|7v|>xs9mO G4*vrR`(H5t literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/distutils/command/clean.pyc b/PythonHome/Lib/distutils/command/clean.pyc new file mode 100644 index 0000000000000000000000000000000000000000..8d7e7a75ee7d63f1313fcb233f3feb0630ac19b0 GIT binary patch literal 3101 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 PDhK}8UaOt`y}J2-;`uHL literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/distutils/command/install.pyc b/PythonHome/Lib/distutils/command/install.pyc new file mode 100644 index 0000000000000000000000000000000000000000..bb03fb85e57f2a3501405059d3e9b71e59b78afa GIT binary patch literal 16755 zcmcgzU2GiJbw0DZBt?pU5+zZTWO*b@=F$>HS&8LD5#7X+A}h8jdniRQBW1JP8ImjQ zpXLrNGO^tz3X=4pO^^hAXxbuagSP4aL*M$+#{zu_Q1msAMS-Fy3KT^jTA=;Db7ppy z60JC2N67H4r{F=bm zJ_+~Z>wtulR(Vj)FCCHAjIi&N^~Ki{`ql@u?;-1p+1U4p!F{S1Zg^DA6YA5}6JPA< zZ`bpf^*nAp@x`9cSkDs%^Q44WYxu03k1*Nvb_2>bU}npJ=d9;1-dcESJDA%p;xv$k ztkDf4!5`+pV6-2hn|cB=A7ehPb^nmln@b}^*CzO zmo1O!kaq{O9&^`PwZ?iF&7I&eRa(`i4O)w;VH7(z((Sldi|d`lDHxaLc>-ZIsk+H- zx7X^+a}Efa?Nn>`s;iN6bKN$~JlEMw*4nKToy`gm=CHwvTWiP3BV#_sF~kjbG55j8 zk?3^ibMAq*Uq>X`pyhf?k88bE->7urXr;d4#=EWgGThVM%B}PCqLE+~&|140 z*(B?Zdrl(vagJw6_qP?s{(hL;OuV@CU=hK>jKKP78Q?de7zAVup&0Lb`ux2g`6b75F zNcdUyM}8Ih{wWC-%U|GmOe0AT%a6d5ppJTL)nAF*O@Dd4-U$7$9!IsL9d9}nC(0J{ zZXzF7rJ(XtexYQGHlo_BmFL|VRFrRmqx^QOu{o3W^C4ONO#02bPE@O})N4M)s#5_* zN}6}49vRHqd_jKF_OrFGw;-^R68e)c-7#dcrh3a~o!={${OOZ!TE$!1YnJ>o?>>cb z%w=$GZ(S7lWp;;f^xG@`Y`RAuTbZ5Z(q@!pGKiS~n|Gi11yG-W4Bwr=;H}g4;J0^f z%6+Psd3O=HZ1+8f3PphZyd4p5IA-Tp8%Y$ms!8N?T#i_kdfjc90x{gAm5-uDH-LV= zNf*D_4%ZtzDVN0cWvKsl%WVZ}n#fS|1fZ>UYnB>pdx#{qY?%-j(xZZHK5!bC*t?@-r1n1(QvdD%N>7 zlUHsBA;ogqeG3^=AJ4m!Pae-s#%n69VPti{cnM9YntO_=)%a&RnD4l`D!LTba3Y1Y3I&Fci$T?2L1hHH1bKd2{be%ed7 zd%>T*{=ABaxkoBlt0!~)EY}Hot1e^yY^j8E_D({^0EO0Uhb!*+th|-W z_59Vm1I$f7+5q*cETmAH(OtWH_0Ft{MRyKBSoGsaE7-G#*UDrGsCq(}3(;kD6}cIe zp^&HTIGk6aBbsP-VJZHDwR&xh`>+mv0}G&_Ny#G$?aXRCCw{2kFL4?Fgd`MsN2H>9 zl^F2PapzsRX2MW*D1BGW9C_HO|!n4j$c$R^}vkVlTz^$Ocu~0`s1rC-yf<&eM zLc0|u{V18%9xha)Tq{fHO2L@WVMq_5lG)Q+>P#GL z>6h}iE+iWZ8MUQPW=QughrAiE0w~RAr2^xc0$PBNwNSGKiV8KvQhrlUB-%*gsyQY! z=dzX1Q&A@-pe<`Y3y8U*q^#!LgKFHWK=EmtRvV_s(N^Sch;gG<^GJv?7d2KW0!0&d z8o5gsZkxzVFShM^GP+Ld8m108`$?gHdt&3IX+Ao0A`6vfSIroO5l%QP=Lrhs{aPOB zmJeuo6lFjhvoCC5T#g|`qm`J3ZF^;El3|c{AjJ0B*ATuS$q>Nd*KT}a4hW6|mV@L# zPzQCDDP7H>-Yp%}Epb3m8zEh$&E+C?axim&8BTHsHpW_j|;;>2nlHf>)|fZlRVK~$J09Wq|(c?a(7zyrj>WgJTaSxYn##K3`$%s zviO`jM_A+5c^(dQ*AKdQw!6hs3_*n$bV?o;mGTzLWby^I^_%NZT5i45X+VWSvBU5- zkv!L9w$7;`4-MIC>8J?~&t0QKvzhe_tIKb}I9+ZhYwnYnW}68zXpc{{W%N~yu2oY* z1h)ZUpjSd9ADix?1SDsNFt;nSo%g(=^NB&g3cVa|o95-s=JD=gZ3yw;o7i(*Xl!+fT z3UlT7NYT1%QJ5O9>8ej4~lLL=@JQd+n_r#j}7920tQbk z0GtPST|zQK@U_B_1kfIZnF&)S83ham1TQh^aeP*NLi zblVZ?0(h+-DFg(UZOW>SK#17@obkBQzI3G!Zg=<6_D=TEe#f%75*YHm_2XInxU>wT z1`YfERRun#qtI&Tx1#0E&F^li>wBae;NHO5WfmNDYLE4lTXbq2)}!z=BFsr9IqGgyykE1Z4=AJ{MhN5;zt0V&@^tK?1oawoCzvRuk-h>bS={p= zQA&F?+RSg0cT8kt^uHmIaXRTCs7Vl#5!B(r1W0NhY>d zTo$Os%XcnP+k=dt@F%IIRnnN2P6=%f<9(n(YGSk&Wr|Md{XK&JxAcr?a4hJSyM7yI zR%7$p!s3n3y!KjU@zN_-Uca)ahNI;xuU>g;F@VSuGpeaFVa2J+RIIDrMl_r8tb$5a z=)GuDXJc1t&7JTr5A+|2)*)o1Fa+cc!6;KBs)QP@MA7$cWH!D=^j*HQ$w&-wiT`H0 zn8joqH9#yP@&T;EWWt+_v{+CJ>Wf;$(;2X*swm(eNWdOZB&#EYq+uRx(crTiF+L#p zZx}CPF$=*3qyf#BGL4TMl|2MXvP_L=n)S3}0!qQ)Ehb+LT|D3oUB}AISG+u%2y}9J$Y82mxkRdu?i$LbV1S!g@sdS||_FL$2 z-KJ4CY5uitjs&!W#RquPCI8Izl7|FV6xa$ywV6n*y3S{id1RfCWH1n5yskc~u6s0_ zD!Q%e?W11*7qPT|<@)I$+WP5~q`M#nNeWl-adeM1UNq{SBXv_GKx2S7Q#wZm@kkR7 zI0rSsQnKuk0>J|S(n|v+u7GG#!hD3x$hIy}8TxA+fzO8|vEWM>`k(nJk$?4+$Rqsd zDg6sF=_#4|Jf=nPsn)}GOl_~s^o{?H`qhR&V?hK`^?f<>Su(-|9?-{zn}-8{=nsOW zyY%bXq>!2=#B+hz*4fk*N;?8DI{sDK@itiBx(!l^n4JlOlVZl|^)d*3Kwf|bam4u% zRh_%0Ya4ZgG{EG@_|v%`KAnZn)OcHt{Hor9o%WM;*n%32(;I_X7j>#J z{HhR2lVJ?C==|qtZ=UmEe(AF^DnKcd+=Azs9Al!2ht!sAb|MuP7-$_bAC`7-aPr@z9iKp8lkLT4zjwH>A8HhGsZjL# z`^Jj>UO(B&Y-`)LH= zAzs$q3Gzz|>>HX5m_pb1g;XWN*dsnX8AcVSfK>`C73BcxJgQ9)wpxb3nRovM!T(!a zftrQx8Lm*nQ-0>7)bW-;U#9r)4f*N61!aWy^xC}b&NQp{A_kMnwE0f^XJ0&fcBcNf zAcAu4U8vaV`V9etI;t_1Byso0Cy7mGaoMCACywro8lQCs*lOkI9W+9=h+?U=(w$dN zSZVkK;p#zFk=uz7yp8e4d624F5eF)H2fZWSac_^2Ed_nol=%rZn;z&*%|M#y!KgEu z*)BK&oG*@*UHc?PSI9wVGzd`Ki`}Fc>w4n%Z&HA6m{i4$7Egad1r!DYgo-ck{<7S% zV~)S0VBtGJF{Pq+x5WE&1$tM;AQZ-qNc?ZfmE1@R)3 z5iFX5rTVmGFW&!|hKvYloK872yV;L#v}}gmpf;FSSOjj{61`Q!MH<3Fyk3Jih6B~D zpOkli0IRf~llc(B)|)S`Qlni&+mCchgVO$rW~M;vs6unU+#6tXa!8+1tBuX^pmeMy z>^eWe=Wupv^^^zgWe<8>RE_a^f&$tvBZ_^7xf$O7Y_`{@@$hG@YA>JcF|NKi z?j3_(vEE!C!8(GEAyKx8*IRfetasFbY7Tm3jBclumG<&o(+mi-Y0xbAH~|bXA&Ki1 z3J2g#a5l&VR2SNk#sk<4{Zn>FrTPc7?QF;Wr^KW@FGSfMy(mqFQ^s1&O2$ycOckbiy6T6Wtk3VvZt(moLK5b76n!ptrX);q8I@$zby^Y~nF* z3V+NOy-`Fn_It-rnqXV820^2bX1b!M#;t-+AY0U6NiT>spgc*&>WZ5MqYaDHA!!xy^oI@GApfA?Xba0Ky>#Ujr#OXkg1|BP=T| z<>G%Cy@M|^Ar%FBj=#kmi9l_T;C1Bm_Q^acireg=(GHFw_&(s=>56sWnz3Bse6*mr zC0@I@{XG;`MHTVq6?ystfy;MZc~lNVv~HZG5X2d%q&`lmO8*`nD`XOMG0q3l(E_4S zy7+(V{)7o{yqK`36A*65Xisnnv^&)~&KA}x((aK$8mfe++QwFTj>Yi&J=EzH4*4&; zQwcN94Sv98BD&h)4Pnm_Y;!<87e2p(A;AwhxQGO-6#N+9J2?!l1Q-*y4;jI|%!D^q zB%vQfI2{I~9SJFqGhV{SF-ec)eD9Hzw>c7G5|oWofmTx|!c&wJZ{(u|vjB;%;P;Uz zQeemfDJndOzIuz&D>oIjk5wuzf}ddEPH^yt82?q`fGm>Yz?-z4bCLY$&MDMM2KW!t z0^DZLeiVZ!+Lj!}VGt$jam!EQb%dc;R87>@;~3HnR$YDt3Uz|_vv?+GdZ=sNWg0Ax z>YXt!L6ryZ=`c_qk!6>a8kb@vkeAhcB!OTR#{`V~%x@7%qy<5AS9x^{dKee!MNf9b z7?nCq6j_9oK5P3(78v{~fc^$o#(88%>q?)}eKhO(Gpy#jJ6qQ%KoDPi&ZiIU>?cM$ zjk~H^&ES4NU!tk>=P+r0J)!nR76Oe{SHX@e?Z?laQ~@2B9XaU&;RTT!;DC<=ox0|W zjcRi_tiJTSTr;3UeiV`R{-$8z{eDznJ?X~xytA3N=SIKWPYVnZRTQ5L0mLa}dqL<+ zqRe~Kx6heg>_xbr|5lE{DEKa8$gPiY@zA9Rlw$2 z)7tGGm$T!O-tlh(8WtjC3_#O#d;;hvzUF@%ZuX#l;g@<*|2UlNS^YxqYqRaPZnE6Z zWQh`J?_ulX`h^evy55#TJDqo#u}?!%TK>#_;Ysi8Z2%)QxVpE;_Q6q3 z)j;z9`PSYRLI%?Z_kqtvF!rWJe+z9q`MrIPgZ$C`!iRiyZ?Jd{>C^j#5Bv7MOsuLv ztEewjsi?72NfkGWRFwD$iT*?q@0Km*NFoaEaVXu#<#xLfRa@B$j(~?0@M&YP!eoKT zbtb%I3n(pvuQA~TK)@)v2AKm!3xkl!Z6-frLJM7O)PSZ@@Fz^DWdo|T;4hHqdy!sW zG`GJr_e;Om4(Ppn2_N@OB>jbcyqYb-$hJ?vH-u;g;+FUfuvSam8blYmefxM9fO0k- z4_pU}d+FJ|KKPr1dk0SqP7My?ZFe8i{=wt;9vM7?&z`|yl#BT5z6G~{91lDdd!}bh zPH8^-`3?J|{I2#9S-k9{Qmv;-C2ZGlsN}5fqa0d^hQ>-Ij^3{8&sZyZ(Q2;un`|c! zFv9Hg`CWG~egz#z0qq?ng}h!JaC-tYf!4eMPP9Flv$uGZ>3Ji5u++vwG@WegF#3BH zJ|eQ%0PT@{nAUUacKfEGU5XoxcB}T+pA=B#>Mst08_4NKZe3freErs9dVv~ju*W77 zQo&A1$t(pkpMxu~pA7NY&^Tg=_B{@BmV{-0BgH&FgnVAwU3kCzzz66x II?!MIKWtX`(*OVf literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/distutils/command/install_data.pyc b/PythonHome/Lib/distutils/command/install_data.pyc new file mode 100644 index 0000000000000000000000000000000000000000..92a6a3cb976b748ead4ef199aaccf90e04ea74ca GIT binary patch literal 3059 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 literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/distutils/command/install_headers.pyc b/PythonHome/Lib/distutils/command/install_headers.pyc new file mode 100644 index 0000000000000000000000000000000000000000..3513c7d21b7458e9d24f294b6bf57f94d3ecff90 GIT binary patch literal 2191 zcmb_dQE%Kt5FXoim-w2{s1gN%5SEBkL&>$gR6+uTNM9>?E&NtE^NL zQ(Bi5MS7w$r5igQKUvjjLXdK)iH zq2ZNmXKFUaXallxcMCs^)BB2Z(I{iP|@R;um{(avbqt8=|`n{o1>Gbol6Z zxa?C14Rnw`B%s+LwM$E%p#d^WKn5_j7@66S)V3%iQlThYq{gCble#5JNXb$B4txFp z;->5($^{pb#lHj8Len0G-3_sEQ8l@igA04mJ$I01&H%Q!dZC+_ zjd42CuTT?HE?Xa;=KMmwd|ZdP?8gv5;hZQ19G)mXEn5rVAW(ugPYndc0|>`rT9w+} zg3_Ul1QO<-+lHvtPBLx_#QUu-7BTK5!hQyAGXLHj&wHB9Hx!w79yc_b)MxGvwwuy8 zlNII{omMsHY2Sy{jv&Yj@$Zvkm?XLPpdhnTq$pGe!7rKpoD{QWD%{z;FJW8~b|-mA z*7gQI*=t$18~f7OUTc$o7Y?m<>AF;UVM?vK=w&%!wB8(-J)DNqf1vUazpz6kXi?#q zxC(;G0!oX@sYe$mxkvV{RGO{6tOa!Gk@xCLUVQxH7j)5@2Xx-A`!x6IBA^Qxac)Sb zBRX%-JwKpl0y0B76{sC^pKINiV@#E*6zDf4b{y{N=Q?vIQUDj?Ij`!olv$K;sbou5 z*Sb_OXCuHR+;pxrP z4&@;pH=)Fg;J?OQ!g2oRY1jJbyD5<=^4b$GX1HV~rD>V1becN0r0J?s>w+IS3#Dz| z7?~M9<1m;C{iS=-R8=`L;1g-u=oiMKv0z}%_Hz}V??xxEkhuSU5ekxDwb*?l M72($9NcRSR0Z5SeR{#J2 literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/distutils/command/install_lib.pyc b/PythonHome/Lib/distutils/command/install_lib.pyc new file mode 100644 index 0000000000000000000000000000000000000000..146bf0ae32db83a47ceb150d9320aeff2836546e GIT binary patch literal 6604 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 ZZtka?%2Liaa_uypUsi&Z2Cmd7{RfM>(y9Oe literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/distutils/command/install_scripts.pyc b/PythonHome/Lib/distutils/command/install_scripts.pyc new file mode 100644 index 0000000000000000000000000000000000000000..1adbdeb636ae186506d21012b61e3386dbcd25d1 GIT binary patch literal 2893 zcmb_e;cgp65T3hp9NTr8&`?lS5GS=!E2@^nw<)(x^Ov7!s@&Po9jS1? zek0tzpt>DaXM7!wO%YbRI-hhNpSmNHht-jLwt<`PK1%QExA^Nt9;R*;!^6^sa)B|) z%w)NH@N@FxPy64yb!=R?dI4k;dk^r~rx+A~g!dSM)JK%wpmdYcn=}#p08iSX37}n} zw95zq#B@yrY+VghRTlGwJ@q&h5rU<6|b~aJGQ&j+)Z_H z&#}j;{enkbsF5?pY3NK1+2S;3YzI2Sxz5t%i$l9zFNVw4qgS|2oj+w@#O=Moe+Cn=OsuP45VGGAPQ+7v8u+Q~uSM0DK;{cut8)PZ8PR;Cy zo#MyG^N^Jy3_$-iQGzgdA|MjwN>B?877ikQtEVwg#3s82&rPn}H3)UM;cmTWiTRG_ zrEirnG5aS8Qdt>uZp4g%pb;}f0$|L!Vc!8q*6k%ZV=n+(DlX_^7gD*wHY_n-km5Y# zH(5owWS*yLtaFvtm`Oxp&Vu)k#s=QTq3^`v4qwQIk+*?Z1o%ia7#=oXqVXq$5`BA1 z1mWVDM_yiT__7+v*x+C>VOPjC=@@mur{_Kuf6&PbQD|`;-T&noy%9bix2Y%y1UyDe zafBzqe(_k|?#kRFMD$kLpa-bd_uu%nc9VBs`*aqN$9G+?=U@vCcmnH$9$XlE5?JBL z%vgP5H?cT68srns)2T^SXvX1|)l(#(ev4?s*Go0HKx~__D38tVTfq(Eh4aM@6Q=N6efIyFDYA`vK!uQZ#~$AwCUgWHcP_PrAr9IOe+a< z?9ptUCY+?K(UVMY%wsMfg&v}Hnq0iCQuRYHoe9lg>YTCs1~bcG(IuvGsVGgIbwDNWKQEHsDwV0FjDqXESWKp4F&XKEkw%*c~ zWq<4aYlDlpU`ie&39~*)r12yPNIK7W$_l9}sQ_ZcoHIg~xm8774CVLB(3ngO@_H@i zK*ro~;*f_sJTUG{?u&HA7AAc{S^{&S={Ex|k%89^xz literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/distutils/command/register.pyc b/PythonHome/Lib/distutils/command/register.pyc new file mode 100644 index 0000000000000000000000000000000000000000..7535f6dc6b654ed9745c654650377415dbc5eebd GIT binary patch literal 10027 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 literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/distutils/command/sdist.pyc b/PythonHome/Lib/distutils/command/sdist.pyc new file mode 100644 index 0000000000000000000000000000000000000000..bae96454f98a8cb4d6ce6c3c3febae96cc671359 GIT binary patch literal 16430 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 literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/distutils/config.pyc b/PythonHome/Lib/distutils/config.pyc new file mode 100644 index 0000000000000000000000000000000000000000..3a33bb6a64bf2913ce7f358b28163ca956f19808 GIT binary patch literal 3535 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 AyZ`_I literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/distutils/cygwinccompiler.pyc b/PythonHome/Lib/distutils/cygwinccompiler.pyc new file mode 100644 index 0000000000000000000000000000000000000000..3cca3fad0799118b1a272982d363c48a247210a0 GIT binary patch literal 9645 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 F{|m;rV4?s3 literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/distutils/debug.pyc b/PythonHome/Lib/distutils/debug.pyc new file mode 100644 index 0000000000000000000000000000000000000000..35cf785d3c20f59f61ae7076fba236b0a8e00efd GIT binary patch literal 249 zcmXYrOA5k342IK(52WH9#6?#w+z28fK9GWl&=#Q-Msx<9Qaj?Lf@`nj%{+i+tReaH z5&n=k?{@38+lNQ^hfRG-rF{}kX+aK<5ZI7dAOJEOG6%Q=PYV*)7((AAv;0tOw837$ zd)OgZ1Ys0M!8&A%=nvM6*z>5`g)s x65S=5kJ9Y}&#D*<(_9`>E;W`YbDeT=C{O+C1Dj+UUlcEMF|mk$?|F9J{Q~INH6j22 literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/distutils/dep_util.pyc b/PythonHome/Lib/distutils/dep_util.pyc new file mode 100644 index 0000000000000000000000000000000000000000..724d8eb853e5fd85bab2d469fc49a84d28038374 GIT binary patch literal 3160 zcmbVO-EJF26rNo>PGS-orB&5Py%?-kc7$UUgam33s?;Bpix#vAM2b?G&F5qwve_= zM$Lu#tBT_y&Sy5WJzIy(clOdd*jW6O6*T(?{ig?ePapf4P0T!+-|PuYdTfj~ z33-N*a~GuW;&Er`aGwkVqwKY5T+4U5SwXhno2wnQCQ= zwtLfn0piFOoM<=lr}NU=B-N+^vVL~uISk4ERyFOqYUZ=+1Mf33f@z*mq(#6N09_QJ~@gj|n=V{!V%m7Ov z7*gvbw}wWnZ3c~CE7%O`A*TZwxk!hfFaU0SB2b6Xds-9bj&R^0WI#w6Fcjh<jI20Fkaj`^+bdLO4q6PCnoQL8ChIPuC;Jn5ItYL8WK;VCf4VWH; z^Gx{z_8i9fsdQ7#K`ba{IpZBsoWv&1bCrXW5c{kc5@uAKjHGwpBBL&GmmyOUZH%%L z#GOREdwYxgilH_$L|guxj@Mc5p3N4{n4ET*Z`4x1(#)n<@KebckC$WqSs`NnT(E2E07uE{UxR zfb)!y`RI8@fV`Aq1ln@~Brtsna2|>?KMZ-8iL-n2nHtZW^AQ#M&p`}3w*XjBySc~f zkUE63_dAqQ_IEJC+pO)q*(PY}((UNMP6|?z(+pfns8k8)Oe6LvzhE0i3IWmc)&d+A z1@09RB#e?V1=4JnIdgu(n{|PGf0+l08It)7iL_ALg$-O~nB;f8athXbo~n-rYkQno ziv(&Tp9*I*%Gs2-c&b2-lpckQ=lS8!L2>dTyOa%VOR5HOnLF8OakN|8Bx@3uk3%L-cMo-wOl?hiZ zv%BOsmS$Bg_7xOR5dLky9LJ|hmZ-VbmLMdqL08HjYq=WT4i_j~4fK%Cr~tK6Guts` z(V`NK3YEDwst@Z$t&|gl0m%wiu&yLFsAtd!Uys2dDOFhVwJ!4%1)9Qt3UWx|l1g(i zDd~d%{8U-rl_#ZRO)OTGbsXm$urrs#!EMM;nT-=yf?8*CsF@?RgsqFH&5hXhNQiDw zN)oSl*E8jGh+-lti4mo4L6IpbPR*7Jkk}A_3RV@$c{+PZE znTOtqg5HBBPeJ@?`U!^iHX5;kYS_3QuA?fh1vNYkJj>x$uoCizGTYPdr#k8P*`9vi zsF#_=r*XgU?|6Bs4Jcex;~vA>a{XtwMAxw#ZK1im0{8w$RbPSh=YUO_t1rlfmbkSM QHo~=FBiIO6Z>(Pb8%hLI0{{R3 literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/distutils/dir_util.pyc b/PythonHome/Lib/distutils/dir_util.pyc new file mode 100644 index 0000000000000000000000000000000000000000..830efd74d602c9e22c0eb29403ca275016be6074 GIT binary patch literal 6753 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 Rt-iCmUf1il=NrqH{sV?sfffJ& literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/distutils/dist.pyc b/PythonHome/Lib/distutils/dist.pyc new file mode 100644 index 0000000000000000000000000000000000000000..f124d415f579fdeb422f457ae813af9eed61b0ea GIT binary patch literal 39231 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 WV`t#f@bGwP*WWt+|GT^X^#1`AT`vp( literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/distutils/emxccompiler.pyc b/PythonHome/Lib/distutils/emxccompiler.pyc new file mode 100644 index 0000000000000000000000000000000000000000..688d34377d22a550410bbe5270532d2a66a88e21 GIT binary patch literal 7332 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 G-u*u+V0{1p literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/distutils/errors.pyc b/PythonHome/Lib/distutils/errors.pyc new file mode 100644 index 0000000000000000000000000000000000000000..48f9309cb0b010cbf0c912f101ca538f128409c3 GIT binary patch literal 6185 zcmcIo|85({5nhp!EYrV#sZE+RYuSk?N1}oJ6Cf#?I*L^obz|e`z=+|1S>7(mt&h9x z?VhOnyZxu=JLDmPJVW22PmveMH+y$0%1(>0UA5J~ zU~;RGo{!Q^COeJvLX@6k@?s;s6s22CUT&mUqVznIR~zZIDD5zLy^-FC(hE%9Y^1lM z^dghnjr3PhdWp$jH`2GF^fHrgH`3ok=@lm5Y0!B$O0P2cTc)lCbl!{7YfSP+dOJ$5 zGr7}9??mYhChs=V_oMVClOHtF-6*}qWS8~3d*r)+lJB(hh1Z$usXVv2>vW#x_E<~h zxH?JI%xh~LFPxHmSaLs6{EKD;pITXD%Jn$^(t3rL!k@nF)NlDzlsp&ODek;5Qsi<$ z^QT-JJ`=guX_1M1pZ81W)%4+s_FTJ8;R=yu^?1ogHs{qctI0&JxE&sATR40~i&I7( zV6pkG<0DaIzSC9X9v=$HQ#+kv`h!dx#YH|YrpkD?*XwkiO|+|R!JOQQ5p1z!Gc9gs zl-nuq^?F=SXEyiz-VS}NuyW6>!My5(Ck45&nFf`jhF&Mn2aHF?I(OE0=L7l z5L#;e;vpfw({t-^%H2ouuD^_%_;q+26Avz9pOf?G8->I}rs3LRNxw_)+EX*5L@z7v^k!v3!!F_HTDWYk`J4C`ZTfSFoFy#-ov^Qr7-qpenT1n@A@o)1 z5uVlJ_c>w&-WzGayZAcIgmWE^Kk^0~>+DoDZtuPpg>|shuU+t0P@oVo0ltL5PRO=| z&^!ew-2Gyd$mLh@t59nB8@P`s9nzAQ1nJ*U&?n0p6T-527pTmvb9#t?C3od|h_ttc zhxhwjBT`IhjS3KrltLg2ZWMq8nywgDdT4FU&^^kQku3nUL9F4kq2d#pNo~eKOEE)^ zfJg8F0+G^lh{O}xU^*4@DN~e%_`dQ65kdWFP_WY&v7?Pw`ADQ{rRZ+}EQ-qt{q?gk z`bXvM%r6Q5$IwREhmi!X579cS7&RcdI}#=>2jif;ySGai4(+&bD>ZBr%Xm8)w&t(l zK8DqUe7vMp0>cxc@K6L6Eg*)>m7AeRgsiOWs%i;8I0$|gCOA_O%hC4~2#sR{8y8ND zSL;~fuXm&UEq{H{{v(~KB?0&j;~$uk!;_$&scXy_L6r*?>yuL=B4NmgkQ@74`Lq`h zcvjAI8tNGc2s$Wxkd}?kP(SC2OXb06NG7~h{Lz!JR?u3|@uXiprnbo74e)&M%SxkX z3)bF_=(W$L#gh=(OXBwruw}nAUZg1W_nkr|#!XYp5fe>3RC(j}!8qxJi_m$15rXN{ z!dKluYRxFqPzBzI143-!jRQl0Q{sy-6b(RD9=MsxGQ{w)$O?ry$T8Hr1VYpX3X!t# z%2Y^DmGX0?Osywqsm8$*daR8I)7Rnbln2?lG}kk~|3-lC!#p$66)A?02~}#2e(7K$ zj@3bF3rZF+GVw4%;NB}^=l23BQmulS^_*C}uF{FJ=`^dM-|X{}f)5iRKWCt|pym+G6=;vp7pJpO3*d?wwZc`I5d8448kNWXVWmi404g6v zq}yjn{^5yAmqhtn=sH943Odjv0fEp+q60A^BfcKzV#>QskWnTc24rfKu#K5dKpoX1 zjjthFZSQyy>!p6*ND3-^&lJ}SaP{{Ft*vu5dGXoyZ8zfS>>p{pr4U|aJ2=EHe*K%%O`W5<_bxls--t$R0oc* z#sYmDNOTtUfIG2A$g#h~o5TBuAAVSI>PkI9P5+|>Q;0AAx3D3WU9h93xt}q@*&xjocO%yAv^pF`trbVp#ZMb zS(KSiqJb?>jn!jB`;r!ZbJoHtU*3qd%96T_V{2`z0!P)3Hmt!!M5mkJfK8slf@E8% z&9wFIFW5}E_m!dk#vEa;B~7P;mj|BMIGjb)8B3NGmClN@eK}jL6}K?&^JvA|mtE@k z!l96-j2jGc9J)Es70%Vjs}GxF)dUYLp%b8l4k8lTv?sK4O(?n(`Zl3%GNDE%Azca8 zw}coqAzn%du!Pb)q5McFh7tlbp*0a63zuJdBo)pDe^(u*{hrp~NYQ3%v$fscUf&Ly@?VKtTo-$_3`R` z{@$zF@;~NkzrXkPzALhS6L^0QKm9%)o)8CkTH?SGUP*Xm5tPIM8m3(q2j#q75eF4+ zS41!&-smsp166TQ75BnbQBjlPxF!-;Se6A+=ngG$-rbrBZ&!a z;vXux``qr7*%S z>7^{RlNQ2h>4amVN&GY7q2H70p-TE`+YehZRLV1YIqdm?C;e2`+fl5JdO^@9RX8$^ zlGHg2RE?;dI{j^l4N1p|k`8|DC^{ycWBWj*vLE#%wCiZu3-hJ)Mg6qfW~0WG?uI&b zLKia&8E*4{l%dmA^0w5FEo^0dlC4T?nPCV|W-iRP4QAb-=aEoO*q5>69y=}QWoJkF zs!>q66-MbTNOj}~iuZ{U%uUHvCeLM)kp+_|N(&nGQ&uTW8uvdLV71;P`Q)3SekaC~-W~Q|4I(;(F?zV*YZ_E9AcYi4B4S#dHAP|FL z+G9t@%Jq+Y7cz{=1(~qJDa=i7Bvqi5^fl(VQ7iP{QC>mlu+I{&vuD|`)H=Mk+a(W# zKjb7q%#oSS3v1@~GB#DV=O_ws4yyzI&dd43j_<~dpIOJ|ppV`I( zO0fgW=XZcWff`xGIL8L>wm~bDPa((}Hr{B!jfhheV<$*Y+@M)VYPO;AQ!I}V$B1ty zNqx5$I7uc;U7hrNY@|Z=>Gh}0s)EQXuf4X;C~5o(+w9yypM*oRgYJ@>Yrs zT%)}Z^u`qWMX@we8LuF@)L9((uAc_|jG4ecOq`_uU;BrlL*7Fu=7+~J^^3S44Sq@F zXPhuzz{P+vBNQM@5XR_DG7FP;T8<9@%*04~A?;`XPs9Q7acQKildJ1Cup6l$Pm>61 zWCUbCjo4OLF%GWO8$<}90%x!;aqQ@@gRuM3$mEGx;N`-T@5#DqHKZYs4U^9NE-ZW= zLpBUj=#6b;1YoHP4YJk2Bdpb>ya+@a`G(AZOL?R4IrKyL$ps`+soTi?(ukC~uI(hP z$I3;y#mH3PB#2Pj$DBKzH$3YqZRY(m0e}()fLuJbB zBZ$p+WuqY%ucLzjmI7`a@Nx{7)+msW+j8@!{n&RMO7Bj=P@ccCIEZ)DD#J=w#YHu=#{+w|DaUbhE#gavC^oe3|L0eO%yWMBko;~ zl0p?QRW`>#y>goST$Z8yFjYyMC_FbQwfbEjz*#IVhK<>g=16NB7hP*(q#Y`fY~Al3 zM!{n}F1JlS1q>Q@$2vstQ4)25;*Z8NnA;mGF1Y%IBf{<@SK4OJrLb$MP$ldWp+bqH zDOQMcBXuDjljQjjKjZbh2J1n3AcS3|8Pu2* zgR+SGq6ND6oDzeIh<}lPPK&{Wh<}@Z*2JJH;*avr88Mg?@gMTfSuvOr@gMWgIWd?P z@t^b0c`>Mo_%HeAf*8z*`0x4Wq8QAISXdbwm&9OB#0&Z7k{Ha3_(uM@ECyH(ZZET_ zi=>X^V{5P|I#=jqI>hozqO(G6i`279-|v-Z00-6d3DH@j9oi?!MVHeHHWG43ER;G#on|XTgNSRte+Cuyn4i)g_*g3y*%R(i$53yxSY}Nyppo zYpqZ=M&Zjzg0P=L*Q+?$@OT*?T_;ZIO+_TpA?DLbG%`+8oM^>(b)U|m!xWlXZOBu` zi$(4jFOm58Z8}i8rI$hBag`L4MyQMmmUIbIO;46VIW?sVMR$>|SXzT^IY{%i1z53E z85FP{@(5?Sk5ylDLqkj4NK~ApWL9Gs?(0NI9HhfjCkc_h%n~Zzd6;@xn;OK-Qk-TI zL?KoreyZve<7OKb95snjlddM3WVz-HJxJe8(s7f_*Ca`sgbvM1^dNmSiAa-_*t|lI z6+8e8@Y++p?Rb@0=;~G-eS#nQ8))s`eqhqX^WS*@V>~GCW*!vq)QI~mo^4Ymux;EV z3H@y%vv|W=vYxf3OVif0weSUh)8$!fR@5-MV$E8MrM)^yo>3&vvTgQJ+cuXR_#{`e zZ7*_dyLlb$CUH7q{OfYxq_B7rKYb04>WkHhvi0~smu8YCN#VQr>AxWkfUdYG3lJBU z7+RtWq$r7QSq#gp&TRa|ft9%@Fsw zIC+<6%!oCbXoHR<-{JnNV={nO zZIorGd|Ez7=)o5d`rs=Pf){ME7kt7Cu8r+X`xxKeASW`u{hW0Vg$HS2*7(A^;vURO z6R%TPS@$u#U%!QD-{U)CzP07dfy)(5w@1ggM#AkVp(~OJj&Mbv{SZ?)wNcBbn^rqH zGndR$nEnP(^cAc%J%lP6N95E#=|w0Fc@xScu}x<;I<5JHKq-N~K1TN;^3gGF8t_eN z26qf0awTPlz^pqpUtof$oN6CKqDc=;h_~^q-k>`R93-j0Y=idz$Bw>AeM$~oH#A%g zkP{8p<-78R8^>AW>?~_+ZJC)}Gqc;}&z-yGb%!&|cg@F}=Cx~HfqA`ZUQJE;ZztjF z6jIO5eM;3T(Inu`{Vbg)W_FKX4ae-MqwH-+HX^3g@cPJFENU+t-C`D}Ur7q6bLm3z z{wJbxy86nj)Nf!L;0tiR_+Jhrem4q_{8p2kthq&x?Tgb=_=-)A*4&{%%Jd@|^#3Kz z2KAHPa18dys+=9UlE77k+iue4ob9;KaAG>*a1{`lqJ$LB1lS9)-&mnR?!r|FE+M_K zvV%(uV#X98TzhcEK?Ml!?FNy~su*I9M4-I>h_oz~5ut)v95~eA&?5U61&864#J!4(6rppV~>@?Ly z)zT%5%vn{mR;)QuE6rAx(L=u_{MJg#)|Ko#@6X>vGyhuz1<>TbtUa+@x>CAanwc>& zaxu9H{tRTk+9v&kF ha_j3BmMi8?b?%w{0d@%xAovT~5(kKwT}oKQW@0ObNJTUm%SuwPGGK`^1ZXqZ8DIz4 zomouJl7I`y!Bn}TDqrkls#2*+xtv3eN#&BNTzt$m$|03Qa!jtNROOJA^L?*pW``mz zTTn<~(9`qgb@zL(zxUHq`On$r-#q%Gjh@Q>)$sQ%{ObS3#aC(*S4(YL%D0tYQ3G3T zqG8$S{QpHmB5ZT5V1%%g3{Z3aV}@*COOX6|lJ83^~bm~REm-vpMafY!!9t3#grOqgcABTRRg>W|>4B{tY zwAb`}KTN|o@&?Xs;HBdv&}&V{dDYSVI7uDwa|Us==U_-sX^aMbVSw>s4AKu0A{WA;^^2Z&)ez6IYn!N75P2?h@w508hVL4f91dwW>X zcsTSD(!5$sK?j&u3jRCe6zhq1@!H7KI`BJTX|6&I{!S_mVy7)r;u;!0UYPUT1T={X1(}^DCWibhcl;B?EkTQ@^5T zK=xt#roMG|iPu+BC{1GZtF*@3meW`;Y1z|V$soZTcIa)S(uN#s0#C8Lvx zW9BYZg8 ze5dm`NOoc!tZ=rGvz)!NTri0v+346#L)pV&gv}JB+G%BPwy=Y-GY8t}qsI-B|K6vn zQ(R6gb)r;PsSs^6JajcUVcShH39t+OTnYds2!YU7Zi zwy&c>-QdR(^&Bl{x_YpERh>eExf0O;(k$LNys93F;K^qln#Q~dPi`HTl#F|@=ESUu zG%leawT_raZ+yI1(&MV)yRkR|HZFN#nyA^d> z%`~%LQ72VK2^Rhs<>8Gx6Q$@DIGc&ULq@xUu$Qg@L*O-mq6N}8t(&^l=Cnk2E*eUN zAj)F65czEplxUD!EH{5FQLMVy9qb?hQL}5jxqA`!XH|B}?S*I~ljjcZ#B(ZZ&Z=0m z_S_4VKMS(5L=8IV9=hEC(F#y583#a5LAy*s0u|0~oS+jRI`R^YIH~U;dWj|gDQb0| zglXSIINat=t0a%ssz8y5vSd_OF!mP`0w$6PVL&0!dR3*c`@)z+MPlv{Knkd}Gi=m9 z#tRP7>IL`uepI=Tf`AELuZwc4XJ zY48LX*`hx{1D=f{1&-KCU#4uoZ>ghwc48+!MU1$;rM7H!YPKjgC)7|?2U99}kATPx zEqmB(W7*kYX|}GRTNXMH8M-RBJLwLW`D5Ugb6eLmr7(I7|KvM2;hwRB*K&38#);z8 z@q=ABa9@ArMZ_kQ@PE-uZLVE*U#P=~DMBwui4i_PM4aS3#6bx`&IH4hSC|GvJpqvt zXb`i_h+4QjL2}_va|o^n+CB5$U=ZHz^@HAl@zz~V@Cconal5iETZ@7f73*U5_xVlp z5(okafryrpWCUGjvK>wP}?6&Lr%2L<|0o|4Fz}^Ad!?8vxmw7RakePYG1nC@K z%6JK^uj+DGXO>mg4nw+=!lFpe9CO+!Wk4qNX1L(f7m* z5jbZJ6LZ-azE}vdV5QxvI@-2rt~Ef8Ya=)Ve!^T43BYy_Y?bWrb_+O^qY-TQw5Foh zOOzF%{8%Wf6H1cJs}xBhfXPz3CImrv2}}YuV`t3hzY{j_Ef}z-4iMP?1EB)hB#3fc zLzQJ-9Zajye<{9Q$=;4}3pxNMUY_C{^t8p7g(iQwmVqbu-7y<;e}>HQl7&A=P8X4v za;bp@Udgw4MQVB#;ETk9Bto?W31Aemm}T#s=s<4HtNpo*-zjE;3>kB6sN`o>Mp{>k z$xmfoGA<}s-C-~$+|8UYjXM~p#2s03`JPYaf5A{oqC%O~;$+YREN023Jmkq_+`}as zL!;!dzmQE_KM*?9mgdw|tSz4%#=Mx3knbf~H-&UtW(seGC5ikgN|N9zH8BMBw-tUK zK^hxv0;~QrT;7dGV~H8Ks~&qv7>~8%d#T5A&A2DkAM7|(iw=TdB1*!Q4?t>-D|F>!pY#5n8UtQ6RM?DfHZx>zaPE#4m>p15%l1f0476yb|y# zps0Zu#j1oldozp>`D;|KP&hMT>x+1`F)gkX8b&3932V++N(Byp81whzKu4`qzg!xt zEI|`TGWrl#+0JE&3>?cxRWBM3cchU8g)o!B@p}6*__=gyE~9;y$+^oyri6t_FhY^f zvI_(wu#UtDP$5OZ25-JisGe<$&ULP3Fy{EzTGrFvwP>#yL(A|@JtfP@Ll`3sG6ko zRs-IC0U=ET*UQ!U$}$q7iq*7dtfj1l%osFvHOm~iwqVWRFKFy}8~2sjDtoR=&&4UG zQx)sHeZ{IXrJ^*ck-|M)#omEG089hZlP@z425!LL+<^bdAlE!wqnMv6x)eMnAOl{- z5fN*Uup%gf0QZ5rxSt}XBc(k?>^rUY;RWFIOiT=KQ;~qW#sb8n=!UA21i0T+$)76= z$Za9n1V$24{WT%zf_OtL*{Ji$7c5i zS{vZM(dO3DQ!tQsnKQE(&+1`k!0Mp^M(rRdLkUc;IvXibo>_IN7@rs5SDOW}zq9MK z_(qErP3~pFC$kzo9*qV#OISg%A2`+0$9ffnk3ab8+IDNzao(BKL|dk;{~0XI2?EhB z3Z6LMk?j5fP7loa0v(TGffEVN8;;Es01W67FB4Q#8Jhw@P*@WwPbMh<2atxbW zGC!w0ugP-Y`LI-+zJ$9xDuKjC1Fr{JMUzr<$zSd>49-V2qI!cbNz~k9nb=^rAt{xs zCt~#`qxIs^apnO^$08Z&0RCgef#>b@iv?k-gJ3sBGM~m{Oql z|6z_6#Jvb?2RyoQIYW1a7x6YrY!SR&=E`p2FvJTOXs0UxFIp|4V=Th7-8sHMHzT!Y zQ{?0OsI4WU>anI^e+`C};ANbYZ z!bP2%0m9F)6l~Y+ro8~%Uxp8vwJ+lDCA$qDvH&m8fS0(2{<^erS9uw!^t^SwQU^tk z667!SdLO@F@eo3 zvz<_nOX6O@<2r_opf3z@lmw3@Bu&PE5uk?AI1ZDr*<3FqNVu@laA?AX@}bFumW4iA z;7)*pk)DZ9kArk#)S5Q(OX=554P1;uY*);yG`cAcvPySWZKiw~Ys{kqIZAjHsxbBN z+MG3GONoP%prwj-{tX258@4(+$<*{<`;hLLu|HfN%gQDTKne)&Zc59{j&Pz_DIDg8 zWJ|WXh9`7usB6uMiy6p+8r+I`fEQr~aGvmqb&h*D&!0!=MWT2$|Alvi`-3ZjuYt$8 z2G7YJ_3kR#yOUYz#C zg~sD_G)`|7XPmhM{8Y8PbXc8v%*oC%o`6^(nU8ymEh!fgJHmBbBoA^lE!Nyc-Vas`e|R%63VZ1%K=KaJK>%j zI7X@XA`)x&Yvf0aCvm}2YG7x^2vgoRHqfOFe2oAh@ITD}zlr~J1GAD8ATh8Pt^wBZ zzYh3dYQbvhJko?2^eoxeQL}XLk^%UR3)J+#DiQelN<|1qerQg|$;zVj^3ZqPx>;<4rfc&S^wg=gA8$is74 zBN)uu*f<(B%HmYkfut9>Pa5=~tSZ@{5f*O29{%j8&gxupZ1EOO2$VH-lycJ~|0Dhx zdkuLk0jJ2)E=w>M1l4jrqR24|aP-C!ntcMrGu9SGtMaHFW;)-W9r zl>kC2S?7k-Vf5cZDFte`<&&H>mLO4PLvlg{c5wO_!C7_QbUrW-woO90fs8SAT6_n| zATkylA`H@yd75A_`$3XPcUX=`(m}!iljTh9k zr?&IjN$0g&A)1*Zq`A4jjf?qi#X!RfJ0+JP?gU38q<<`_x?jevpv31T%c?bU>=HXrtozK1g3`dkS_~Xil?H@_xj`LK)V}!GR^yO(xotDKgvxIx$Agv z*6rs0K3@J)ZZXzN)zpktMLIEsGy4VnpR?-lGe|D%2K|h6!J4vWE7#$HYIeOggVf`4 z?GnCRd8yh13rRJIAmVF?@_-*g4jLtt(eINaj_|b-j)y^IeUDj~kI1 zAmL7sS4d8QdTq4FL#pM@GS9)6yURw4CbXw&L>KN$Xqj;SCR_M5m(K}G^aaInc{eLa z@{76bG}?Uw1U+)+KkA&AsOc^Oe3*w27FU4{fXYYs0_iD|Mh^lb-{ZN;j(lmlcddNI0ZKks5Emt;CuOZoS!Pf6eA*&dx)J@Dj6|blp;xy2evXF(gGF?20VJ? z*HHLaH2fY2u}T(^R8VKyhI%N@@X;LKfeWtx8Em zOXXY&BT`?QS4h|gE+_{O65_^<3rGLuR&ozFx{{C8^%D-v+eiM)RIbNYsxA6AVEl-6N6;@SJQMXXQ|C&mw zs$WyLYRcpHluD*lzpif8l^0i4Sf}`_;j{`5;peal8|u|thg5i6g>&j5RHEvL{GX>J z%P1_UhfvWNeI8X0G2n~}kEw^SWtNg_trN8GE!r0wTi7@;E4?_0IxIFC@8KQWq3#uF zVB;(`x|iiT8$`KpfF`vT>NkRU2l2#w8!vT9jSi{f>-i9 z%UxR)ZAo^=(pNz?7($zwMR~)|L!HFw7Ah>2vcib9!+tkQ;=oUm;aGxd%&;FX;5Sx~ z4_I>u&lH}^c+8(*3;eeW|KMFyAN<4{9#_^=JF+YfDr{O$Us5$&QJYn@)lm5j<=sa8 zl-k8gzzi%7q<8A7S5YS)czl`2g{%+wT3tQ|D*(}Sv}9#KUT@BfmjcB*RgklLxx%H8RMs#d)Nv&DoS zGuxeMW#0DQp>apmPEBndR;YqT%<{ASv;5gXed3PES$?K&qSHE-1e)^SdeqlY50vtt zALizN^l0?B>Lw)DT8FuyuV6thBV@GQaPg;`CJ&n0X1W;~+gxchH2%Jo*$v$WG2JcupD3Q4CGFgz~b^BR^ziFVFg-N0cvX$ZzMdME__Y2>Y>#jD9r8 zSF~RBt*>JvI;iwTcDGTg<5UM5MY?5l*3->y(d$Kd$HX5*P2C+@sB48$&o2_IzxwLd z5;R@Uw2z+sffZ%3(S1LRINuFF4Y3LRbZ9qdv_J53E2d)}cZ$S!v%&_YM-Z7x4HH)e67EsT=LM&njdu-!c%6kvAygv_%ODmZm#(Rhq!CIsjf znarsDdTRy(viYxPX(R#V;IyfIQNQo@MzrVY|f#*$Ky zWF~46D6C*e9>_1^$8z+2t0EeDh%i^6L}>xMCu8QhvAJ|dw-$OUd6^ebx_t5WJ6N17 zed+7Blel|(47az(aJw=X+T#%I5C=O_9b_pY#Tp{0ptNe#y}DP$zvJH1-s#FQl#ZfQ zMcLI=y;CUdmFr#&-%jTFYTcVd|Cq2G<52-;PS6~~6vz{Y6;3z0w(3Cy~(NIW%uj&Kqlc0w~FnEWXVyK|%ZS$>u> zbEP6e9x(RUsQyUV7rlrV|5Q5w4gdvkx1whGja)gUwx(46H)ZG5<^r=PjjA|A!Az!! z-fP1n$^yQo)Z*?D0O1(`*D=BTr#$>&AqYuRW9tE-d#dk`<_jwX@ef$NRZ)4zvnX_3HEjTL#Lnnx8qeLzv6?Bc#EzS-L^1%@ zDRfk*sLS$fN3|1)Q)8L>kmF%B`Rzq*BG_Q5`YhF+rJl3sarQNujFyrvFzp=(0Y|j= zIS`Aqnx#!EN=x%e%ZC`Y4}W9*-6A=mVlc=+4PtvyH))ULnbuNM(}h$MY(&8p&5#N2 zo1kdnoJcSjP51mb@w-V>y6(M{9=+xV`t7x4U62nkcvGAd?v?w31CGxU7^GiL=$D~Bs3{fe%VqQ|!2{z; z7j7`u4{YHlviGrM<6V*!c7VWPQeKvrrt=Wr<1nSi#`}L8LG9WRE8vUdSfXmfhby`f z0LV21A{fH?u#*=l=7TN2Bi%vtni8$HdXKhF)|+))fJ z*z5wg>yoeuVLEYo&rjk|;|&1gU~*_2?X3Jx(I=%LyMikGzwid$ZL+U6C)j!xFXUp- zkkOfOC5#4gB5j{$8>Ni(ZJPwLP4V_~d_B(>j|Ocaj^t#q;gUImNI%8~nLre5W^pR+ z>-r{QT!_oi%5q!It?Up+-QtdA+Ho<6_yE32$L~c$Imm+PD0PFgb)PgZPJ3CKy+o4f zgm%cl+(I%|2@!2lZK0AlbHfad8f*YSTjXW!qkPdDb`GzJG+~eIuMuQ*j8_n}z06LG z1HgY5EZ0rY#hN(sasG4c7e1o*%E|J$VC<6-S}q48M{wrbRP5`XDAbt1)>L24@FcHwA+OUyUiXMCI4oG2T*Qz$-YD57NC$Zvs7Q5u9DSePBxYzK z(fy&axO@?cxkq%t6xj-kedJLTUT>5t7?=NAnpW?;u=YXPfgv5a04Z z+o9ub;BjV+(gi!Ss#l$0!?+&##Ip-!JLn~^6)K*`s}GC=ZY>_drNAfNzL7uPKk}Ze zOb%9_*l*=uNX6xX1(x8#YEGSU3&J-Hs*Mc75WFnGT-RFM6lMuQa4iGaJ}E_XM6P6S zAX@jpWdIl%v-1Q^6kI1}AcG+Rlr+)ZL?BCU^5Ovm3j$!7qnin>%k(4}GTIg;y#iE` zg5(OLTvBGU@5likStZYmxe!M8;vf>M$mR5VX?!0Um*_l^)WHqbk^i;d1z^h<6WR6B zrAt!jat(1uAgg_bCBlCD9AD@0y6$qpJc{r|nFa*7%@lkq(}7%XF!POVlSL?RIodBn#C-X4HkC-0X@7|&Jo{2tn?4l;c9GL& zhLOZ@<>u;@8|`mUnxNO>YcEB}eA-O+pFgl<0zqZmL{%Z47Jd2cn>$Yq^K`Mm{I8(V zyn~l&w7gjW`AL9y4Zp|nJP-Jm`w4-6+*6>f>YczH#=LhJ;C~w5$5G>MERK2$UQOg{ z-g92SOhmxva~Y3eMzPrV0{KMMiu&LMb^i;5g4OSz;*~C7X%i<DnkDZr<9cTugc z<3588fGk`!-o)3Muq*QeYIYY{C3NiV_CXZ5Lyc@wo^0Hm751E?o=x5IWk;FlZV{!} zqS(o}6T*JMDF=s3Y(t(CaLvV|8sa|7%@QLrw&m3viO06#yK%k6rD>DzwYl-y$~6`X!dG;I%g!Dg8h9YINf3 l;8aBty}{ryPvcdu)De&i-a@tEO?!>%>??=8W4GpC{|^qBFhl?V literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/distutils/filelist.pyc b/PythonHome/Lib/distutils/filelist.pyc new file mode 100644 index 0000000000000000000000000000000000000000..4fabc3a08b9a9411aafa118ff62a7c7f27485577 GIT binary patch literal 10508 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 gF}!ovhG+N0SToM5f#a*Kl`oQr^UzT=l3l3 z4^}Br%vw>bDD^1zDD^4!DXmakp|nbImC}IH8s!1S3^pijP#V$;qHCgG;~ME2P`p8U zgU&*VLjiS)>jE|@-W1TFxFKMR;w=H&6mL^nhpqS)rJDk7W3z5+3k*MH)o$8s@;ukg zycjkoxH9IG7k!;%qmb-sDJs>ad`Qp820%g zAIyBnV!Ny~vrwej14J*_A?yStjMxvJ0Ct5hfc;PrP=kv=pWPA&2tglj>J)Wb8*I0a zU6yiy-Eg)`MVCa0M4;OO?~Z5}GIS%O?WoAp7S=f&!|HqxVOoo&RJO_J;Omp)xf>PJ z{Vz}Q?DQnfted$kwY8(X(+f3d|9EhO}LxaV+Vy74dj>Nol@e&@R?@EzQuaaHZM#u9ZF{8`dsH0gL}3v z*~5g1emH#i%VTlikDW(H0-m*_j*J~f(NQGmQTyli6IbW?PkZ@H9~x5_NfzsjIKBKa zw|so|pi8weOIXaD*tjs6(}D*1%#K>vJ(BPN2|ckgu|uKJGsC4hqkEH^h85vUIK+2B z=xtV{-dDTcEfuIObx$?CP~A~|_yaQ`k6G+HtT^w^%CJe0u6D6i63p~IKbFY{zbv`E!i$p+cf+Gscwvd~ioi?Kpd|OkybzaEpU#FKF<1*T zSX>7)oG_aXijUVt3~9SAVi!F#{bXIlYHK0}&-0}$%xCLjhPt^9mx0-!=X&|)D`u@t z#*4~4?M-x&NbyOMNs-QS{uv=)5pGDC^7nvtpm2esccFHn-ea}8kAhySEkwMIwplFh zcHlMqa69yu-#$tKE*#{5#bR&n3}=e2q;WA$A!_o`!xh-IoE6#vYk{ z8Q@BTfn6Ek?!;Z}CmHa|fkofJo$O@TboDQzERi4byE0&iby=Q3hbtM;`J0~hT$|Iv zW^UeQE4IOkRD)}KDWz4EK8GumBx%v-v;oOTSV#h4DB6HRWF+R%2SERuPmvtxKF?cm k7xY@0C29R_naJP41F|Zp2HctC>ovT)dx+c1uNMaY0pn!E9smFU literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/distutils/msvc9compiler.pyc b/PythonHome/Lib/distutils/msvc9compiler.pyc new file mode 100644 index 0000000000000000000000000000000000000000..3e3a255ae5eb08e630ff217f94ec053aef38d3e5 GIT binary patch literal 21387 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�VT@Ls#+OFZdhuXd!WBysM3$P4a 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 Le1`^vj+6fdb>GT6 literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/distutils/spawn.pyc b/PythonHome/Lib/distutils/spawn.pyc new file mode 100644 index 0000000000000000000000000000000000000000..5cc2b90eb2c812e4d7522fad8bb387fc09dc580d GIT binary patch literal 6363 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 literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/distutils/sysconfig.pyc b/PythonHome/Lib/distutils/sysconfig.pyc new file mode 100644 index 0000000000000000000000000000000000000000..26d896a1a0a157aaecc3e64b04c607a32a39dfb1 GIT binary patch literal 13137 zcmdT~O>7)TcCMZwhnx{9Qj#f(mMpbw+8oN_I4kUW5u5g|Oj0%%63O()){iOAHm93p zlQZ4Jt{#fCNd$;|T40eNyYVJQHVAS^7P;iIz+Q3*66CN6a>ykJkN`R5kereLfrA`2 z-}kC}W++RsrA-jT@)WD<=T+6Kdf)r0%KzJN>BqOeU9GG1zkdAvCVu*dIi)gf)r|u$S@_BVPpXK}1-M%c}ukQ9szE3p@syU$U4k*jdsjWe^RaAbz+A66B zAbLz4DIAi*;jHj@mKl*QqpW4G6H=VPG_J!>8jC@W?#|i29 zqVk>C2=g#2bN5>}cKYPABM{(Qe>AL_n9PE8G4)|Je3b z&kMM0w?Q`S`eERQb>CiZhjkW%QVgCobX4jrvQjGDii0HaLwjxiHQTnY#hB{#iaj5@ z+x}(yTXChd&;&(@5sAn0690 z^h(OIg*cAl1Tdq*BpJY;R(-7C;5qWJK zo-)_=1?|gRxG*8o7#>V;lTD1KRG`;`hA(AXQ4l6Wtc;^Azn;|ATy1J@#%&*SRO%Ww z(l^ZJsOw=Fsggv$gxuU~t41iUe0{YMtgUkHvKy;=zaj0<-iyN-7rPe^(!2b z2TF}YMx+vD1)0^~_7IV_Ad{!zT&dzOMwCvKwwph`~=Alma|o8qH^Xgo)Y>-H3(x|RX{lnp3dr_k7Cq3o}_ z?M4FdO*T=3{{`J4jMOK{3z;wqXEMZ}$w*NpbjG`E2Nl1P&ZM#_$6H6x7O$J52ukt& zKm$u3HO_xeTPTQ*fc|Oir&7B)-MhxvUk~wf1&6-U zlBRYP3t5)|-$R?!eDEEvg3G%ce9qb8W>9~#!5@}it>y5VOOFl^R z1T`ZYjwl66U!FO&y$Z%$|BtPc4;4 zKuaKVDGL3B$h2^KVGf#M;o9PDnWV`&ls;)lm20rI2lX7zRVI%Gv4unZlkiBAN$rFd zfz-QenuzTXB5{%p0+^klMt4S0&sLtyFR(v!e> zHlY-fK=3Wl5(?_rkTsSYu?p6hRmc_dW7f&snAK-JXN_2=_{-(3yjABWQ7v`Q>MYR; z_J8RyXqEdMT16tr%4%nE6Firae9>O1`*pS-$e=5y?aFk}j zAc+u#Bd`qw{X-5W@Y5N&AT$A6;mwTZpx{!U#VP#rBWVKu9zoy~As2{!6t+q*5_snH zB0&C&V2k*Y0u~f<>;lxv0J6|?W5{SKl|cd%Ew$tH5kdbPm?ba;E@#S+#2*EgBI}vV zbP=p+43-qU+;HDECH8t8!L+pn_u8>PVpSUXoMWRirJkzf{X*Sc7PlJQ12MMb@=FT%IS_H#8FhMMH+EH zMHpp=pjS|b1L|;49ikjvU@3{M#~_DgnLG+74v*1d>`wAC(oLHVsQ5E=Fu<@2FcGuj zCk#4FO{_tbTo}hFFf&n%(UBpxbq2Dtfr=OiR;2_My4Byvs)tc6WV{nSy+6pRPoR28 zg)$377sl~{*g}`iuUeQAf(+xP2z3+bw7{uuv%jzoU~_hx9b>b8F6ZGwGncWRzUOiW z7_{4WjD3gH0k-d9tRh*p@#_#x_W`Y_GYijy5z2RI&QBxRF=8uuosEfGNBn$Jq-bLxO*`G9pW$nG_a zfnB24`W(;npCOr#V2#3XOx^D;z}4G2iJHNOCP)JF(6#60qGk*Bb1YV)i?~4we>dR3 z!TJn+-vf}t0DCtK_Ac8naqs(f-K9a+-ascYpL^mh_;wS4S_U&1SgFSmf;H%lppBTx zu(>f0>IZZ;iUtv!8;CB@l20v8!b%%MiroZNc^{rJacS<|>doaFi+301Ys=N!wYlXR zD~s0`9QdX1q!B3i*^)!+O+4+nIYHC8+qdQK^2$x2Hh1m%)wiqIPEebxzH`-Cn3s?1 z^XUgYx9YNxxax?tcGWR`2)J`AD+0Xs%!1TipEq^H7u!%>SusV%mG|MzGhl@v2*<3a z92cuK`>5$i@U!z>-`h)}Gu-xLR&!a6K)zs`3Mn_PZwBx`%g0eCHfN`QvfoOLS&o^V z1sS6!5T%7NaAr+Kr1xrcCot25#%Ok6d~`9#Bq4ep4Q6R$V>7q3gGA<3wf$bQz> z8}5cSysaBr^3m|p52`I4k+zV*yvP$bu9=S1Z=rubquy#cS5aa}*K75rSH|ZPhgh7q z(dh^H=?~bwFk+3APFh2Vu8ihK@OKj0X&Cl5{^iH5BL0qMzg!8qGx&|Asrk$LGr8lr z<7i#LzvGe?tbtseBkS^xR8}Ou_*!yRc7W$cq(&-CEV8SFQYnVIqIX#6)|fjSxY}nfR>_lcRu0poNs@sR90G}9=gvJOmhbL4YU45MWU+^*C3YQm~rlW&p2&vCI$W+^j1jGoXLG7C8 zJMNU~n-UG%h@*B()DR34QF!n10!Z#Ugs9M4Z{a`zA4HX#b=2ZLp(``x2Q3{LfGwNS zK9qF#>BNM#K#PYU)AO7Eff6mm28Kk_j3DMSM1Ki*RDh1jt5IuM^;yH>F-=&)_wxJT zv#{L!OFGuY-YVQM!U~`b$ z`z2-&ug7HO@6B0o3^^X0B=|Wn=eFQ%$W43eo`ryA=MwtRE~4H`cfF>WImIwEvmkUp}&*`4iN%1~J#)_W_w*kR~< zIWiOskbUCF$JA_i3=oS!%$H%*8$0dX&J}VIE#5%x*3Jd%7O@wX+_(qZn`Qegxl!j; zA`ihRw=aQ{h7@i*q6FWk=hq!;6#M=C9R9xrSl)vFCMtq)$7-4Gz!8kjwCn$8j25TM zXm|?oO<392U;#;toDstoeFwt77VH(TM{lEet>K2-TA-8no-qGIUkfzLHQMB)GXr{p zgp*5U#-EZ?NIDmql>|eH4dCpc+(fPFY(_paC@)w0fLO<4z0WEd1TrhZ`PheJRQH{A z)^D($V9bkkLj!up1D&rBrp2)G>2V#YyF&Wnapnzahk;>Zgf5aIi}9Wy9T~odLa@P|-7PfDT&XD9uFC&Zs$}F{WP;Hu1Qv;*c z`5cuH92ikTLmeeFlsk!wk78zYb$=AO>sr^$`I&GZf%8U?V{I#0!q=Krr(0JZ=S$FC#zwJj(-Pb|GZW>-8zVe~DsGuGb@b3MBNDU3Pn{CtSI= zTCC5=+qCWYVkV8u@Tm%)j=a}-|AGT#<9bR%P#Km@K&mS8_>Phs9P8Zjl~2O;v*nb=HcA?ejUozf|tJsZFwQ36%Qv-t?0 z4z^M`*jXcWxCsoM1s3^8%!MC~H}kNAvlS5((O>g7oL^=u{GK?5Akh&s+gc_|1U4N} zplIl+k-P}VNvo3U>-v>6aOKEPA#=o>f?flTxOf_X^DAc*Qeb&>9VsXJ>qr(uyeD!S z!H2#?_tFa>81*<+an!;t;kJtRCo9X<#oN4OCWcjdGy$VT;zibypy|t$mxR8kg&KMo z_XG&%I^RQMXP(K&NJN!L+0(I%@LR*<6THvhh4pvHDPp(EkHR~wGsnFmFbIeK02x|~ z*xQU%;0CQrm7~n}tJ$;y#$ay+Ts5GiVeSKEvF(7Gg*nJv5jof{$iesks~;fJi_Qr1 zB6@4g+2g1X)03A7Ce!o41G~cBBWf0ZT$q-l*dgiy{W6j-y+cbkjpvR&N<4R?gz4m5 zUwmtRp?Xsk@LP*Z*=LdDm*%d&JHN1UM;>|My^!a86~*R@!N)wlaN#amqGI$kNxrw> zR2P?*M16te{GziY_oU7=DxFCta!OJQE&ihhBx82Xhp#IZr7)gXn3F zLYRDy=OB&7U_|n4;Q33=&)9qASD)y>k#J$PaS3gM){S7swD| z-s2rgdJi}=TC0~?Nr&m=$R@12u)4}1YQQzE;@kSAE~ z{F>`w-D{d9eO9?p*#2VZm)Lc%?o0p1_IMJt4B1T#`QiPzq!!G zgjt5>>g_nDZq6e4&}?t}p&x_LJ{mwdrq6Fod<8G(V!U&q4Uk^pKxqpiL%XIS_VhN! zysEO-aHVgzaQB}+36NTuRks5MUCwTTWXz`T;(e(M)={r`KugtogQa3SQ{&31j$)=j?o!d<WRkFR)SrKbGxw94nUbAlv=@`YgR#td6_LV%`E{}E!$+Uk=yii?7M)Te^2(2 zBdWhlz!xX9R`a5It!BK+TI}z_55%k7no*E0n~Co!#=m)=MqYOPV4v@+wSzLFPbIvF z$9zqBuy&Efa*iUoX6Q{ z^=ak^=FTdUZ!>8zSz~gaiP+K5sLJ^+lV4{-o#XrllOHnq9VWtXGONpG$vue&I*9JG z#%z64?jn~^P=Fd5!ZF1^_?BbVSpP-qMe9=TMHtXyCWZfaZlKs-%ohhoUOM?oaj|%! YI5>1cF6nYZ)#3ym&=rfPQ2Nq;0kVzp<^TWy literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/distutils/text_file.pyc b/PythonHome/Lib/distutils/text_file.pyc new file mode 100644 index 0000000000000000000000000000000000000000..2703891965173ba2b4f41742325e601acf72d6c7 GIT binary patch literal 9079 zcmb_iTaz0{74DH_*^+m&wsYB-1k!fmlGfQ>?g5;Hn*&8E)RJfuQW&SiNYj#LcQm7& z9(lc0HV-)A2S62%RKWwh@kEgqUU-F{z&k$xUZ^4keBbH0$uSofI6I@Bp6=79&*eL( z&!qX6_3m%p{@(sr<^P)a{W325aohr>Zs6{z8=eXpDrl;xp>CkjQbAheLM@tGd&G&;k_U0 zFwRUm@yAAIi6#wA8n&Cw{7mgfU-8mp%@&nI8G$LkpH>#_rk{Ht^i5!E@n1@NX|W zgU5pJ6)}C4yZtF{24aGMaBrv(auH#@z@MgifwDStP0LaV@(C;rLnFC`~64B=P%DH z^?IQSU*x(Ig@+K|=)jCKXa^!*l`14HO3P-DmenW8va8)cN;!$66MgK*n3d=tfhtX` zq3p4-meTbr1v=t0-)fu8O+kd>-x-~Ni`Zy;5@-JHYfh7;7IhzUqJ-3}zWnTE9SR$1 zK_b_-9?$&LAH#OGwzWMB7f$C+!P}y5?FR?2D{$+yJ~}CA7(4dGbZDQkITm*Mq1mmB zLPInLh679ETP{L_D=0+94`j!2@bM(oS?Y%vHl=ZA#xAhzuGU|HFfkvCSfj;kb89ZB z&@#g~Fbk{%J|Wz35@%@=MgAx#2!N>SqQT zO2ydcP>VkmH}tcDR%#YWn(4*t#D-%(lHKWeIUkvHTbo-@Xeca02h(am80({@v2@0Q z5Ox_`JzqvyxPW)B5VW#;@Kz#0ZyBeM8D&ZCCrPQ$aE|G8V9Jm0cl>O}-^s$c0T0Qc zKf}CA7T1#)nploAh#jVZEkq`Otz0XmMSCrrSNDk~u|GF2?7AMG?SFbvBv0LTT zS2I0I<|C{7gC!W6o3Ev5l5SBXqXd}IE2#AZRpb#(AQGv+Scs-J%+8W!6zCBQKrASp zIzTF>3PXiM_A9B-Ys3kiBUN&&OOf`|8%K#1nL3NGTaZ2W5!!;A)Ht6BASZEo8jM{o z7O*#1IZWARwVlDz0mOucLWl(+8d(^Rqh(-ph!x@wSsIs~I9fewCr&cAQfPwhf=oeH zkFghc3usxL9LIVoAVQz)C2$Ga$!HnEzT!&#Z{lsPHjz64Ym_9|MC=6XPbLoAjK1YZ zOQTbhEz=l#ul&DP6XLakE$uvfScDV(-M~zInD;ff_tLymjmt;sNt(V+PpLTwr+;JC4IB zs`GLcesz_Y!i_E9S|xDzY7!9-q%3x~s>w`*hE5cfeSg?s0C+WXqao5Qku7EL>3FAz znPm{xNsI}kTP>xv2=`yewzkbYTyup9VqbDx*hrlgd<-6eJ1lgL<=`&$2zB{Ig7h8( zs5RqdhV(KQGCZ?RM{>W~-nN}q_MZRbeIX24BC*9tESRhT>P+lbBgPEk3u}fH z`2XOW_gO8e2`}V2EMq8*Ymu73FcVAC7a<=Q(%jEr+(43v?$`8AOC>Ouwp+!&y#(ol zxCo#aDS5B7=$@n)f&gL)rHALHAYv@GZ_OM@VmJn@BO27e7U=>kC9Ttc`(0_vw&YZ>`SU{)4$$X~`mhG<$(fz^!V*Wl(k6mV}q zym>gCW%_`8O3)T`ap+hJ&zObCvs1aMj6jwMS=WU|$AJf8X9%(P`DU?0=wdhYkg#Wu zFl%R;Sq7mDDZHx93-PG34sNCP?S?vN@&x$GJ6~3JTj~z}n(DBv(sxvbHfTu? z?icShm3Q=+TDMHEy?Oigr#ZVIc%>jH;|@=&^gWf~fYcz(C&0zgd;EL5;_&yvQk(qW z^OP4q#TIxNp5`{#zzM1;jgFdvH}v4_)WX4)GO!=uR%VnyFj#Y$_T*U^Q`sU*q6N{U z%QUdiAsw*q3)IEat$K2ZUXHFGytbSh5Wks)AvdZ42Xfb$InjsaX2SO$SUJynqq)NJ0V0Y9W5uKc^PU=G#Sw824q6U6dce? z(C*_$$xU{2+F9cx&Ef z^Qq>e-iG&BW6e9)=y>?=)VP5$ytv?XT=sd~aw7&$V$BCqkh$j!8s6y|c>#u!wI{fJ z3*yL4m@?2j_27I^2&V@_escyug2kk%lxIY}&~@Evs_`{dmu3h!oL+65don!XS#cqh9lIkX)$Km_P2TF6^I;M#```gJFk0&EzLe$|1GAG zDOuykXo!l`12`r{a135yJUQRcf5|rhODqYIcwZ!Ke+M&v9r+eYyZ{uN1y}@O^ZtT@ z&JY|+$jQAk&$#QLMT22ILXfHE#I7Du@2#in`HVUt0nUG0*^)%J752GNhbK7jWO9O(G?n(v zh%M$#iJ`8D@*UE7zfMaSVhXcbuG{8RsqSQE%G8{Xn&p^UWv@<$yzh!<=EX+%DUqwY zC;D~%h4@Y1aoQEgfOTHH z3&SiPUWS$K!#)9jx9>LCEk=9~C@G$YSBC(+H&n339;Cq>(^Bc*Xy5LBfD~1rjKC_m z$tmAgM;L=gKFeIly-VNp=Cy6{pDPf8+r^cn7^T!Tg@bP2hV%hXBmi`|Rkd z^h+FdaF&bYG!P9C2k?NLii6g9OkoVTB}CS_p^LaS-AlAyI{IV&s_fdFx|C&I#jnb~ z93MaTz|j8vg#Yki!b40vmoJ~Mg)WlcQ0WIU{+u+xyhw=5f1()hSYu^VPf9<=Z%hCA z+GZgk(YJktuX3&Ii&3#$9&Mg3P{e_I7_MlA&&@ zF%73tIe_D=>Og7c;}C)R!L2Y^S`-dO2ASk#SFyibcY7(Gtd{bn-0Z#>^r~}bFF&tH z

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 F{~I23=u!Xx literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/distutils/version.pyc b/PythonHome/Lib/distutils/version.pyc new file mode 100644 index 0000000000000000000000000000000000000000..9c99d4561b02d0a17e73d8aeb99bf798953d7282 GIT binary patch literal 7133 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 literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/distutils/versionpredicate.pyc b/PythonHome/Lib/distutils/versionpredicate.pyc new file mode 100644 index 0000000000000000000000000000000000000000..5e3040a33e102230926ea5c98f36a44d200ca7d2 GIT binary patch literal 5437 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 Xxn<9d&5t2rkI!6Ksw`C((#h(NiyuvN literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/doctest.pyc b/PythonHome/Lib/doctest.pyc new file mode 100644 index 0000000000000000000000000000000000000000..faeedb901d495e9fbf2af8485d41e91703ade31b GIT binary patch literal 81866 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

6`Q?K3lcV@~f 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 literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/dumbdbm.pyc b/PythonHome/Lib/dumbdbm.pyc new file mode 100644 index 0000000000000000000000000000000000000000..c12f4872d65e76b56f205a8ce9b1110f39a7095a GIT binary patch literal 6242 zcmcgw&2QYs6(5qTm3AfDvMoza;xv<_Y1WRcBuEh;iIXP&DB#wSQOZG7!70HdXC->M zVd+X`b?<@O8t0ek>p}bomZc^YG;nktCdpaHs zx;o5aU8ecI?v5&5CWB#Wble^2D9tmo(Qbb~FLWGMVK*#|E{EY@UCNC(DRh))RhVR@ zuJ(*hve?|!olsZiZl!xkYR<2>xnQFk_VtB9IKD7hphMjaqyA{9^WLGgX_;f}Ac6fo z5UO_!s|f+SBiZ7H-6RW(vE33JZ*OnwTQ~L9n{T$;7jNyhQquNL2A-Ej3QH(hqg)p%YLqhMb04u{=>e})u;g0 zgRl>l+rqmk*NNX)M`5N1qykK*$~d&4>GhH*fhd#x07)7ayU=#6-NP)9%Klys@I|q0 z2ve9aw!m?4vW#NpLz9_!-5OIqFcw+xU6}m>Uriy@Kj0YPqYG0)Pm?)1`d zSHG=a9K49x$$#*-nJCz8)q({FS8JvtG~~}gc^O~%1quU)a+HD9yL1^kk)mI~gWzSX zh&Qm(RHjK+f}SMZfzqPXX(dypCx zM^%oxoM zorolf289+&xQ|L=m8jJCG%bNxy9%1P??8hmp+QeH_%bz^{Qzol)aUOh=k6OciK`#I zs_w&-TxuSwLLFkG2?Dpp3hu*n@E=sMkEbqu{Eqt2>R5D1mNrGBK9%JkXF-SbPoNMq zi?S+`p#Wn(3DXWG@K3W?cg%-yx zJ>rVs>8S1T(~|{Fsmx0$PV|UnpH7yMm~}aX8b|zTlR9I6t0u&q?|xSr=xtL$S3i1Q z6eGHU0^wme#TgAe)pOM-vSF-J#`Lok@*DqOMT}ZS?&` zwzy_xSv7ykgjsT4rI5! zPodHDsP;9S0%!62B)%2Ggh{wKA~Xm-XIE%vsB?h~0cm#Ckbwr=K)PU*b;K`eh(-4$ z1S~`?ik>ifNT^qG4YkpO!uj9k2p1$-C74zwO)Cxsmv7v>^24p`JJ&BBT- zL!hw`e}{7#C^Ddb6xMWtAdF+I{u!zgvlUQYMg&>KZxfjR?|FQUTRepJvo)58#Wgel zc4lccPB^;-TRSM`>GYv9+j_KtB3d(rw zpls~C!qF`h(D2lqEPcX-QZveSBq)jM!$VPtX8iC; z!Z0I(ACP$(P99%o=oQDyFDaFkndj=V)h88CBN3UuLWTMi`$dHg=R|v^|GJVfMHC6lvl?iaX-(xAEFR~G9Uy4 zhx*Zp|2T>qRs2N=!QsRiLEG*Rx|gz5X-xK=4Tusb@g@WWBF~@zI;Gs$VHzXc)d!=p z(p|iKaDHdIrFg6OsrXYh9vTV$w@{J0lhxa6pya>8Vx0wT)qfR5hZx%fL6j#3E2jG* z282?c#@#fJ`lYlovu|5RS+tFiFliehe+6>&JzxW8{|V<@<23yDEb8axBv#VR_=&c8 z<03Aixwlz^y5SLmkiFh;t`+V%)Z{Rj3G#T{;ZbP0`#mU>1YWuAxrp>9pK!xt#d2fW z*y=pQf?!Wg$$+qN1PA_Gp!o-UCFM}|z+{!*Y*TBYu!1Js({9RAtQ`3848Gy|{ zqWXW^mlv5Jm?R;B;Lis(pP-ZF6dikYDP9u3<&|3pQhR$rv=uKU zflY)*JeK)zvrn|z2=THkd>h1V-7j9A}ZwO>LxPeDo!7zQNj?Ea@oH=U;2dZxA9TE*{T>v*fxYPOz2iAN~@ zx#;y;ji#G?0S}tqfrz;n*9}z0nwo<**#i@IL))|$YCMMc8g=FM^qM?_mhc+IY2~RC z@ABa(Hwd0}yfRX!<-f7lO}x-0T{O)vQDN(n-6Qfg$y697!;sTMcCH-eSNp2$n?DBTB}*SGCRoouyu3K)`UV=7c=AHo6w zomkB{+0gnr7%{zYlvXm9M-?`Wxaljezy3N>u~{sHCNhAZq*td&Nqkr!Baq;|xvNKm zu z{Qt!4l3S={4;P1%Od)uSuFXS{lOTxm2)<6Tc_}_#+3QDll%z-N&N%&g*OeVES&MpySAG$y=`P`hv*glMo9+`| F{uh9NtW*F1 literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/dummy_thread.pyc b/PythonHome/Lib/dummy_thread.pyc new file mode 100644 index 0000000000000000000000000000000000000000..8108412edf995a25f09932594012f6cbf144f1fe GIT binary patch literal 5169 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 E0`IUoFaQ7m literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/email/__init__.pyc b/PythonHome/Lib/email/__init__.pyc new file mode 100644 index 0000000000000000000000000000000000000000..c037387473c77cbd74acd3a9ff9d3ab1023627dd GIT binary patch literal 2842 zcmc&#TXPge6h51on4q+cWbI_VRn zXGy<7`XuR7q)(H6lk{7p-zNPI>5%jp>W0*YiFfH4jKa`a5n%2d>GvqDP#bp7lc~}M zoVmceJ48RU;m4j^&BLC-33vdd)6{KH8}42t{XXeS;`e3JS4g+0J5KEyJ-I_>g1-Fm zCbjEi#>v#FcZ4nMAo>Ow{Hst8A%4JHvp3Aq-G!@k5-T{cQ>NhIAGB6@e2m&t^rTCs z2DPeCt3TY=Jo~)rYcEi(ughYge&6ccA*+kQ8bDfYe#9^L1%_MUFz!5vyC&Soa>%(& z2HnfyW<1cTND#uV8JIkFn1`kxCu!I>*5ZzB*$Q;bwXU|VyE>%%u{9shEiEoBxN%J9 zH=)lsHvxHJ(8;vPt*i1R&ohWMh+li%SuPuQOpHUavFO+)A7fQZ-lFWV{#zrRWTKd7 zw_$g0Yq1a4+!4Nnt=)^0yYo@%62$4;RI#$04VLy6*;T&woq6KKqZJMzm*^gjvSFU^ zuH&%3cS&m945R`MwUK9iWnB)S-0|nvHC7?8@yhZJf8dJ4L3muWko?GpV; z)GN`p(0#SZckCk!f>IcVKKL*hxD2xb`!KuTGaVQ9L4dSXuZQ^E8@ePL#A&EHX>4uC zG~>%S7Uu>;wASblTHK}y{TqaxY=9%94oJ}wCCOj-H93Ij7zT02H6RH~TRw8x5~j!; z8k!ug<7-x+iu0~@9Lj^o)+>TcO&;tS4D+9^uWY%^Y;f(9^)$J^F51_XN(PBjsx{n- zrg7>zA7{-}nF{_ps=q){gog%<%p3to0tgdl8470x5dKG`qmW%>;3XZzIS*|KYa7Gp zEbpJ&JtTO(3aFe}H}LI&D$l(v4}3TNd26vhL_(OngER8u7rl+op2A?z9YA7|?ts!B zh)||zwaM;vc-Z~s`4T5APJ!mLptr(=P$>DxvgJJToD#MPo0J;FeWR2d5gu8SZb;n$ z(MPF~{a1~;Q0=MpE&IhDP$2%6A@L{veg?r2r(!SQ<`cLQ^^m4AKlxOWv^Pe*3a2du zIa1{bLfk1KHpXkY$<xmtP-|Exgl6Q>CQ3jD|XPzL25l#tzxV z9!3{g17`z+B&wj|mBHX5u2i8|sbx&<1O^HwgQ;L95W0D9x&0_rAg`iJm_~CL_HByv zk_mkQH^0Fr+^Yt)vLN)8F?z+9Q?8%B2XTJnN+A@HG|=tn;}h6IVKkQabD4T|8=!&}>m+G3OUnDo#_pELW}K|@8|4>eTJc0s*aU|m-;Kc_*8A8R;x7{r4y6?uwOa2UMo)q)4}oJ Mbh!Zro?t2X8<96^zW@LL literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/email/_parseaddr.pyc b/PythonHome/Lib/email/_parseaddr.pyc new file mode 100644 index 0000000000000000000000000000000000000000..7918849a1afe151f4a221e13d68f8ff62510a519 GIT binary patch literal 13690 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 literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/email/base64mime.pyc b/PythonHome/Lib/email/base64mime.pyc new file mode 100644 index 0000000000000000000000000000000000000000..73e9bf39f00aeaf336c4ebbf9bd907b74d5076d8 GIT binary patch literal 5298 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 ZkN#bl7HHyMr_qhJo1Ipt*XiQ7`zOH9)I$IO literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/email/errors.pyc b/PythonHome/Lib/email/errors.pyc new file mode 100644 index 0000000000000000000000000000000000000000..8971f91aca0fd91c96436b3b1d5fbaf57ab8db36 GIT binary patch literal 3454 zcmb_eZExE)5I(=eaniiB&6+iBhjA#-cvzPK1%?gVu&r@ZEWlzEO1Ggw0FM^wn5aY= zBAqlqzpcM%e{6qXca$g#!GOhqY><*p;vJuRd5*1r)>r@jv;|@bWXnrCrL+xVIY_&ubP2=?X^~|MAbn6uH$gmv&xk}iS$8Y(WWb$1sr%oBo;)Gi(?Vel1kB+3Z z`1&BrOjbG`-3|LV>;|bp$D_Y-ZbEcSp#b{@eZZ~Eb+NI@m?RCBDb3sjtyOLB^(d0A zi_>tZc`AoPx9T5KBW4LbF8fDe;^DA|w=kdVr})_a?)25An;8A|&x4S#EmbHQL&Cy@Yni)nV6!VBgHN;MwJZ8TA;K z_RTC2de^bB(tF6f zi!T{y40=>UR|v!#8W=4j3g+C9zq^jLh`8`ESs?(OMyKf>;?2N>;yl!4vS0D||587N z<9X>;>?JCdSgeMPB&%loXy(|23#Rc+QN6@N$o^Q^wWSg@sLyc(1|pcp4r@3d9T@kL z%r6R)I^1h)WC5ThrE?@y6j~xnVDCfiwc*)Bvrj8{D2OjrW?kM4e#Klov`8_?iZi4} zqZh^XJt~}sj{?M5T+zoU-5H`&&LR(^WtMjh|DraW)Zf0U;3PUYQg)i~Sc(Ir-^5I1 zj(JgpKY4_^ziIXE%W-DX-2i}M=A#u3DX9_yyQ3MS4+@Z@#KdoFLrJ~ySp_9^oFks# zaS3bYX6Rm^3ZKyPJ-Z2ao~2V|{n>;fni&0*;jxTB8$6L^7YdJSX)s&t0=8jYxNM_rm|WkgICQTaz+C8bV8&W*_K4SIm@ cI6veE>>p_lzK3?&+r@vUz1`XBY`4PyUnSeq5&!@I literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/email/feedparser.pyc b/PythonHome/Lib/email/feedparser.pyc new file mode 100644 index 0000000000000000000000000000000000000000..4471a5038541a81f939bc1c15f66be6df5e78ea9 GIT binary patch literal 11027 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 XK~usPZ}|NI%1D0mloLh^M?d|4$HK;N literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/email/generator.pyc b/PythonHome/Lib/email/generator.pyc new file mode 100644 index 0000000000000000000000000000000000000000..bbbc9e046368362e8e54eb1d75c6e2f714c674e8 GIT binary patch literal 10095 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 literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/email/header.pyc b/PythonHome/Lib/email/header.pyc new file mode 100644 index 0000000000000000000000000000000000000000..57323cc5de5f0221c5401c882df9d96bbfda9897 GIT binary patch literal 13422 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 literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/email/iterators.pyc b/PythonHome/Lib/email/iterators.pyc new file mode 100644 index 0000000000000000000000000000000000000000..271a01da068d87ac1d813076d8c9c64e3ec8217c GIT binary patch literal 2341 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 literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/email/mime/__init__.pyc b/PythonHome/Lib/email/mime/__init__.pyc new file mode 100644 index 0000000000000000000000000000000000000000..7779e6f6b08d4aff4c8077866af8e4e61b4b231a GIT binary patch literal 125 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 literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/email/mime/message.pyc b/PythonHome/Lib/email/mime/message.pyc new file mode 100644 index 0000000000000000000000000000000000000000..ca2110e43d568e48a925d2de2b722cbf96d7aba5 GIT binary patch literal 1403 zcmb7EUuzRV5TCvLX&cd2`ylAc(g!)Eq)>eDK|~D|3Z_C*P($F{+-;H#cYEP>QVI0Q z^i%jj{9=9po!PsjEePt7o!rjO{AT7ivse3hxAo)WmwpV@Q=|XawA?9)1Ykf?z(l}6 zKoUSwgEWAw27?+1-q#_mL)L&ngZ2V+1IA?7fGdC%z~?~|k|y-SErvWK(Mgqave5HF zJ8jX}iOjTfYNC&x$?j?QL?(H>$mqzm@eVn#u3K7|U-X26l*o9MU#ZxuOwV%LU8HE{ zs=!TA0Uf@j3R+pU(Yo+xt@Y23Ag%ttdFqf|DL*}|b55t^08I#f2+G9SyT z2Zu5*q}m`Qx-b_yk+E;Z5Eh;*sJjOTiMD4TL1L!8o_&uE#Ts{1!#V8jK=r(Z;xSk9;J5FRD)A4xMk9 zN1jrJsNyN|U2z&CqJz1Lm~%h-$aCv-I`%I-C1u2_2O*t;7w$2=wTJJ`Xs9z~(qU#Y zJzRHWzU(p3eOiu_gx0=zAa-l}LCE^53ac_*RS`v5o-9({^2LrK`UXUi2f2>~h^M|s=Vk5J8U2j~U+BxS Sv{(MJZWBl|*a`N;Ui~+eomqtd literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/email/mime/multipart.pyc b/PythonHome/Lib/email/mime/multipart.pyc new file mode 100644 index 0000000000000000000000000000000000000000..a8d371360e798fa214b187da3f317ec234574399 GIT binary patch literal 1624 zcmbVM-EP}96h4w{w+WW5K#SgOICpc4RJ$Hf6kEFuD7N$>8Co=Oq0l02E0IK3q>viO zuG-tZ&YofKvj^C|L&lmgwc_i1e6FrV~k#qIs;G;k;DN@xnHI^z`Uw zuG-QUYt{Jg?z7*l4OhlFwKOjE2UsF8N86C%Up&(Y!~SMJCn*QMBf-Gy7>xm6ut5u^ z=p^A6(>w4T(ecStqCbb$80)IyjnTPe5OFf{D_(bo#uJ@KbQP?+LT5yO!k#6`P!`iw zLd`Gq<{Rn!^y)VKF_ww*gs#T)HlpbDA-$*(98)t3Gb8EC3`Sx4$yBQ1{*H;BG)8&j zSbfyQbbp`w=kbQMStwX}$oU5r21Q%*5Bak2D_%EtZJHs)6I**z`v<>EnN+Pq0Uta! zjVo-;E2A{J*B~?3&O=EH$9`pa`)L>9bErJ$UE)yx!!6CCUb43X_*o$M?X~oC+tyk& z8}8HZ@(nZ2H%OB*@6>bQv0zA>t1@p(*r-`Ku8q+~U&9ayvN@fAD0b#`YwFxEBouYw z3ss7$E<(1n$Xu&UX_W@*Q$OHTt@At=+d#lHYF;AA{M_Uyhimhdpers5=dtdkZ8=Az zDlgS$$5nZ+5Luhc9jLdRm))V^`G#8;oCA?AetHj8^(%W_){k0)ysbeW+!f|gxo{>$ zz%F3!S?A3*-dC}NPFb8QDW^-v9_}47k3j4$H6i%#h%3*3z_YAWD1d)Bzy>v+6 z_pqaf>OGsvaXKDOd6tROSr(2wvIKLz9J@}R|3c1#@!7WO;lAl_}In; z*rCAw2GaB-y@0Q$Xec!9YxL6DZ^e9ODpi!Ts;JCtV4SWu#{zc?ulo`W-MKs7izm@R zbSIibouH0KR>N#)*+)>8RaUp9dKq}*}%R3ZW|7pDuCQ#6TtKZRV6 uqskIEUtu7qNkvUM$3+@UKgM_`dk6mi1_XHzJ3)`6fKDnjiTC1LqyGQ^%&M~h literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/email/mime/nonmultipart.pyc b/PythonHome/Lib/email/mime/nonmultipart.pyc new file mode 100644 index 0000000000000000000000000000000000000000..e50c707a0f72f091fe11bb5453a1c8a561ce9ffb GIT binary patch literal 841 zcmbVKO=}x55FPDTlR#649@?XhOQG9KFM(1@Ob&tChxH+3F>K|PoNSR+W+exFP4b)a z$NB@38LjO$&_k&}vl{7X-g~2sf4x3>y!o+&nFj?bM7}Q z#f@@KTr0=@jqqIbig(s?v(~;{iQX4}gtrMkwcTX5+dkpQ8J_qIgX(+RyCFZ=!ijM2 zj*w?K-8({~JJgC1eK1mtrpj3!5uhOCU$pK8efscHchS(j-5gVmw-`LYPb6V*&)_bw z4Fps78BfQeBbUN^(cEw$W$Rnp3C-PlL9VeI7W>eB{DU^=D}(3vSYqFcvF&bE@9_RP zwIRTKLOPUQdU}AB*k~(cj!Ou^aan+a literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/email/mime/text.pyc b/PythonHome/Lib/email/mime/text.pyc new file mode 100644 index 0000000000000000000000000000000000000000..500fcdba1fd019682a37fdd8af83f0fdad913507 GIT binary patch literal 1263 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 T4*_-Q@)~Aqqc_nGjhy)(!1Q}G literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/email/utils.pyc b/PythonHome/Lib/email/utils.pyc new file mode 100644 index 0000000000000000000000000000000000000000..15fbd0b03073655426dd75835509a51c541dbeb7 GIT binary patch literal 9083 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 literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/encodings/aliases.pyc b/PythonHome/Lib/encodings/aliases.pyc new file mode 100644 index 0000000000000000000000000000000000000000..8157ed7af0a5e14c1ad7a54053bbcc2bbf162bc3 GIT binary patch literal 8765 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 Ic)Y{?7vmK(bpQYW literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/encodings/big5hkscs.pyc b/PythonHome/Lib/encodings/big5hkscs.pyc new file mode 100644 index 0000000000000000000000000000000000000000..579c76595cd09a381148e5f0f1d9650ede56ef72 GIT binary patch literal 1705 zcmcgs&2G~`5FY=;`Ki+&1gQLo1E-vN<5r=Hz@ZZKusKv%kxb%sQm3(lyj!81!!z+R zJO&Q{-;5h4YT=Meyx#Tf%oGPXuJ+Bh@x6{C~`J> zmm-f+qPb7nr8P_q($F|G4`>QEpMDUniM~Vu=?0}9&6{Fw(bOd!)aDjx7+`LTxg+LQ zZSIhUArOxv@d#<^k?zzUA!!&YkFIzei$_>{9Fy+yB`Jj_!Rl1hJ9G6&&zEKLmU_5JdI=9kx9PP zw+o)KL&E#p08(18EFx48t6g9rk<2Sdr=w5VWF)RxF*BnY?CH0aVss(8;iC(jwqqYd zxG0h`&C|k;7a!#p<->3|1$8))TZiC5uUsBP;(hl<)x@Gl=!W+R-20e5NUR6O#HaFP z2NP#)Xv=h*t8}c>1Eb-pJE_q)c8lh!%;qN$6e2i<`6=NK%w4qD>{dp)us zJv1PqzmahhGzcXQZlk6_YTG2;VnVE`IqY-HmzE2PxuNhS#e7gq1*ws2TelT8%KPey zCZ*)d$m!t(ae6z7?~*|In=ni0W`yShX5K|HT?%iuKUZ9^iYr7hNX7Zsx9IH=7R^#% znt^!b>NTc@NkCv_;Dl&_v_31Vd!d3BU*9Ovak}IDc44#0$_hsk%OuPviCik!T~;X0 zp@d-h)IM)kJfyt@_Ftzv9!lW$>F!Ru#E_Ky%Uo5eBunwFvvND&Fh5V6 Q(CxX;{kHSWbs{@!7fUxqRm`^PMA5-;ubw4dP?-wL4%T2nP|$y z+I*r(Nn0jbGI3@;(W0b7x*>C`G{P6x=X0x+Y|Q4?WNvdlw?@fXemQ6}U6Wn{`+JqYUW>hP{jp&GyN6MzH71u!D{T{8b}5S zw>=(y58V?%#={!fEpkLZ1mu8#8a;vS1Nt6BjaVNHwe>m`J*c!8 zPn-zvwPjVL++>_-)h#Cub0P)X#VhWj%5-rEwZ&y&C%I0Tb)M!&8&et!HICAv`iu;z zBWO2c?YmM%<8e0asoRd%MUxD+aOM1nT`&9YVvDyotSd+;vZ;zE#^}OaL)38|bcCtBnH?Z!-JP9T5=fR`EMSsSHB!E>F4!I?)q8L!9X^<0+&-8)1VH23Sil1^tvB&z835GY3O0j(6#zdo0B#7t|2qJ9 zH02Yx?vP!o0!`%`V^e;c&hR%J4dB2=N6Bz9nwt;w2<~OG()Ir6xb~u|CTAYZ9-HgD zG}HO^9N>b>j?xV9i{NnjyC?^kEk}~sKF@}rk%NYO>m|l;2*XmyPA+KT80JH3$Osq2 zhK$&dffcrR3~gC}`q20mHhO?=FhIo<_BbrZd?Y{2$8|KT&}k$Fge%EwoV<`$K-a27 z7WO@JSV%ED)~xM;w(IB+-w^H)(4KM}V>$Pw57{@pFS3kQXQPFP%Sgv6@vg_A)iU!G zEXfPIuot8Q>c#o+8h#&VRDAdd#i9-dMU?BoKny$>0LC-`fJuYHMa%gb`cw$BeX`DPZj2QyI#P$=k2Odlz6+MD5*$F?kC$*Ov5fW0 zO$^)v@q994dqZGkwHh7Qxt!rw97Uw zNrj=9iFYlucB;Z88w>_%k-EX)Bkc8F5Nri&9xp8DT(pnz0@Rud%=|I_Aygpg8HrhP zGYV&3C8UoP*^Zvdh0NE|yz#kLd@1w^>%eki X0K$XLN@t_9wcXl2yS=$n-)Z~?wPuy9 literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/encodings/charmap.pyc b/PythonHome/Lib/encodings/charmap.pyc new file mode 100644 index 0000000000000000000000000000000000000000..55d7208b98da265db2c1bb3c8f70275b4f2b895b GIT binary patch literal 3278 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

LtlPQ)lmAmP5` zJ|*1u6^?K!?^T6g#gG4bGW(f=xX zbJuCmglM7BAvC8*Iz$TzE}=Wb5~qlh>=wO3^a!!2#VIt8G`OU}n>VT~F(VYU)}bZe&t{@`gE$ zjrHNVk;(ftgQ~!)Q2iVjl8O&X<<`&U}?ha;Po-yuOi!3;rA!* z(-Ss5biO<#kFAq5)$Ce;2AyIc3?;n1`XgA(lAAGWv50((%DW^`k@;}#>fT9DCCeUC8?ryUZSmaXqQ~8g(v}GEs?m4;{7;y;dq)T6ka;a ze}bCemMSR@_g`V;6-G`epy7!ewsvN$9ylCiFial}(P&yt>Cvd^my=XR>rB#AVVlAs z+6PJL(eNm=KoruO;{&|TB9}Rig!**M&{KNaRFkz5J0nI~`Q+I%fuBNJW(+6( z?*LCGtxXf+3o*sTOrd*S8VT~Y;RFprhAP2Um}e3^g}sxkuu+w?h$qr&(vJ8s!7@f1 z-ov0OMSMsx4RXUeHJQ^TnD(y!21m}-*rBbxj*%$VNUHolC~|r&6qzz3P*k``*`YoL zK<3vZdjAtD`=U0em-1IO^EeXG+1}XYJ$}MxXRKcqU+-xlBt(@ zn8ccw3pO=8lbVx{t45C~hyBVPM&GiO+H<=q55<@Bdd;mtiqQ^VHPM1g~IuGq70hM%XXbyp%!QwT~leA zV=@Xyp~LGaqK{X8I=h)d4yOwa6vFD|up2hP=21n(qf5q&9XB3+gH=9Q^K2<>gDqvx zJ^uo9!wOglJ<#iaW(ur@b+8^bz($X^0Dgt7lVCgSfSs_*4SQfO?1TLiCc?qV0XT$5 z@E9J#!*~>r|AhUxreap`jj6BVX*`2x@f4oN3wROFVc+1v!Aq~d_R%+QRpLtQ#co`I zJ-F&C+A4qXTJCT2XF=VzleKrAM^z| zTf|N7Wm+aiy^D*##R;1UOahAzQ&{5CWpb4s`ti`#nMi6@Um)#6e0lU`mpycr)ir0k bXkm`~7&Sh3sjt*s>MnDYc?wIs_l5f}Y1w9+ literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/encodings/cp1140.pyc b/PythonHome/Lib/encodings/cp1140.pyc new file mode 100644 index 0000000000000000000000000000000000000000..fafaf2cd8ab10c93d89ba79cae836c71b42e0583 GIT binary patch literal 2694 zcmc&$30GTH5WZOnVe786sHq!qDJ@#}T9LF>v_*VDX(O73ycY;&^W`C;)fPhcecyMx z)4hf6J!j^h_!s;Eb>_Y%571L=&+(Y>E_3g^J9p-r@6N>WXPI}fWoa-f9)2A3zmA^l z5DlsjAsTH$wTpyJgh+4*%_chSB1W=P^b3&_VoAs@RF_mZq{3ZLID}dx6;7$}6ckRO z77NWTbuJMj1KxtpCDf9<&MkGN1)W={WjqNL3AJ2=JkkJJ@`xNc=w(lX{t6BtMuV@Z z$LL6>e1VRL9*G*7?pqYeWa6oIUm&e&QC~DuTRVG}uU$)Ndc@FFUrbLYebpJcYev$1 zH#;-X#IMyfFK({(b;pek-VkL2HJP3ouQ&dHK8=Qp4wPmKVA^S=o_+DrppnxAn#8l8 ze5H^{whNXWLJ9gAdc)1H8+tryM0w7Slb!%CPo%*RqSGdp(Vtxyc9C;XxHejEw6;sn zvPLlOe=YnJz>6q3L>B&-zIz9)&iDVtTTCfZJZ`FeZ@Dkc#SB zQcD?;#C(aJ9;H?JDX?b}O-=UDg;9mY7*71(0iH^$7EOpR#1scJg)VYs(9dQY<1`2v zssvkMo=NZ&_D-_GLRHct7EeVIR>Wfj%NTKZ!$DO_`H(Uiq`?J|L{^hvT2}uJj-0FU zdDCv&XcXs3s{B7Fa(Yb^nKGkLRJbZxp^gC{^J@w{{|ulqj#N*;LB?%z-YQ|o83`J? z7D=|~aVn1m?lH6K`9)5o$vvu2Bn!zOE0tD2QW_&FrUVxe8P$mM6)mFv_vdp3t+LK9 zgv+T3@Om8$=G`&79`!q}vUG{)`Z)74H7^&FSaoy3rVeLNH}Y`R$cdt$pJ~u&@I~SR zBI}}AC9TpSSsSc)v=CM z`0^;s0)?SaI3JIdL4$eOu8}L$0u8-qI!&`oMqw+qxoxHNb<1y8FH^{7cff&SShXB> z!$#OtQd(ACF>d^XiEt2BdSLa_m9PyqS3UFWbFcz>p$~GJq{98cgWybQ-`=J;P*_A;Kqvv>|q z<9WP*7jXa&Pk-^%S3ZD&88fjD`*8*KVh&g0YTODZUwG>Z(6{9`{7rqN)~a?})=WxQ&R-2Cn*}Zvd|U zmNmM5?Eb0eXE+M?aSI;ALvZ0cI1VRZ2+qJM7=$};7w&!YEnI}ta1D3=@^O7&-uwlh zeA)o#@fr@|6}*bqfBo$9g^L=$X!=rtn|K@V;7z=R_gir&*!s^ax+uYQEFaX{Y_F>RA3gEe3-@(*Diz0 zbpF>vTUR`xnvH>0hY{w{w_P^TIcD3O>!6KUZe-N?oRywRXQi{sQROPGa6b^vzW|<> BWa0n- literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/encodings/cp1250.pyc b/PythonHome/Lib/encodings/cp1250.pyc new file mode 100644 index 0000000000000000000000000000000000000000..d0cb7437de6aba9f1170dfc859ca5c78314f7c12 GIT binary patch literal 2731 zcmc&$dskFd6hHH17(jd%N;URkdVyN@G(!e3N=CXvqC}0Cxp!b_UfsD!l+_3nwMx?^ z84pn*(p)Ox${;D0&1sVNvFLKe?WBj0ZbA+=T8ZS~1{*gx zvj!WHa=5|H4X&)gPNZBSTe;0a!mxomYjY4OZ^7o|w*0KkNu&atH0BU#6=`(w4PYl1 z=>`Yg=xM-Phyfgi!Bf|%wkF~pU#qByAyrm9wPG?EiMM!s2}urlLdk90cWm{v$Z=T_ zRax?cl|;-_QoFmZuExJ7P`1CyU%5{Rl-1Vw0@d|p4K*-r2$cEia9L^nf%+0pM?`JK z4MMnKX|l7_?T*}n$FDlT0e(ytTq|fQ&^HeZG6Vr2a(sKhcYpw7D?!;tgn$=Qp*r#F zsuBsQA)MoDhu4Sdbug%ev{}dz__Gq#O1fP2ylpr$)MpbS8)*# z394dqR5n)O2`M=m<{?Dl$##|dAuCEkNqNCY_>d|BskCWtq`7HfmsFDhDF9(C;ke}C zei%Hl+)ES!E?we3Kn-wn6&IKKFCg*)A}8d)a90i+J0n)N9rhv^stbl-FfPXAU{H1Q zNh~3?M`0?UO~4S%gSd2Ocm!BLa^X$k0ZwbaOo#sB&6_ zBXKcmM!Z6>h!KXj7*ru24=I3wZ&)oxQ!)qB-1Xn!h`Cy`u(i{&9K}jbmH!7tOs|0= zQf3*70#+$A)D-|ker<&Jp8*tBgXtbPh`4Q7*cGtDj099g7Gn)c1j=QWd&sN`{30gO z;2u;ckO}9HnMyMtF0Bw1QUZ$zk7~*Jf-Fk^{rOlyi_P=1;bLlhs4s`XxI0D{g#L$B z7A_H7ANzs~&CG!$mYi6yq2sC0om^Nox=BvJi!|`7c#*Jx@VaPJNwait)<(>`Zxm={ zx!R~s3eOXC1;`V;fYTyH2TvS7)2N$xI&VWY@o<7y9rIWLFOPsM5D*Fh^Kn-hRFRi0 zGPnXQP*pm&z%+$qB$ix@(~=J#C;zmcMhaQ1HoL=_gi`n%eHRY{_Jx*o`2!RmtKBl=c~J3E8kt=tE{Tt z^Lou2Z|<%2@2h)D2-Ls5zu~~a#&??DeJ^-OYz|3sxTQ7H_I@-LPb5E3Qfm9*jt@IO z`uNBvpMI9UC=ISKWUfPS?#iRMZ2nvvm4rk zc5Qx$b!peNU$seXO8ZU!oSoBd=(F>~`W(B-`sh*GrFYRDeOmv5_Uhlzuk?QUwLVCX z(c}7Y{RHb~z4R3AV<+fo`aSDs<8+Ws&@*(HjnZ@MJ32x~^=>+*&*;7MqJE5C(g)~e zeTZJA?EC}Q*40!OlR0NdXvtwALa+Vm_uMJb~q^!f{unQ!C;EX z52S`clFcY#K~u4IFZ`rvZjVGIqg#M>5sU6z0(fWLY4p-vHdvU#?gs79UgRpW7ukz# M#g5!U=PhFY3#txy3jhEB literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/encodings/cp1251.pyc b/PythonHome/Lib/encodings/cp1251.pyc new file mode 100644 index 0000000000000000000000000000000000000000..c51e6e08bf0b079ee7a68ab3912bc935d9cf91b4 GIT binary patch literal 2728 zcmc&$d3O{=5br&+SrTs0K-9&H^-2WA6A`iyjFKhJMglRqOm=3I#l4)JfKk*T2{!^E z93g}dB7(?aPyqpj_vRB+^AY9?_=g_=t9r-|pbv!ie9mS%-BsJwRloXm)q4Ic4_;_m z9ZRsAj|cxR#J6w}2Zga_99>Ltv$Tsfti>VJ(5biQvY|-3tjP&o)k5`hKA+0Ag(5jcO@tEpIdkXD3AL$NRg-m9 z2_>~$CN#T#QA0yrbZM-5#ggdaFs17 zK?bYxomIhL>IObh-G>f{V~XIqQBp&`g>X5K`HEhc5h3H7%zV!l-0oC{*CAs%2TKwPnmop~Z$2fv~p-T*i?- z3ZA(hBnpYP-sV3-jc^N*nBMNcM952ooK%9teK~AfCai8c940XI01okZR?evLxE>UX zOit-Y<5D7>L?Jo{iP_!Zk#GYm#kW8Q_}yh5eKJn!vI$Mis99Z3FA>;j36zSb$eyXV zwAq6fNMR0RDDi&>cm_%xnjl}0DIQ`9UhIlkn9N2~I4}{a09zuS3GgKHPO!p3RnQ`t z%F1ac;(G*37*Tk)f-05KA>}v-gSB$Hpb9V@tN#W^%GIPX(|*^TC@vOM`F~KP^x7yA zW$r*xqAKNtdJh1JU(@mZX8@&%sCobn5^mGRtRi-lk(jQja;8a3VYw`FkC;_MU!+9Z z+`|fmb0+xXq|ymU%Crq3)dCJsj(;s@c zV#dtMM;?7FH0$vvo_y-*+2LoNeeU@es;Xa{Gxw#J=e_dkYp=iY=KQx7yuENyO=R(s z+NJN*z5Cv>`snh8_oZ0l2P>LZu4?|U<)e?|tL4^&q9)tgQ)@m+XR^8cr&>YpSiA1C z&d#2kj5dFct339`}hIa4ZW}j`d}~YgZ*#-`r#l9z#$lf z!!QI#U>J_V2z(32;5#@DC*XTH2|vIoI1OjuEc^(ga1MTgpWzoc4;SDf{0f)gGF*Y* z;CHwR*SNtq@GjoXd-z7aiErjx_*TA+Z|6JsH+(1G6{Z9tU8%h(xdgT|>IXJW9C8pZ zY=+FF8C5f#3isIWiPnx(TCrONN^hai-S59>tMlzfy1;`Q3)I@M7kVoK72XPOrKi$Y KI>CQ~dH(_hS9iz& literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/encodings/cp1252.pyc b/PythonHome/Lib/encodings/cp1252.pyc new file mode 100644 index 0000000000000000000000000000000000000000..3eac5e525436d11e740c432348fb3715c24aa85a GIT binary patch literal 2731 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 literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/encodings/cp1254.pyc b/PythonHome/Lib/encodings/cp1254.pyc new file mode 100644 index 0000000000000000000000000000000000000000..d174941e8194e72b15957916b301d7a26825f11f GIT binary patch literal 2733 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 a=CHXzH*}Z#%H8Ge3Ri`vc&7InasLHj27A~5 literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/encodings/cp1257.pyc b/PythonHome/Lib/encodings/cp1257.pyc new file mode 100644 index 0000000000000000000000000000000000000000..830e5139251975e55aefab9a69eedb0d2a8a198c GIT binary patch literal 2738 zcmc&$>vt1X5WmSLX_~%xYoKcI)%a=!MSLKZrY%NksGCY5R>O98(+2Z$v!zy115L~E z9Qb0j4<1?yR-p(;rKPmgbN2D6|3&@*KllgW%w3XgtA`5bcucyJxp(&7JM)|0ohkEY znQN-`V2~$wKMefV!jql`ArKM*X(57@#4IEP3PVH-Ib-Q}=xNYffdL!_;c4!XJCg~IualEFUKS-!6PHRw6CEC3QV@9$pW3o@+jdWfm=GmS z76ng4O2$1^O}m<#{ej)Vntcs{`n_zhrpfOMHn!BX`eE1_tnoGDvg(%oEmfZGsN9Jg z@VH@hs;AoJir#@wK(>Pe^q2y;R+y%9r(H| zMR}RWF+MhUd^o)pgiOdG3poORRw7$TF9YFQU_M|jr=F$da+u`-hd7rC8}8C6ssbWm znQM=U#wt7^Eyf}=glHnwB~w2{NlHp-FBl0GX*X!qZF{2aZTVf&Z3d(Ogt3I;QiA(o z@Wk>UQLwmliT?mKz)h#9y3~Ibk!KM(wg|+1Ic)5VSlxBli(tr35aDowi;Ll~?4pBs zQs|1okVPAdA({tK?cVUPuz(c9lg0xa)>1}Z1BySvOJZD1$Xu*}Vkhx1OFsqntb?J! z9=JdPF&Tr2|2x1NVb-Jx@CBH{AXDICyMtcbHV_3tXs8ry7I{X&W6?Xx3KLaIi%2xV z#mtCT2o^EI@D_v0mf|60An1mTTr4e8FwI^64UU+r)%mR*mgOkcQ>y$wC}MgI6p=E^ zP-L-6nW3%#Ao6PiJpT+Jy9!JXz(K@qeSTNK4l@#zC6SA_N>M161@0lU>hMKOq`^I? zP@ogaA2XF^KvY{HDx?G!5gOH!^I4G-{`>Q>f>xU67sAEV_;9`!gmHI_E(rY(t1Mh1 zxIVVL4$aJtBo-W4u%YA0(4CxEHF`-=(2Fz($as;kfY7>VR7taRP}WAxyKfX|Y5BBK zog|tk=n9Z0cmStG6Wug%^h~2};_0*v`4f>OtvcqhEM6WKS->I`Eav0BGAJW2J4A2= zTA(cTY=&VP$w(~47Kf!2z7G2BI*SytSQ(q$QRFOkm6Vp1SFBpSX6?H58yV0J zBac4j+5GquPd@c@mG_xvpL_m=>Y5j~Y<=nFZLe&9^|jaE*zxAhw`zCQ`RW@Qcfaj_ z=iNO`fxXS|vB8%2_qFan5c;6)!;iuTxprO%DJ^#$?*6prv(Jxw z@#R;!W0(K+EqwXv!fE^&MKPwFS1zD3uKc79D;M=aWkR{E{Gwb@`;}|TugZ00Qu$4} zp-d^$>P=-vA5vzOIpwx8ua0Y3?TVJs`qix3rwwc0XeZRK^%-qY8`Gw=OWLeHs`u)B z>VSSi{Z1WJhxF_EQT>#DNj;;_>bKP&v_9>sc2qmAUQmD3MzjI#q68N+2#aIw8qJW5dp15XPhlGQ{A@ zCe*O5$ymbk|5>zmMPq`|G+=fSneJT)XoKBhwA7spEKFmQgRW?EJKZ+7t&*v<7gsp$ G5Zhn={(zhS literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/encodings/cp1258.pyc b/PythonHome/Lib/encodings/cp1258.pyc new file mode 100644 index 0000000000000000000000000000000000000000..f5a90b175120562f60f18536efa0dc25391494c2 GIT binary patch literal 2736 zcmc&$d3O{=5br&+*(BVcfvAfY>y-$Kq9O)10i$GzvyniIE|Z8t?Krv5k#Rrg((HB^2Jg z!o`#Vp>PX@FRySjrI4vkq4Tgf8t~_J9;Osc>byc%oY#4oQbLo)0;Wu3jXq%jE%{g% zI_M`)Bf;quz-Al*bsc(ZCLIX1%9ntC)=80y+L};gb$vxc4Ne;(6`?xXR$jlMeo=n zQSi)hFHuOeb&CH8HNq{HggDiIiIA5FIjI1LyK>mFOjzA;I7ndVJ{+Raw473-QQa>l zsf^N|#HmC&i9)mw64LGAk#GYm#3x4wc%8*AeHIEe>6oUb)U+-qs|9vi3|GY`&z?Cr zwb+9fNMSZ(DDi&>cs{P$G(o-~Q(VLpyx66YAejv(a9|=-0k%Xu6W~eYonVEHs-Q(Y zk(QHo#CHgmFrx5o230DiLrQQE23O0;oGQSyt^OMvDOWQmO?w@;qF5!U^8cVn>9tTK z%G`pYL{-WT^$q|Mzvkid&j3m@P<0O+B;4jsT1D(ABN1IweC_zO;L^b7nNtKoV{(P#SW%l{`a49t*TCc>xx;s`E#QsNB z7B3NAANQn;&CEk2R=iZOvE%93oqSX^x>!LZNHhrRbdjilh`MN1NxO6i)+X$`Zxv|m z)@7?YX(CV96);cuAWklNSj14JQ*)8+Pf3w(wCqT-Ti(`U?_HG9t7dH3C4 zI)6dg0}nnFSorWGk3RPJqTmxxKK1l7@YOJ8_#*-J0Kvi#K*uT`#G6{@OU zz2^0rH{M)Z8(vrUmK3Rfdws)(jg9X#z58BtliVCr)Obs4qV4@;DxJxGpyl-T&09X~ z_~_%UpM3h6*?H=Z(JQ90e|(o|{A?OWOrzH{`mSv^jRBz;zPby4^M9tX*EIH-MvrOy zWE%aZvD-BETlULE4SypQ+ugZvOb%#ZM+{1`vZPwY$u$XI0)zA!gwECgh3dBVHkl+aCv;d>^uphK}sajmfD<>iD6r#zF^VCCJFJw zV#)%NsH*8yz$gE&Xl_p=6{}_7>P=L-eH{?(b-C40SGaIvj#?b{M0csL)LrT>bCr1t Jr+cq6_g|Upef|Id literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/encodings/cp424.pyc b/PythonHome/Lib/encodings/cp424.pyc new file mode 100644 index 0000000000000000000000000000000000000000..67ec0c44e32e230119c0d6ce997f1a43ce69c92f GIT binary patch literal 2724 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 literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/encodings/cp720.pyc b/PythonHome/Lib/encodings/cp720.pyc new file mode 100644 index 0000000000000000000000000000000000000000..b1a08b17377aad51467ab5764764833958d749cb GIT binary patch literal 2791 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 DKhV{$ literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/encodings/cp775.pyc b/PythonHome/Lib/encodings/cp775.pyc new file mode 100644 index 0000000000000000000000000000000000000000..bbf977e30fe9c85793f6dcc7503a49c61aa14c16 GIT binary patch literal 7943 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 DQcQio literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/encodings/cp850.pyc b/PythonHome/Lib/encodings/cp850.pyc new file mode 100644 index 0000000000000000000000000000000000000000..69d4f6b491ac263f9dd6374f7f89e836910c330b GIT binary patch literal 7676 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 literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/encodings/cp856.pyc b/PythonHome/Lib/encodings/cp856.pyc new file mode 100644 index 0000000000000000000000000000000000000000..dd163eb8e26a3be58247227c99a4f7b5e8eb2569 GIT binary patch literal 2756 zcmc&$TUQ%Z6h65U!mW3k7B%%oyn(mYsW ze%s(7YK<^>g&|-YyhN=fnp@a>Bn1wFw#`S>x{A#&Z1uLyPt*o{NYoIukt71b0eA|K zNeD2Ak;WrUn7{~#aPPP=oX>@$!?G?bhNg#m+S819f-Fb?uvCDlHzSW-SKE!v=`oO?K{%f5*|w%!?;R8C#{9?)?hGw z13ods2b&7lHlS{p>A-lxAT$UZfD@QbLA;PQ=x&0#he+`V!f*KTbwf`phJw#HyfC6T zy%B^#$cT#^ho74mZZheClwB|%bC!$9ibf;MDv*0tE+nmR#gtG1g`^=5W;AOR?oiY+ zDUm`tR~R)!9Gb4@^;ZAz-OPcbGeI{hK5tT)HBB zKpM~%Q$k%CzJ$O_2%J;{VlDAnjuEMw@kS5|BLE_q%*k0TnKXjpA)8l6Gw>*(O~MSF zeS}sO90}ehwJ?h4-|w#X7#l$8&MCT<)pCZM=@Q843e1X+O`T2fXi*1lj7l83;Hm!= z-fb}Ja0JK#H1Qx!;3kLS5p)|%gCHVP0kwoA6VOQ*ouGt+so+E^os%<8!qsy{gfP41 zkV^HqM*|4qZ@-)=Y642f=|4ab4{CkIv){EE!%jhy{|7@nTnj_w%PI^dEJ{wM)!{>K zZGrLk@JZ{yw08a>YMU!g0XaO5xS?xuwqH*}ZM1oZtm?oQ@f0oIL1_Y=2<|xN=%gdG z>Nz1DLNG*5E4G(3S^dwq$HLj{Y;Pxv#}dW)b`aLBu^Jwf!4b-_hTYJ}$S%>+{zHYJ+w44UJ9f)^FIjY4es_wuZKCZ@%@m+rvBVxbv>N z?`etLd*A&JJlNXy(8G^B`q<80kMDls$*1-_z4w{+eI3!xuKfp|?SAh0gFUfBy)Q`d zz84SoA32(MY2f8olE>shMb%P6!|9P%Gud3e@S0vUMqeL$WBkpxj=%lRyKI`xuoLVg zGg*n1*(^K7K4hoaN9+tc%RXkGusQZAJIChPd3J#n!o5LJHk zOS(vZp+DpMpVOasd4`uy@bXD+zQ@h;_Ck7@m*#nChL>h}=`1}*FK~03neM&tF3VJ6gNNM<@b4ciY}mw@`P=)75crc zE?4MR^a}lge#0kb={0(lUcA0Uf1qE}OLU3;NWY`s^70&=i{POH!Lbvnc?CKj_700# z4xf-p7OA$QhPBVYDqs1>V{kN`QLVNDv&&dlwO)t@yvJ&}dp)qOh+PocrZ*G_c|+c2 NPqVMK$$x`*{{#-qq~QPn literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/encodings/cp857.pyc b/PythonHome/Lib/encodings/cp857.pyc new file mode 100644 index 0000000000000000000000000000000000000000..8418831b7f16b47fdc6fab62f00e2bb034cf8d64 GIT binary patch literal 7666 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 KPj&_H>Hh)ss#&Q3 literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/encodings/cp860.pyc b/PythonHome/Lib/encodings/cp860.pyc new file mode 100644 index 0000000000000000000000000000000000000000..fe5c8e465fd9513dd2f1b67faa48553f62915ae4 GIT binary patch literal 7912 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 literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/encodings/cp863.pyc b/PythonHome/Lib/encodings/cp863.pyc new file mode 100644 index 0000000000000000000000000000000000000000..1874c58cb5855163664ac9a6f0dfd8aa1e373456 GIT binary patch literal 7923 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 literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/encodings/cp864.pyc b/PythonHome/Lib/encodings/cp864.pyc new file mode 100644 index 0000000000000000000000000000000000000000..52ea66432ae4ebb20634c472704c3123c5dc0e1f GIT binary patch literal 8054 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

QMl?k1n5X zG2H_0;C{MpT(^X7A=f=Xw}@^j-D7mi=oZs0r&~cvkd|;=6WuntX1cAUm81u_ZWY~b z(rVHk(i+lsZheq$18FU32iL8mdz|hex+mx!rhAQUJ>62eN9f+5`x4!objwH^xwxF} zQMwg$3DRaRHqmXNYo=RCdW?&QNZUxOxNbFR2NxeF9UwhHT6Q{UC*5+oU34qxGDxS9 z_Hx}C?%+wf2kG|Ft)*K>dWwtXeDl+E6X>3yn?yI2bdZY=@y!pD4s)?1HyoksO7|?? z0J`Vs&Y?@v^`d*8PUv2s8%p;g-FoitCAvrGUZyMM)>r5z(!EL-rF)I8g6?&?>2z<< zji-B)u9D89+ra&$=r+=QneI`#uh4Cx`zqaLy06h~q5C@BR=RJ{?V|f8-EO*X(e0u8 zHeC;X+jr>l=)Oz0fbK22M!L7@_VN?&&^<}_J-P;N{XX43uKNMqe!3shJw=zMdz$V? zbkESeOLu_o$8-njenNMM?x%Ez>3&9cgzi1MXX)OjdyeksbkEcMf-Xt-OS%{6KA>x) z`;hKeq+gR>T-b8f%>=beASg#!laMS})kJY?u4mkt|#*@&W%qefqT#h5Fv8auA| z>hTjoB@?f?cGBeQO0Sp)cup+rXxjnfl-LNX%u-aRYZfNordW*cryv4zry(QkZSTbf#&y5C#oE%#P<39rd(_Eshjd8@qD$!*C4>E>nW=H=<;73sv?>BL5F zjrX9p)?1fu+K_HqmTp>^Zd&I(BQc2VtYEVHl1ilCk}e+y+_hbYtl`L zbko*!)24LO`gGIMbklZkgSXLp)Z653_O^Iiyd z3sd)bJ5x*2&FhovqqtTQQ6e4bUx_<(uJe}q=6(QT|^p08ce#FG=wyibP4HF(lF9+(q*I(q$1Kt z(kRks(&eNpNMlG>lCC0+C5Cru!QNF}6+q-#jmk|vQRlddC`lCCFBAx$Ms zBbAY+lftAKq;isxBBTn^Owue8t06j@bOWi9R7I*L)sSjQHVWl_VN zC>pOXGd!{TlfGEE8j~d!=COxWJZbyS$8%~8zcTo9#NwLjNGO;4W2v)rK1H87oAw`1 zhXxO%m-1$*%K_t|GAqAzepY@~ugqTAZQ6Ci+^p3X`oC>X&L@(c`Gp>XFIols9RV(* AYXATM literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/encodings/cp874.pyc b/PythonHome/Lib/encodings/cp874.pyc new file mode 100644 index 0000000000000000000000000000000000000000..6bbbc580dde50fd6dee65d2a6905e57a7c7ea488 GIT binary patch literal 2822 zcmc&$d3RG)5WiWQhL*BRp=xj=ZmkOnDk2aTt2ES?N}*Q6Yu-znn$4G2YZWEXvhS3A zaY4lmcZIqBA?Nr>=Hv_bhaUiE?xT4HrN?@X$0YZ5?w$AM&iv+gXX^W-K76@zb0Q_K ze|+?JIgQd4nhYVjX!Z!hE3zKZMS@S59?|a=X_Eb7M2KM_Hg$Q05l{-BQUt3CpD=2a z!mkves=_afT48#XE+EomAY9c2gfV4I7gV~ssxByudR}zZ2xF?~3Mm6*DI|u;!7zK8 zh&FHlHcgTCA-k`TkHq?POHbLR6=~Cp#Z1085-S*HDv~NLS-dFHYvxT$w@o9GwhFn( z!nPId?XB^(iIxqkBXeuuG&%};gPiUo~-G- z#V3@^Y+8ko$rlG~<%elm1*;S#rBG98E=kSZ>oPsvV^&Jt3Q)qqc|*Z6h0Ss7!t-x} z(D>CG+$W?7ZMCJu8{O9!c#VP6YG|5_zm8!>>bk#ChQbcfluYLJoS978VYSE=jDajI zHP&eyp?i*!CIm;L=S3}z659`Y>wNYM5?b>q%gmX1ThFdm$XO}cRi7$#X3^524&5C? zxOCyH{}tYOwCi$&$U-#nF-_=BHzuNNHlCqLs7Mvm8k0;xr?Gd65-z5S6X{G|&$xO3~#1!H|>dV90#A2}6y` zlN;&8@G-aM(D-}!v}vT8JpUNA*<(ftIZj8ywoEqCVe(jvezU}sPEa< z&;nYPn1{ks>j`@5=o?hufon`3kJsl91ZzUI;VE_XQyZpDpD}aR>^Zm1ZJam1>GnJB zj4Zh8?tAXNZ(;QQ2OfOr;pUb{9)0ZbMNd4rc*#>wKeP1NWzQ{Nu`;%5^_sQMx4!V= zy0-ZG_LsCo$IBZ!H*V^BrTf*_lAHCOlwqcO`!fBnXLI>N@eQkF54<_}*3jGUY^rPoX@G@(jwe;Q>X_Vf97ei4WC}WDoX-;1 zOq;vI*gq^i1DUMhv?JOb$JPn!jB4CVomRcfNAH!mds4ggH-;Mhjs7NIQ=qmXcun~K E1TvV>xc~qF literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/encodings/cp875.pyc b/PythonHome/Lib/encodings/cp875.pyc new file mode 100644 index 0000000000000000000000000000000000000000..af78feb2dc98a01e15871c7489164e40d593b693 GIT binary patch literal 2691 zcmc&$30E9N5bix$mMgb`pl-ZaFYt2xgF<_n}0HR6k;*R5USYg3b|ChMx=i)yKa zudIG!LqlC~Q>bEVO|W{46soAN3xsMLD{86&)pdc2Km#r+Z`{^c=Ie^-?X)~X-pbS6 z>K7N9_3wIZLWRbO_riu>c!%4*m5J3TMA08azN7>Fub}%XAr#$FxdR^CI5j{fB zG@LjBq+W`X&RBlV$Wm)J715gq#kW#}z6eA{=2|ZjGzv zD%v5V#-k#HSTfzIi*u-&meMkQG%_(|R-#nivN_h;GVLYPBJe~U%oPHbJaR{|Guyuj zLZYR!j*mzq+CnA7*~ga%c!_|Ma&TJ6c}>TJ)PwW-2@2hVQ#hQI6KXiDd&NT{rF6#e zQ6if}5nB5QXQ`(L7^@g(bR;R)a7`MKu(LGR(!J5S%!}$b@1va z%%Tfr{jczrpw{9Dk_BnvAe!KnE)Mz0Z7_xt6Ojt2B_f%CPNLHZN?4c*PDEo#Ic^0! zf2@QMMK=>tDWCQzz)AS4mE##zKxsMs2Pjga7EgP2+vZ|eEok!pU`WX|F(kgs!BC>= zWJNkZe8jC4IQ||!X%U(h&ObtJ`Lt6+j?xj*HC0YDX)!F4S>6$=s^~?^qRBffO(-+L z9V?GkI6|5~CZake?_J)aeRQwV|*VU%gZk)ELya9$x?ob_j~x@%3^+q z?=OA$kw8f|Nj!F9L+ zH{lli2)FsQj*sJsWGelM26x~m_!)kIyYMT&^<_ry{Iu({?$6;K{06@pJ;rXMm!E?x za238cM&Jiy)Yxb2HO7oRMxW7d3>bsP&=(u=r$tTernl?(RbvE&0}yt;PXYy2j^ zgu1)@jGt14w50x}q$1d_sN$P^uvkC@FsZPLB&t|C)#mA+3$2~8xMDT~)Xw0_ytiDm i&GlxZ+~B}<8R}iw?3~4(VrQ|l)KTinEpp#y&OZTad|&+l literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/encodings/cp932.pyc b/PythonHome/Lib/encodings/cp932.pyc new file mode 100644 index 0000000000000000000000000000000000000000..1108060af0d83d3193136b49b2f732280da91e16 GIT binary patch literal 1673 zcmcgs&2G~`5FY=;`Kgm21gL<-fm2RBz^M{K6@^13=wWlHup*hnyNMjdPGoO|at_bL z%kUUH0DLoUoT!CEF0sAq+4;t^GqdyA``zvQy!kdv=`>%v z^)5vo8KSvQ+NBMk25D#0YV~`r;yG@pVP@mOw)W;jwH~t)mm|6Ax6nZ7C3FkK8A3WCxyvO zZpVvH;=Xv83a4JD61jEw9`wrPNhJ1rP()39@Cc)1AAx&6o{y5_5#!;Lc(NA{S8Hes zGtQJ5Yjea%+Sr*7v#N|^cahu_sXb;S+>kGKk<`u6hwhT~7nm$K4f^5%OFgn6H#8ue zzm>uG2BDq7Ve~J^Yn!B7-25AA4hNj?wdDq49w@v?aqlZ`d+CdG*QXT?iu>w{5{1;N zlvBgW;nemN-=%o6o3MyEl$4ft7ZzXT)1~lax4GgbRooeh%@o(;kS4b$_+Vxb&kQ6h z)~~QEx#mAoqZk75}TS;`vI6j!PY9w+ow2)>b%?SSDOHN#y4N@A8G>`bqef zPwdO~i-#1Kr2cDk$2&>dKHc}UPX;N+zu>AvrBI6hFb7qO3;nM8{k`YPm(0ggCv^Mn NbHD98^LV_*{TF@RGrRx* literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/encodings/cp949.pyc b/PythonHome/Lib/encodings/cp949.pyc new file mode 100644 index 0000000000000000000000000000000000000000..f566ccbfd7a87a0fa1ef1632ba8e6bbd77d2ba3d GIT binary patch literal 1673 zcmcgs&2G~`5FY=;`Kgms2v7lu1E-vN;!+8rio&51^sqTpSdmQP-9!$tQ`uXgoYQCG zWq1r80KOSFPSnC7m)PF*?0n$ak%%?k|HPP27Al)G2(Yz^ei>5B=poUwd0RV0b+!44{ z!yVE90-BPs32BefRIS#38d4}=X5d>(=?xzBMJ2MW~Df?5ToQH3!JuNpFp_Glfq;s zx8ubpabG-6g;TFniQGDT4|?VDBoh1GE21VoIL0X1N8mn;=cD9!z4_Gv|f;-R{tL?N{* z<NpY3|uC4-dXUvSl-QYgiLn7yjSg??B4{@!!tOXlN=6S{r( Nh2M6bdpzFY{tHdPGyebp literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/encodings/cp950.pyc b/PythonHome/Lib/encodings/cp950.pyc new file mode 100644 index 0000000000000000000000000000000000000000..b0929a5892fb4a64c4c8c9088b98b8f3ade3a6cd GIT binary patch literal 1673 zcmcgs&2G~`5FY=;`Kgm21gL<-fm2Qu7Y;}WRV^GUK@Xclg%!yp-c95vb}D zco`mp2Y_$JjT5zS$R)OSJv-lcc4l@yd%wG#pI1MI3Ef{l-lrJlFH9PbLkps)mK}=Jr^qKY8~~*OJF+cIah#7c6UVkAi)^WH7QB?5 z*uM<`m^^_jB2*A7FF;77@)**|=xaI|iD{b8%8>+ma=lUjfc@l~J?iEoJA3VV**+<|$jOVlDc))o0B%bZW!_^wv z!i+Oz#@ZY(k~Vhc!>lUf*li?NMQRTj2{+{HZ6tMb^r1Uv{V663PJ_O9z*3Ja$PEn$ z=Wk>%zCmbba2Wjy^4ccp7B~Nzn!^F-duh3Wm4L3v6y&?ekqvyJV1Z{0pu+R0^f|53^UbxX>S~-`^*$e93$~c0#xB OzVzG93y;TJ+nH<6>*sqBqV&gGeS z86JZNfN#c)6SZ*3q1fK_?9A-${C(s7>UMryejO!r^Z59mVU#~HX?zYXiK3czC~~%Z zmm-f0(ZVO~(lta4(%?9>2xta1pS}}a6McyS(hV{mEt(>3(aa?s)Z!Lt2q12YxFh0L zE$)zpAP|is(Fkegk?zzQA!!IIjjm|)L?f&2Ew2HUw$bNxVqQ z`1R@O8`}V5xY8!6!{UJR9;1B5x;Vul7EXeGf27J}Pi;oAp6FzJIeg zJ&*Rx;@FLBVJ4X}6K(F_pf(IRt_^aeC@X_5i`4!HgScj&?+mI7rw`tc`Dd6c&<~*F z1D-vyXanE?n*NqXZ)gxI9%x621Ln3#y2bdorsinCZeLg~E{2N2pA^GGF*2lB(p?Q# zNGWc!E7TMcvQl!0JR*mCjBgS{xlMp3=qoMXK4c)C=d+byXm`2d%2iw^iq#ay;{X8I zBkY?Sm^B9ui_HrxO9li1q=6IS4dfj#v+5L;b@Ad#36CQlXX~X+ryDDHNi1VBn Vp=7KcJE7ZmpZaa*iO1s=-app;NTdJ& literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/encodings/euc_jisx0213.pyc b/PythonHome/Lib/encodings/euc_jisx0213.pyc new file mode 100644 index 0000000000000000000000000000000000000000..6873ab5e892384020800b90a623c1a9a47d4bce2 GIT binary patch literal 1729 zcmc&!OK;Oa5FS6`JemhWfC@+;amuNpa7CyhaHs@5Yz`GxB$IeIk*&n3?2RDj@SFHE z{0x2od^2vGsD(=o#rCdeXJ&Wj^^Nzd)B17wWf;@-M*k(XKSQq&vI_d+gJ&--Un4Z#);a4brUQC{2oQ zFJGO$wly#YOKsvREDkvDFp4Lvi&GpjE~TDC0EADWPiokQl={5gHZVm|HeQ%0vMpIG zmU=bkB`d^yz70T`jA_@=~44kH8 z?}Iqc;@m7uX2OBMwC6QRr4)c;G9SC!zScLr63(*tk7{4-1z=m*g8 z0nZ*;v;lAcO@B+HH`E9f545Ai0drd?-C%rds6Ono+ZUFLi=m?MC&lnkj0`E3WLLu_ zQu3SZ5;eJmtdJZckI3O3ouw+Fh==auwH!Vl~C_H~;|l z2>WIRX3c=ZeEkf|f&oDQY2dW+2J-fqS$2xjx+uL;!sCcXi`CpFleHDR#FjC+n8ea% zaJuYJ97gfNa^gO1ciip*;@dx!t}!XT+lTun?IT2@@;7l=uM#iCP3VxIaoFFK{qim6 WpgwD3v0w1ufb8XAWd0nOm%(+{F8(YGid-5}%9qABJU&0Nw!ZElf<0p_-tJ7R9t z<_>8X0`WK#kC0{_=}zqtl7^x3=!!>AJi^+eN4m>{sLwHt20g@={=su&1Bhmw#EU!I zfH+)flhg@up!tYazGg4XcgVQ3@FaE!K1DvM(EwH&@O0Zk7svS|GjVJ?GRRhXz2qS~ zB)opLY0k2UP(iF#fe(pPUO>7We@Ulf!>(yQFUJ+q%e#$YXdzn3hZZ<($3BN}ohOCK zOl~L3&$52;G!_oNjwNzy{2uhmH_IQH)Q=4Ityll#Q4Bfk1Qw-4QS`@ zWbnR0sA(`6MGOktCg~P4U`x%>fCIj#@#V|B%gLXuU= zx#8?^ZU>5c$)4;cR1$ubmUkaA)voi|O1QG$TydQ$t_{U*it}+)q1!Xem>U3^gK5R) zErul*K7odT6XFfz9k8;x1u9&)Wt8YR*KxL9+H|_H!i&T*>#}JgR|r;@8Hy7q_$?pV z*WHY#JeR2c>-4}qiQ2wATI|Eq+zH$y5i9jkFfUWk?!&!>T^t^K@ahzfAHMe0HRqZ@z=sO zAP!gBBy~a@Xs*%9m+Xc44jGpgp2QBpr^qKY8o){eo^D&{;y9mVCXQ`K2H8rlmpo*L zgx9Y&%~=)^Du~r8@F9`P3rLsakLh%5*fq`P<+wt6`E8>ZT8LKip#@Icu}>k~F+OnBBMXW{1KRmJ z8N6>0Y8p&N5re|ENxH=h*iv&e;DB!}7ZH;|;ZKSQpqOw{8tJ}PrNB+`P+jq&kYtr| zZa6!f+kxV{WKVVzDha>;0u?UYGD>uu>o{94Z93gp;YDJZb=fqLD+H^{48;i){FaaG z({9FNo=a5!b-L%CL~WlRu5`!;$;ZFURgFrf6kjvPrHfPjwz>u1aqdgzjVWQZ0%X_szcYLJG;p+!J5xcT&h=$7b96p(I^@o3Q$bBks!>7X{ZNW%bgTg)9X zw`y~TGz@`woQOwAGmmtq_6SMCP$_|iXku51(HeERCm z`RjArfIM7jlhhe;pm~p0K0^nzz;9eycmf`RPmxb*G=P-`Jl(d?#c@8#OdQ*e46>EJ zS@Mt_5?XGc+e}CJCS(Z17qTBK0qsZmB76l(FehK)QI>z9_>ZM z85`NcOfqFA+8i~OHugTPV{z;*mg^$5$Bl(c^Z728x=8xa4OxGI&Vt{dGCnZYBMYKK z1M>M>8SHNm3LAVzC4*E5C?>?>=O{UFNfu@MX8T;!;&y9g5u)=i{(qw;mh*P8?_^vrHU!3f>)n)jOvtKeVPo2>1 OyHEYL^Tgx!67OG3^fqGv literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/encodings/gb2312.pyc b/PythonHome/Lib/encodings/gb2312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..aaf77109740a3d2466cc561c0265c37d8ee79f7f GIT binary patch literal 1681 zcmcgs&2G~`5FY=;`Kgm21gHgx1E-uSQLYG81P+y;hs~kFiewV+CUO)z$leO&9G;1n z;W2ms_-5QVQ45D$Vtd!KGqbzj%+9yo?{4Sk&DT*vcaM+%C0h9loyO66_uCz(&ggDT=M=PJBL$C_FRvPeh+d>z|`6M%OY&$Z@R{D0y zLv~1bec9CHEQ<&g#A+4zkVxejr1SBobUGH-G@qB_3hDW`wPI)?TFHkNIBmy1hH#Z9 zg~?2AC(Dnre(^9C4!({ha%=n^^vdN;d9@ zjcj2inKBb?jtQlWtxszxj@?1IDN=h>C|s27BgT&&C!4ZzP4OMOa_HNDJFno!bxeQyIQTdP~2BnyeK4D zrJNhi4(GO~_%7L#-GoZQuhR1FL#EnQK3fS_cAG1%Q^mER*iCUh4k~nef*ErIKyxsy zSii)uR-7al9U0dNrVwrW>G?6O=tIG_<2^9R6 zkL>ey#zUSbS*OXlRM6S{r( N%x^o-JZ`V>{smcHG`j!* literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/encodings/gbk.pyc b/PythonHome/Lib/encodings/gbk.pyc new file mode 100644 index 0000000000000000000000000000000000000000..26905d35fe9a8930b16b4319b40b9782442c5afd GIT binary patch literal 1727 zcmc&!&5qMB5T5)r{n@ld2+#r&LY#Wyzy%2*w4!j>11sbnRz#IT8@nZ?Nm1ez>bX1< zFT-Q-0PxLZn^wDU>7_~RjAzF7{C(s7?sk4&ejX)s{rLEwVU)ixX?zYXiK3czC~~%Z zmm-f0(ZVO~(gvaiX>c4`1T=%1Pd|t@M4zI7bc2jXi>8QMG;>J@wYWtZ0*Kop?ufWm zi#wzt2t?yVG(wtrq&u}nNE(7lqbnLc(Fkje9_cPGqCWdH8uZ{_`UlU2^+3+2Uu^^b z;YypNj)nuyTa5A%CU^?pjY|tp90%c3pMP5`wlKsfIdOs0 zcI;gc=Xp|?%;a{md@t7&w_V}@)GkGC?FL6fxjYHQ=N@EP6C3Yflzdj;-n8qT_)b9F2#9!fB&R?kVshmC9Wz~0;aeV9TYVV{OhW1zTr%i UjMq~qbo=f@zwJEmcs#@V7YN}?`v3p{ literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/encodings/hex_codec.pyc b/PythonHome/Lib/encodings/hex_codec.pyc new file mode 100644 index 0000000000000000000000000000000000000000..4d91f2aac7d1a6a334ddc4f27c85d73cf66e9d92 GIT binary patch literal 3715 zcmdT{ZEqVz5T0{l$8qyg0zpI+vElq(zPjBndufqw_52IDY?xL#~n8OsQU)* zCkTktw-a|-7HacUKkLP1qT@}q&p&Eg?QSROFm(zl6_=jkIhhZ z^C-KY`G=jj%s;|g>F>A>U5f$1VzG-G5ZUK^?{oJjXr7CspEk&@kt6ykAP0vw=s8>& z(2o!rhHp9)o|xmqj*F@z@wp0FoV#Mx}8&souY`9{Z_w?$p!}fKYcHjaxypXRS6aEsKY2 zzH6hapB9mg)6^~S!*0|A^8hLlHs9r6*F+=OiNpNHMf9k3p(bhUhmiK~o_Koietwdr z{gWAI?McPEsa;&4P&yztro}2e@@8Tn#T;p~dmpmp zkU-Ky4n&r_;N-^JJ(M=&!1ck&yR|wS)SG>^eKJfw7C+`0c^ed5(<+W>zojKeufrmb zI@f}!MLw1B_Ite|%5|?NnWWdt%VeD4F=X6A&UG~oB3&ang}3nfHg3!4wi-(fw+7*$ zh>gyXjibz07xS{$-@-WWbuG^J#}as&omauh=!%m+fPiXtCJf<1x6UPw3tfZGP}u@5 zbiS+|)~Vccx?+FGyt#tAFcYOI%4!&{g8-xW8E!#iB6`aLv+e96loh@7l_Mbo)4Y)%y9CJfk?pD1z5U?pSor7sWnSjNW$Cz^NWmsXb6HWoIT8_hd&cbb0y+A=XX literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/encodings/hp_roman8.pyc b/PythonHome/Lib/encodings/hp_roman8.pyc new file mode 100644 index 0000000000000000000000000000000000000000..084489767f3b8ee5bd65536a6b6e9950da03eff2 GIT binary patch literal 3977 zcmdUx=X)I06~@mNt%@x-jBSB10|{7wC0Q}KNT#@mVi{W&Bfy{-*5f@RX{_DZ&CD#e zo`-MdFW@hrIDzy)5|U68dhh9`rclyDdL!?9$I?2spU1!lcvxwE=gz$|cg}gwxpyY_ zPJ7!O+jfkWaXav(LR_@38po=TJ%hq zPm3Cuvqbx07KjeOtPwpMW{K!IFpEXcg;^$g9!#g`T9|dB>tPlNE;hP>u^Al{Js;)* zL5M~#6uk&$qv#OKCee#wHj8e785a0qbgMuGqa&i1z_9j5%_O(yXaLgTSTvhfzCT%JkgynB~gX(MaN-=1Q#2f5XfdQpp!6x zKs^Hw&@#G9Ae+%C(K5^qLCYX2xM~m%qA^+#1Z>~|T1G>Gs|HTu$p$XtSq6?kU<0=h zn}H(;-)L2!kkOhTD5IYh_+j7yTs0aAqA?l^958q^rZt)f5@V1VNMn#LsArHa2yCD} z<}+FsNMn#0y#{8jAYg+kfrtjlgU$xUf>apYEl|%Om8b`Uy1?uPiwKW2sM8GBP&;dt zMLUnnYqV<*SKY#lh%+*sOjbi@aMFvsQsPI>7Oz$d!U<=vs(#6t@IycH5?`J1s9JGW zOxB99UfAE0>`7KQyMtts*OYj1Pi?xVtG);nTM@(mu#QVNjyN?hN}RB2JzBl`%(MEs2UZQN>Rah-^mmv2 zq7bT-vP-{~9ZAAtM8yZ8+!O%TW`FuPf0(X)ZFIe?E%0h^NDudaivP#f*6 zu$>ckv^~8GNM^QD3yD%sgaVJ_m+cyV0x6jNGZ*Szb zHl5yO^SXdjGJ45;kT6`{`hNkSR8TH90NXq`0GGnM6wYl1-mk~$)YSHX$6XX8X#tAG z(5v{xV$x<$DpjqQaq4o+odYzUWm`v;$i+Rv#Ke3?Av-shEJ9-_EJc3B4->C^fz>Z6 zq1XOqOK34p(-Oj4Nu^OX%>LmbABWyXt)OU7E;*J9-j*GsU7U6}0K`UX1$S9&RzjEF z+2UwuYpY|NOR5p{(c`63OK}`5t;;fW+W|Z0g>l>h0LK^o^Olh zqtUXJF|r(8*3KbXy7SqG<2|k{TWiPT@*~UWa=Cr5dR&M*St@p7D9F@|CXw$|wnYJU z$k{q%m2KdK%xGGN*s{13@t zeKj_=6kEhWV?#){?&bk~Y(!tlO8!gkw)9n^tN$Y&p$Zm4{seL)R{<5jyAH6H77 zEx9ZQmkDtx$@@)Z!Yy&ahc|e=C(-n&IE`7Gl4;EpGIQ})uz!J|oPzIRAh?mZpSX#5 zl(?CAoY+S^L41yQn)p2N3~>wbP2yJK32bV?7ub53tuM0mC1O8Mzs%N8h_4VoBfd)P zbAYe0^>yMU;x^(x#O=g4h)0Mwh;I?k5qA)OB)(02hq#aUE^#Mu7jZXn4{<#szn87o ziMNUG6MrWDMLa;fMm$KoMLa~jLp)6UlX#VQlX#5y6Y&q?7sQjquZgFKzY_l@o+W-q z{Fr#2c!BsO@gnhC;s?avi60WbB7Q{thWIJ5pZGoT3h^@WbK(!gUx*!y*CX~2@3QZ| z#9{~d8(TM=f>N807M2U&xmqpZ9gCcai$ji7nJ)J%yCf>!lwS-K^%f-4Ma6fMeW^rV zIN{r^*M61MYxt`4?b;izhJM02w|CBb$?$6^ee3a&jlw_b_GP~l&Pl%v&TGNFF$Kk& bJ>SvNk?+WN<~o~N+mFQpX#N=g&1w1{?2rV0 literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/encodings/hz.pyc b/PythonHome/Lib/encodings/hz.pyc new file mode 100644 index 0000000000000000000000000000000000000000..9a9ae50a658516e43b9d91c8acd2bd5f58d1e078 GIT binary patch literal 1649 zcmcgs&2G~`5FY=;`Kgm21gL<-fm2R>0)(mt4wayX&7s1IWD@Ttbrd_u-U_AH@Jzf6 zkHG`LH{-^MT99&z*Snsb8Sl=_e&2e(yPcocUq=buKR&+a=;bdA8m~i3qNtV~ikz+9 zrN|>gwD3v0w1KHX8XAWd0nOm%(+{Ez(U&M7-5}%9qABJU&0Nw!ZElf<0p_-tJ7R9t z<_>8X0`WKzkC0{_=}zqtl7^x3=!!>AJi^+eN4m?CsLwf#20i4L{=su)U5Gb#wt>%Z zrA<;7!-3`ky?liMi6V95(!!IxA@~&eq(%c+X~4hR7KS*^Cz*+3+mT7O(zi>VvO~h_ z+W?ZuSr!p0h}9~vkVxfoNN3|u>2xfvX+AH){4Ul(Mvw8z-c@7DTK>BDNJT^ zJ6V2|wTs7jaME=ikz2>^L9e(BN+e$Q@Nk;&eu7@|0)hK5m=BWOv4Y_Pc(xY|*J)%6 zGs%>hXmhME+SvBA4#Tm#Fs_T#9xV(;;Oku&H6Z%X4OxGV!GggcD_(HYBhX<34d~@> zW$?Q}z%LjJz=Eo_NxH>o-%xWj;AF2XgNA{x@Fm4ySB!IkL%PFeh5O>6y5c|~g(~H| zaAr8KJ;isaoa`pF5iXUMcONpXF7w$+xUt(@F*X%rLb03TdK?UFdjjvdK`?W$s#w3l zv}B+YC>J;(S|Dw}%8Kn(OmUJc(Q%#Q>~?9>>Dmep63YzBriok?SY7^5Ts(>0@^O9M z{_&X8lF@&i?ztuzTfRW*mG(IxwfL90!lqP7@s)CTskp@Ns+;aT*Sus7o;so1cVGH# K=Y_}pE!tmEO)nz= literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/encodings/idna.pyc b/PythonHome/Lib/encodings/idna.pyc new file mode 100644 index 0000000000000000000000000000000000000000..5470ccc29a833e3e17d80c1dc0d6526c04c3367d GIT binary patch literal 6334 zcmcIo&vP6{6@ERl+SRUCUU}EHqQu~_laMvR#+H&eHg>QrIaSIJ6*X%kBW#xO%*dYg zYGySvizP~`O2xiWMXKh9M+Uw`j=ugCnyMCsQ{-*32-{h0WF2`MoZk%vD;ZKCCVS<$lUwHvf-NZFvaNvk

3e4hlT6w7Hyi)%yr&8`p2)Rv?iSn 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 V3MTBS6S`gZso!*-c-&s${R4TDNO%AM literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/encodings/iso2022_jp_2.pyc b/PythonHome/Lib/encodings/iso2022_jp_2.pyc new file mode 100644 index 0000000000000000000000000000000000000000..d8e1404948e5c7f65820d1af82c81bab3163e804 GIT binary patch literal 1734 zcmc&!&2G~`5FY=;`Kgm21gL-n5~rLhlyikD0*6Y_!{$(7MKXzZ6FG{L%H9g)9G;1n z;W2ms_-33qQ45zGitSy`&dl!4d^_KIzuK)I*I$PTZ66>13$)@VI*rev1yNMV4n@vR z?^5KEA)5Q7UE07@BMps1^MIys^XWU$hUiNakgk#OXkHg{gQhO&pfWc|!vJ$r%q=lD zDszi841su@h(}0Mk94c@2uZ_GdbGu(BOYPp(IMUDLDc1(hP@8*OMm0JvLTDbs{gj% zkLNdW-`1cQth7lgSR82HqZKdEA!UGIT$+1=00f^RpVY7iEA@D~ZJ>+e3yc&Wg>8`cNO_~FCi z<9Tur7GpQGxfy55jJ0|AfSL&4v;u?Sk)bw{U?uHtn;=y*5IB0I`q#MkS4b_J|PW#GoaWPdC{-l^5ikTtBlJ0A` zWJ-QlU9u(@$O<__oFmTgK=Dm5l--1A!oI@t?gJ*`<#M_b4(&HrT)B$tM6sJ0awE1)U9iH<>zu|F>_&3Akl V1rzqv3Ei&y+;2M1JZ^9B{sEK-NPqwU literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/encodings/iso2022_jp_2004.pyc b/PythonHome/Lib/encodings/iso2022_jp_2004.pyc new file mode 100644 index 0000000000000000000000000000000000000000..d53918cb50835e29562f13cd9ad1e8ed6ccde8dd GIT binary patch literal 1758 zcmc&!&2G~`5FY=;`Kgm21gL<-p{JaxDB_4vMc_~gde|H)tVkyDI+3H;sqC##&f%GO z86JZNfN#c$6QywJCAN1xJ2SgGf8RL2+pV9s-$oH_9~b{CjN%t2jnASbQBctq1=fyl zQ{Yfcv~Wq=w1KEb8XSuj9?hWU(hs5y(bvEuU8C5cMP0-Vn%ShiO57j~0mMxaw?y2i z#4XYgc%pG88a~Y&(ydCvCk;WV(H4!4X!w;zhjg14L6?0R^*Zn``Ge=ibeSwxgZ^L; zF7CoXzyH?Mz#Fb~995CA!1;htyut*p5r^2Og(E=#;Zop|8ucKh9&a}dOktQ!(l`uF zOBU%$-!FN|3K5@gJWz4Qw2)wdEKh-igeopTU5-B|)3K-~*}NDZnS6P-R&1k>QE(bP zt7)01Ag;40kJC6aljSG5D1Yb_hof>Tuq#I#@RiMzP<-wqZL4GJ6O4jS^Xy~GK8oKb zv5fQd?7%XP;K=0hBvtW5$0xC=2^-EUn=G@p={8TyX>8&We!aJ;Dk8?ukoi}b4Eh0} zj}HiU$e=NR1F*U~8r`Bs008ihiU;sbopgiYvZ4B@$DZF9E;L4t!k-kQMKMsMYLb0D zm%z!7*(Hc_iCQ6HX3q)3p%*MTT*jP9y0) zxI(rm4ySlyIDubwJ05lh@$tV(TaZc&%=5#O4)G$<`IopXU5T6G#`MVGaR%O%o%B7Y Vq+sx#TfW`3U%E}}g~Q_l?_WDbO*jAm literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/encodings/iso2022_jp_3.pyc b/PythonHome/Lib/encodings/iso2022_jp_3.pyc new file mode 100644 index 0000000000000000000000000000000000000000..e4f7313a94fa5065a9d4531db918c8643277d260 GIT binary patch literal 1734 zcmc&!&5qMB5T5)r{n@ld2+#r&NSu0Fp>joNMd7d#?7=;(h$@9PcB@ovx=Or4J(p+V zWq1r80KS>DX|)TN9+o6_#xrAk=JR~^ezjXauD%Wv+CD!1=V--GbQ+&S3!y{1R(en`J{$DSgFU;Z3A5#XXB-bW80F! za;0w;JYHyIv~}knIPFWz#l=)n_>*FKC}xHfOS-S& zk}3IZb;+7sAS>hyagI2{1I0JNP<9id3Hu7myAPO%7uj?r9NKTLxN;TOiDEa!cpO0h zdxCj0gRo}cVZMHWVZnqTkTh^Yyn(zuR$4|kE~AUL99Mh8@@8Sv$=V8O63fI~P7=9m zu!T%hjHRSv`Sd>TX576BB*A|=ZHXxW*vE$}9nwUg`J1^cS^-V*O>_)$jQ!j4(tO8< VQ7~aoozU&NPyMFz#N+k~?;oyyNQeLc literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/encodings/iso2022_jp_ext.pyc b/PythonHome/Lib/encodings/iso2022_jp_ext.pyc new file mode 100644 index 0000000000000000000000000000000000000000..f5db188579074a57110548f332910eed2de94809 GIT binary patch literal 1750 zcmc&!&5qMB5T5)r{n>Pj5TFGlBslf7LOmn2qHtIV_TU~?M3q7tyH%>DT_s*Y&*hnT z86JZNfNv&kT6W>mOOx0c&y4Mv&-2;))o%T`{xV2t^Z58*pcOySX?zaNiK0q&C~~%X zmm-f0(ab09(i)~3X=ogp1vG)1Pv42wM4zL8bd8Khv$~iYG;v7>mAOG02AG>-Zi%^3 znOme`2*l$=JVKgyq+69oNE(LHqb(k%;t^IJr=;6Fh&r6ppnHn^(%*Qltcb<3_qx}M zXE(9=W^E1D{!*Ky0>**n9a`}W9g+qN#-*7j7(nnT@<|Q4uu_+&+XlKgUW_sm$F?Pd zY^iVOJYP9&Qp7okhprE??S2yr~_S}^%v+YZUT@V zAGqz2#gzaJXzFie+!HlI?SuI!c2M5dNjI1&YpM^rocNXHB4g4h{7ErU6mvvMCf(I? z$(j7Fy5vtTpcQhCI7^)4p5m*ZD7y*egolOY-TO?*%f)0VT-t4}xPBGaiefj#cpO9o zdxDu$gTSU>WWIWVVZp>8&^2&Eyn(!3R$9h4F5`uF9^AuM(@d}DiNJfEH4-OkUOFXM=IkBk2$TJZ~=#%IxrD5zwM0&B0g zDR3wzTDqid+5&2jhQ^|$M{}6D^n++i^f~ZIHz;;!*%Y`%bDOkR!7b7N0JjD12;8dR z4ru_MSe%K4PjiQKr?T)#11K%JV$l-|zq06&?(!h$b4=qw5Ah{`@LZb?i^Y2QdN>Tf z=B9z+XszR@N{R)|JG9~%Is}Xq#5OG*i64SXflF#U07?U%Zd&NVFq@`v7|Qx#n6CBh ziid0v@%qMt6lW}p2o=O~6(A&1@dDDtmKh`6SE$m6}*sV-*xJ}M0;wd_+TC# zIK_Dzn>?PTDxT{2)b6yg{dwh%WombB^2D6n9cIGw+MTLk`p}J7e~He3@gO%oaM&RO z>O%uMx_cS-L4#1|U^ogJ)HY4hEoQ}*n&SZneQmg?m>>#&QcMcPe2_9p>e?;&k>6F9 zT*)P2g`6MG5a)NG_%0cg-GpAkxx(=7Bc|U~HeU;O>dh6`tl}C`Y^FFLM;E?1!>mON zrxsvezIlmZ!9*ZX)3bcMp1cEA8qRH4`WEhZt!f~>U72LIF+!HeFdfrbB=-xpkZFoD zDS;S1yHEQW_b&hm@4rSnLQ44N@!?8`1d+u23oZ**Ql|L+IX-Wk_c!G=`IZl&V4|K| QzTLNaOkTs;|GU!uMxsxW8plJShf0KKffj!x|u= z3DHW@BQ&o_dqgWKKB0R=msg}n_lrIu@m0Z6yU;P-vw*X)O}kNYNUS4#-nTvrgWBC~WILjDIZaPS4J$Ww>Xd1T>S%|a)lJpbwP?!BWuoN`Gn<;~ z8|TKW>f`hID^)Bisw~vBy1tNJYos`dWG#3c^{?h zq4h?0yNt}TN78DNa?hyU2`5~+BvnEoVXN(F-Py$_Sb91oQ!ujKJ+_QPH_e=B#mFe6 zu*yiQY@27aw+(r*+6pid7S1jS%?NhM`3ujpB%<)v$5J4)330h3)yGp%7<`4nQ;JAD zZOo2yMr<(V7(-%*NF)+jHKQjIc34g_Ijtv6Q-y5`XX&0LwP8V0XpbnSVeuJ3Z;8(y zOGPS4s zZW|2}LS`!=SD0`TLWQG~^l-72{74yDHSH!ne7=knXZR?zN(rA+N<#XaqoyrgLh3sH zmuT{(jT!PD^gM~>EJ>UH2TQ(W2TSJ86Id!-sN8IahmpB9k;Xs6sEj7lv+AbwDqExr$tCwr-L#}Od~QsS2o0IrV<9NIs{JP+ zaB=1OHW)%7X}+d9UaukHye6k9Qaj`VOwWoQlz&L4-WFg^YeBB%)BtU2Rv|7Wc~KOP zF(n#pep*~rES?S)(28oeq(~AQZb5L$xB29`yWjC@S~~IKK^9-r!zjQnOR#mYxbPEpVxo!<-CT*`AuIb@#e3;X<4wa_1m`Z zzE3Pt+mo7}>gY7Oen@Asx$YlL%kKGU@z1@#{JP|~-~WK6und+%9{OMftb|pt8rHyC zSO@E218js%uo0NjLIa2xKxUAPDL;Q=niWw;#k*oP}{C9cBNxCYna zI$Vz%a3gNQ&A0`(;x^olJ8&oN!rizB_u@X>j|cD|9>T+T1drk|JdP*uB%Z?4cm~hn zIXsUS@FHHq%XkH^;x)XEH?SWE@Fw2E+js}>;yt{N4`O^<#87T?S}sX#jhli)3zrPc z1BVgZQ4}s_Hka<9|1R2ljI`$T3tD}IGQ&Q6*3jbeQOK{f! literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/encodings/iso8859_10.pyc b/PythonHome/Lib/encodings/iso8859_10.pyc new file mode 100644 index 0000000000000000000000000000000000000000..c03466e447f8aff8a68f82036e31635059ccc779 GIT binary patch literal 2748 zcmc&$c~=}o5br%%mMgasiEg}Dj{s4liN=^f4$-i|S(Ic&H^a^>4DNw5gNR0j0MUey zi$KVIX%fQA@r**AIsWMG`67M=KR~SNft>_>FC>5HF5UE0O;=a_>ep54`Ku^6(YQUD zAX6U?{9g;hn1o3oBnGpKC~lH+kr*sIM0JriH%Y?UOZo`uC1hL7O%$I{c!a{AQ+SAy zClp?x2;>xAqU00REp$GT1OvgG&PSAjX`Nr_3UfL?QHt;(mPeFg5(@|eU@1U)!NDMU z8V#3V04bP4^<8FbHWR98m328`s(PqSZg1BzEuosMq9#I`kzKiR#j5!7s!)rXQFYl= zl~7X8rbFd*>+0)kBb%a?wb3p3P9;vumRD6YY;7nHb!uiSZb_h-iuSIGU{JdUpNQ#$ zV}*Ys@aHC`oAi1hXcx#M&UWFMVHSfl0nw-B_PFh?5Q!z=5I5!Klxpw76AU$#6d`Dt z_6}3{q3U{8H^QJKVltM%s-kJL*4#90#b|PX1TgGv0-FM~i2xAS<3u9i)(2t$xB+q@ z63Yi;kPv+d(UbCEdSs_<>xkKu(_sX~48RnRXXLaRkDEd9kj^R{DR`7nCt;Y*VPf@g zm?YRl@?jWwh~Hi4G3UXeHj~iRw3;#H)CPf}o&c%%KmF>iCH&HG(5(OfU6^Z%fUX|~Zs`piI6!g}R|I}0F@Z;N33 zJCM>GP(3Cm5x<4gmH|V|PSn&@Io+shP(X8BM5a~aiE%~mT~<+9wfwc$-&pbHTPs(+{m$xl*SxoOU3Ja+4I4MTU;Dv_o9iN5>OYdA z4Ih8fxOH3X)27cpk8hWo6N;K_Y1P`kNToB`_AhnA?D(ql>#lFU-SOS`KhSR4LwC|% z+DH58F8U+=iSDL*=m6bI2kAb#pB|tG=^;8q57S{fLXXfxhgf+%)S~u7q z>=wJt?y$T3W*E~2B*liOWE0TfushhqaOi+cusMOPMMB=1Si+}&X*73eDaCFaAia+? m55N7Q*{-(R>lzPiHn7=2cl4G9O1-7tGEbQ=zr=r!c>f0cM{=kD literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/encodings/iso8859_11.pyc b/PythonHome/Lib/encodings/iso8859_11.pyc new file mode 100644 index 0000000000000000000000000000000000000000..4f91741fd24c11b6133e47f5230d0cafb58598c1 GIT binary patch literal 2842 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 ZxY<#6^p}Q8{iXggUs<5ABzRBw{|4H+bTa?| literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/encodings/iso8859_16.pyc b/PythonHome/Lib/encodings/iso8859_16.pyc new file mode 100644 index 0000000000000000000000000000000000000000..b8329e7aa31558bf751c7300cbab65b028a591d1 GIT binary patch literal 2750 zcmc&$c~=}o5br%%mMgasiEg}DkASE_qA?Q4AsPtIq9iN28Fpr2a1WdrL^K*;3FLr; zBSwxK#OE`{B$}u%F(K-E-8=8`Irs{GfLPVT?g08;NdC}Wy6LH!uCDskudCMaSDyDq zOa6DEm}Aj~!**-6w!g0OH9*+$yzBm!$E=_4db$o`<6NG`5$aD_Xg za1berE1X>6$tave$|ka%>s%xP2D}-ai%2_oSdqyvJsfxOPz&OOuge2|7A`k2@rGTr4Oz62aXy4W0*&0TncCPyPY z1SQ_yp>scERZXaxAC!bo+6GvaH0@EEo6=UaCJRUa!`#NP$w8Y40I@wtBm!<-6a&Bw zkaH1VE{;J!^aVsu$b#vA&#-t89_wLndrYRW-^hVKVQO*&m@ZVkL&l1=q@%UPGI6A+aSl z7Io-_I`l0MR+J>k3iy#0bvj-!EG`;yW4@9?r?E;4XR>0|1+$Q=OT}jOQhCmxdqB=$ z0A33Ooji&BT(h>K2fSU?#3Kn_k*s3{yifu%LO?hK%*%aeQ%A10$lwmNOI_{S2#*>P zl-ROuZd)#V-Td1D4IG4ahtuWG@??8+a`W;FR;*mLdd=E(4?SGC{*j^$k3Qzx`1lh~ zKJ|35|Cwi>dwx?%=?i5qzV!0u@>eRhy!zVK*SEbiA-?LD=1d+Xm3 z0uArJ*SK$g@cpI_J`5cYo5PYEX=zp3K8nWTiT00GP4D=m^V6=+K0o-ymxpLK?V-Ii zN&Dzw+D`}Q5qgv!qsQqW9ik`bNjgkN=qMedr|4JoH2s>6(+N6Br|21amY$>M>2#_u zb=c^c>%B79ea@Js7mW+_((E|BY}}$(joZcyy+*I628~|h_qpz~^aj0Y{E-@(ouD(u zs4-^zX53-jtcUfcdRbqppY^i=c7z>e$JlW;$cESnb}}_=B-tn%W2cN^cG{RUuCWO= z$)?zu)cEWqJI|)s1@=uU$-YeuuV$bL$V7=7$#_6z&f7-2Vz zDdRf3#cs11b|*D4JH`I=W5R%@*z%-A7+M_m2a_5WA&?6uE3ml;$Xp$Zc>1?SbB7X@ s%+>+Y1+=;M{pam=tJz?;IbgGf?GE~*v(QuMEOZt*id@+R?z_bKH?MhfqW}N^ literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/encodings/iso8859_2.pyc b/PythonHome/Lib/encodings/iso8859_2.pyc new file mode 100644 index 0000000000000000000000000000000000000000..42b7edc2e41e3357e2001a75ff3ed65d763ba076 GIT binary patch literal 2733 zcmc&$>sM4&6hHH17(sj&Mm6?gdI&{XSY`-5q6FyO&OUqp&hPAv=g;Ecjh4NU z7@7Nc;BO5K<0c4&kXDc`qPR)IMOs1e5Yt#wSXu~Noznj08asug#d#X zX(U{N33P!7HT9aE=~Sq$Q`Y5}sp_EyIg`;+9ih6kqQ*j+k*==ZurXQ{>QGavE}NC7 zod?tnE43I;2!slO18@S<0f-mU2Hj0i_Yf%(M)*xXe%;iym>I)44lj&4TwV#nB&5ql z_Q9{4m~N8wK*}yyZ*;bc$P9BSti~Ysq@0P`;ff`p0t!)6ZcnK8E_dV=o0fMt_Mj(!mSHZ0JH&du_V-m zDM$#ugy2a9AnrG2+c_dO7jqaPF#{l?(UhE2qfs*`CdstYoq(x?HVLzI&Jx<9AW5)? z6v8m@48Oa`W3B+DJ{8l|q?$72#5RGT9)nf!$rse99b~}YVO|TX4qt#c zKp78G23~b(B#dqwH4sE(DYbiP5B)xdPh!kcxA6lsh&nX5W zd~TN$hAJR+9REu+@zR#(y!&1EV!2h&=KsMGFWJTtxpNPe5*8{a+r?o-uC0Ob&oD~M z!1Q2zMD$kY90P)QH4#%+U&I@=c?e|-bRxLq+^Lh6&=$`P=}`(p zEFGbvbc~MEb9929r<3%8H84BE z`{?jfzGZRa9?!SxnZY`nM{Q_3!QD)JH jFFNcdyQgmUz+MAe9P~tQX`s|w>Miq>`3g(?cZv5e-U@E| literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/encodings/iso8859_3.pyc b/PythonHome/Lib/encodings/iso8859_3.pyc new file mode 100644 index 0000000000000000000000000000000000000000..43fd69a31820ed3deef0d718ab271690d8534d91 GIT binary patch literal 2740 zcmc&$X$Dc*sYt4H? zQ8M>&!2cQ;+AK^GAz_$pM6#2(jf6pP5ZOjL>?8)Vlk^hOL&)y1ok%WjaBzb=XK)ZH zj~kra;K>=BM9L?!o!eX_1`fPAn~O*VS(}^N3Uf9$k&18;&LdJW346E$@Z=#q5TF+$ z4FyUtfex7bjoo^CD(SCl7gaH;%c{RYOsAD(o4+n4$x*+erK+pfZ-`X++vKFIin=WM zV`?hlFKgJ`*jOLj9;&Pl?ZihaaVoE>Xxi0O=I>JUc6=j>PAbyf6<)7$3qC>J1)Fl$ zIY8~8sl|BwFv$=&0LL-yg?J%tknIFz2N6O6gkN{#LcAssfd z7yj%-x046?jY94TF�(|^VneNni z9I~pWR4o8T!Y8d1q>7duN^48ji`J5Z5wI}d;?NYJOU$3x?j#WbUtN#_pbdy~6&Dw# zARzbxf+ys`bh|N|&JnS>m;(rj?tv*1Ns0+M64AYUkw{6Maaamy6EI6_FD@+!k^t|J zd>9(;;kFk#^c5h~C!?yIkdwL?-^vkGqoC!V9F11N(xegG9*J1gK?eLC=Cz=;_yWWM z$~cfRaI1Zx0J;q-FcF?Dhg?9yaR>#Bj?=@!mh&T~B*nOu^wRkvQkdaCX6w=&jB=1_beFLb@u8iDp%Sx|!o4vaA*##1l1n2xSXo!ntIfsg)L&md*|7;e)|* zTM&XEi_(7*0v1=SZ*w8!lE!1ILwyZQ=4~>YBD6y+z;LbLLOHWC^fniAT5@A8hX$xa zv+`gm=^=Tc08%2TCRLw|rFbc_wiWO$2}lP4(Gc)dZucm4q-mQB(Lj&X)$Vn$)R3FRmTz<0 z3gPSK-_Aaylg;jMy4-o5d~ZQvQE|z#tA_wM?-LD<7+~w>Ge07 zckK?p+49!gkv(E-RFY$D?MlZx@kBC}epl7>&iA_B@BZM!y&rx23EfBc(*v}J_R>%3 zXS9#@(*Zh2hv-3ih#sa#=;!n(Jw}hy6Z8vulAfZc=`cM*&(aY(O2_CpoiM(+d76Gj zC;#~UH)E1c(euW|%$PA|%+P62Wv#>xJrM;2X3%^ zY(F~yBI`8}z~zo?oj#Ax>2sDkN?rLS?pwt97lw;>V*mgE literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/encodings/iso8859_4.pyc b/PythonHome/Lib/encodings/iso8859_4.pyc new file mode 100644 index 0000000000000000000000000000000000000000..162ff0dbd25d5057d0bc2a12e82d0d37cf3a9715 GIT binary patch literal 2733 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 awW!BoQ}maG%KT;ia$k9%urzp;`Tqi}3UcZI literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/encodings/iso8859_6.pyc b/PythonHome/Lib/encodings/iso8859_6.pyc new file mode 100644 index 0000000000000000000000000000000000000000..6cf0f040353aa34d8c9aa3c49bcda9054cf44abe GIT binary patch literal 2778 zcmc&$`Cl7F6rar|Ap|JBH5GO1MLYnnBGpbx=V(sE0$C0=vcEh+pY|oMbp-(X(&0nR8X3G zH}v)Oq_(8ndeYnQl{V~J+FSd#_ctr!79GJAIvQy$PqfD4)|afnCU`) z6zEKF9Doy;PJ+J>Hpn4@vP{%;65*#&e4W~sPIVk(3q$M1>1EJSLPjOB3%(&jL!=@@ z$P&z_g5|<9hc1Fy9bzwN<*etfm=YqOkfqvC-t<=C4vv}6i4d$}d5j7_OxrHmP7;(v zbWRgUt%F;wp~0#ZXV8Zcu<%w1XzI`;#!sZn2}H%Eb3y>L0dX-U#JM4;2)>HosWs4D zs?VNrL~O?ABtk-C&}Fkltzc%eG%f~(k};Ntp^7>cqYU;E(t;qVu!ht^b8wGns9vT^ zLFg&!wplQXRLgG?2--T#ipQtXau|9vg4<(|fI7&4Kf}BVW&^$eaey*1QU-2yBArCD zDGNFxq7{&rxf}{0g<=)MR8k=|=_FDj zMe%B3R&j7RlR#VAgOnmjYy}CyOW*eVX)kNp;=rJ0z=1&nv}R3=ixU*vdMOom6h*41 zm@A1?6l|;FT~d(_Dx#s{sa)z&Ql#my3En`Br1r#W7&^#JBGpP!sUAL2@fn*&I!Pfp z9EsM%YU6eF4T~BVFIl>5`HGcST$xyPRnyhiT&t|U?)n>Uys0^P^DVdD*3#N``yF@Q zb@!U~dpg$Md*8bI*FVs?p{sl2rp;R(?0M+nt-YyjeUGT={zo4h*uEq4_}~*yW_M~s zx?$#qN37AO@`Yll{Iu=Rv1i7gop|o~T`#=2o9$tH**;cblWadbzz(uQ>@YjRj}~cAJImhv?blztFFWUpvjslIre}}; zLFQ+CB|i%ye~-V^r%0J_u^Dp=`|B`>jzvkcYZ~1rpd;SAI&oA&F z`A__3--0K&d)&S5KDXjdy8GP&?m_pEd)PhV9(AYOWA1VHgnQCG<({6m=PCt`_kBHSc5MQR(P7fJXJ<_e+E literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/encodings/iso8859_7.pyc b/PythonHome/Lib/encodings/iso8859_7.pyc new file mode 100644 index 0000000000000000000000000000000000000000..f9be977965bd580d749af995ef2eb660a477f50a GIT binary patch literal 2741 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 literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/encodings/iso8859_9.pyc b/PythonHome/Lib/encodings/iso8859_9.pyc new file mode 100644 index 0000000000000000000000000000000000000000..6792ad8c9738e2e5aaa18cd92b08694e28b00d19 GIT binary patch literal 2733 zcmc&$`Bxl85bix$76`eOh`RC0dW3jIL1QG4Lo^VajV3{KGwjU5;2toI)e0=n`l7@AQ zgeF7-NsrLHBIOYcr1*sH5v^X4B;7B1gy-a z7rIy40wPHc!Z}+&Xa$3|ptKd{Y(b$F@uVS7Xk$b}NID=-A<<0%hB?w$w3riUB@wCb zv|F;7NOg;9stH>+BeiNslmfX48>rwR7t0 zYw8xnX4J$M@mFTBm|jt~cA0=uqi82dI};syLnq z37rBb;3TF!6fdPsx>vC76G|+~@Y_NDx@{T>JHc}vej3%hJb{EQM5{-vpkJ@By`tMk zDSK$W&fP8}v+OannxNd%YFpe1S1w7FP>9=VQ%ZMs@d=imO3DB z_IOfiG6_>p>ls^3&65b430jq(9E~Q@)S(f*9!)l<_fT=v9}* zqU^TLAR%P75^{wJCm~cgI!O-~Tgi{4kx^4_(xd0gNO6Wkp;Zd`oFWp^=X^C~=@L@c z@xMfqFKyhQ_n>DamUAU-{vRy)k{v9WJ0q}ExKO#-jt(PpZ8D92hEW+yrYGYgqc>^L zF(JrT6SGZSO)oJGs+&0;GRvy?i+rOF52>)SvGxup4;s(HPVg!7u5rbz9O3otz^dQkpBoqAhFJPA#YF~>y%VJ zQ8uZXOfoA=k$bGdZ%JV~D2#@}xAM4GX){fmb&7_1q-}OirK!c-6rOxf&{If1LHX0( z#dPv`ef~f&FO(lHC@dONJa*jp2@@wxe(LFxDbJKX``q)9sV}_v(#x+*i@y5W>u*di zoAKsbZ@=^I%=g|eulV4@Ss%^*xN=Ta_1t;$7kpCl>1PXT>lW32uEZ99@#T`G%No9F z{Q8^taB;66qxIWVI+Jbt&a~|I?>m0z{PCw1KmW24x?mNohHmJAHLw=e!Ft#L z8(|Y{hApraw!yEk9d^J@*af>`5A20~upbVdVK@Ru;TRl;6L1nv!D%=H zXW<;2hYN5KF2QBE0$1T0T!$NQ6K=t6xC3|L9^8lD;SYF#UAPKYV>kBT8eEI(a6N9o zjkpOn;}+bC+xmNPJMO@pxC?jV9^8xja6cZvgLtU_^21*2!^3z4kK!>rjwkRWp2E|3 z2G8O-JdYRfB3|n6!z*|dui0)#38hf2`H=1^fpGKqH+9Ac-kw?a9m&(xRU zF?ay@X52VY3x`}{d)Kowv*VfB@3Z&2+qt{?HcIIJ^6@^$D1TwncpO?1MYZfu9Rh`Cjp zJEUO<#N$LfLYjG`JGDnh8ivZFD;_=Z2y2fX=`Js#KG!rF^iW^=2iK)-KwPZ8Po^Rb zSK1_XKOERTV3e;gp;lCHTv~WiIs~60pVVjoD-Af1ZDESze3F?swjEhyD}A%%B|9V> z-v*FO&a#M5L9C*{LL!x?kj}=R)9F}T(|lfzCDF6%wc^Y|jFOKmaN3T23gIG83X_@K zPL`h}eDSyxF1;=#a_jUx=#|TpNF4W|jGEZ+1f%2_f%`C@k5c0i^Wl?twwDigYh(*E z$&{IBbHq&A_%a`6)fva`GPx>Jd(2E2kgs={)ZpktH)Q=eCJR1*zIeb=k1WUy4G8CN zWiY-$fHOD@{DQo;NxH@0-%xWj;Ce4D1BiK`@FvCBR}6c>MY_XjMT6p@x}roOy(;C@ zaB?`cJ;hIHo_tMMB-AP`e|^X-yU1rN;mPjfib1Lv8H(K$_u~+d+Y@Y<8{{(w$%^$G zEK3GGfq{V&;tu2~j$Jx!&rqi_*P9&BImrWD-c_6y%P~1OB-|~rl z+3t8uaVhG*PWQZ%qV4njNc&`vcKpj+AygWr_z!bXx46;os^8yx?tIC7Jat01@4ocg L&I^ynTikyEG*~!S literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/encodings/koi8_r.pyc b/PythonHome/Lib/encodings/koi8_r.pyc new file mode 100644 index 0000000000000000000000000000000000000000..dfed09e06e7df1d22840d2ee40bfa72acf76a679 GIT binary patch literal 2755 zcmc&$33n7l5biy*SrTs0VAREn^&s&U6%h!B5wgTt=9=tVie^_)I_5O zm|kuO5N=dNB&ewG#Xr#V7wRwg1F))x>;U>ec+cl-rqf-uU0wCn*Hs(%vpRZl^}1x5 zU3~)he?Gp&5gateT5$9+&Cjwv)`F7&(|v5cpJi|!WW9{_Ft)bE&$N(K1f(KdRs@(< zAr(QXh?EsUrd2ZCFLfc7K?BjUF2uBPW4f@^Rh4yNrd89TrGjbWSxZD3KuZzUgAPW? z(`0-C1(3xd*4%A%6!Ni#4%JlCmTtzH)Xq*L-yUlyXnH!fpX)r(oHJXgTe)WCtk_1w>Y#0DGE>*tT^EfS zSMW(#Av{(ZFGK1_$wKldhJ%i-BXkngUi26P$GM-;JiwG>oDyJ#>Fbthq^&fq=?&uB zK;kJlSd6Xru}%2rXO^G!1TbhH$`jsp=~>YlkJ2e-A8!N_-ZS<(;PGz(@ij!GtnVhzsfT9+Gbtz%Y-tuBxVgu6xJGLGy~@XU87Q7E+a zI{y)Bgjoz+|WrY=w9x!BfaP$qEluNsEk;SF>Kkw+NOn zqVTQ-RjHyws&SA8m#EpIF2VGy{u>-ASChs}hkZAqxJXjv|3Q(`>!L`MxdBCmYLgf0 zEdV5bO~?120aPZU>JB(axJ?_gir7&`l9s8fxz(nDMY7C2V%9?XA|=x09#$xvGszz> zm0mz{c8jQp5>!NFRM(xa=&JVLpHCIE);qr(E~Tb{p_J zPuLYOPxvBE*9bPs#K|+=x=E+YHq@BU6lB%$j#cRLD8vGVpin3ux0OMQc-gL_E7$@p zvwJ2ki$q4|tMr9^Rrm?ZPuC@)kk20ohQbw*%ILVN>hTjMPMSPr>a^*1-CZ-|p4xlw zyFWJbfd?OY_>o!hM<09qiP?4aPd@eZGtWNv{0nnleCg%6ugrUO{(^-Kixw|g`dZ`b z%a%7KRy4n%Bv-z+@0Y5CZ0zU%$DDYw6$ABLPeggPO;HQ9}27U(k+0j$ZSK^%b-uYBq z5I;J-;s@swaY_6neipxo%i>q@oA}-N+S%f4b+$P@;-Wb33^-qi5vR}j(&=|Tb3PZ} zib1hm92d6WVp!}H$HZ>2N9+~*#C~x=92AGdcVb8!7DvQUQ4%}ES#d_}5+}ts;*>Zc zPRA+B$Z6_Ahg$4ft9;BB; literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/encodings/koi8_u.pyc b/PythonHome/Lib/encodings/koi8_u.pyc new file mode 100644 index 0000000000000000000000000000000000000000..58af99f06499ef0aeb1f2f7fff0ba5b723f4be8d GIT binary patch literal 2741 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 literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/encodings/mac_arabic.pyc b/PythonHome/Lib/encodings/mac_arabic.pyc new file mode 100644 index 0000000000000000000000000000000000000000..34f77a80e16e7af8cdde204cef189226e8716a8e GIT binary patch literal 7879 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 I1aS2K1Vs*D_y7O^ literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/encodings/mac_centeuro.pyc b/PythonHome/Lib/encodings/mac_centeuro.pyc new file mode 100644 index 0000000000000000000000000000000000000000..f648c4fcf4b4a2e541456c6376b563612bbcfc4b GIT binary patch literal 2802 zcmc&$Yg<%R6y9@X7;fGRqa3?AU4-seGvuOCIMNxs5j7spIRis;p)+S9%JLwn&?A+p zD5!;sl~QV1@POclIeUNVU!1?t53sfNapnN^frk$@us3V3HGA*1-u3RaaQ#){pWJ&O zERlO37yPY;k)DD{CZq*s2a%m5?jS87xQOB)olX)3*-iQh=_6!+i<8J6Zg6pfH*ate zxquto+~CU_+(a%Uij&(sBnk)k^EMBWi*hzEw-x7YULu#^qNRYyrKH8j4}g<=qz@eQ zqo?6u83vGnDbUoTb)=Gk+73|_B~4KSJH@W9Sh77(o01hNkPxMaq$D*ZqoxAwN>Wip zO_2jpHI)c#+PST%sUfr@T(ze@RJThASHZfmzN)r9)Lg$?*j3rQuX$6TJEnEuP6^Me z?CPoX`(tJ3t?@w{y?ZS}ABHfFU7vMJ#u@ii-e9L=)TM zinR-GNGtIu4r}PGpDq9<4ZLPUe(yj9m1vspY9GxOO6(Jyw z<-{W3)&)@j-~c*TadBZ30^%0E2)#F60ip^zv{Jj}66OB0OLYynxK(Knmy`=ZTFlCrUJy6ytW> zO9~nB!XW1ZEEMBaB{1=0w~O(#!hyBVUOJ|jy_LBOypF|))^Q5`KZs(gEkuz-ix3sC zgxLWv2~6bOIvD>BrmzA`%jPCxxHfk-;D|X2YpNn9_Npo?clhyqzI8JmIT(Q1JViH8CBNCKw&(+IVGYS>iq|LmS^=MyfV>b85CL|!Pd@eZ=E|yPo_+557hZhn!mxO-Wj^lyr03Jm z4u1Z{A)}w_wAUD<{l>6y-ndAQ(BsB99im6+G2<$mW;66F;}`lh{g$4j!^SOo#`xWs zH2yGV=qNpB%$oXG_9i`>y`25g)GuWxjqkJ9vscajOLQdrlQ}p>FVpMv2EAquj+=v5 z=mecK2M(J9C)iz+ot|Qc8m?MZ;aFI z1Uqi(Cr$m7sh>CX3#NY7)JKdd^URlQh@E1m8LX#GeTI#&VRnX%nfj=yf5$GeQFhMg zW#jCMF~sKB9d^w)X`Esc?7A_^Zm^r|SN0pbWn3`k=oGundf6tGj@99+#F<8hBUUV)fyzF4&&No(N6U UUG6J)m%A%m6`sN}?_J{l8|Jj23;+NC literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/encodings/mac_croatian.pyc b/PythonHome/Lib/encodings/mac_croatian.pyc new file mode 100644 index 0000000000000000000000000000000000000000..f306bac955a703ec2b6627fd8f105d532e1e1872 GIT binary patch literal 2810 zcmc&$X?qk!5biy*SrTs0V3fs+^&s&+5eXq+6qYy}Ibw8~%*-Z(d&Jp^7)2RK3>yTI zLxqSK!hOi0+^9Uy)W$D)9{msf2mIgQtfEWsRd(m}70A(*D*~g@Klrmuk>FcJU zE2ctg8h#x0q@IS8$=Es%+kn4bW_nqV52N>>KIU#0p5@Gms8tY#wA`6++!ZPzA|MG< zZcAy-F1jJ7rII29J=57`3O_W%$QrpQ8kv}Kvr(#PU8c9S7Ej5wjz$#Wa5f5bCeWz_ z0rQL}7Kygr76k&1pbM1{Z;wJE{3XIqD#K|UZae1_ZnxZy5-?^6r$iznr?o`F42wlN zt9GSuDUnU0K;7$vG#02N+{Vgrwxf~)Y{1fb1sC9{h3_|Ysh&%YwtKv~QHm2jmM8E=giI^vVl*l{56Bl7Yl%$@K zQ*PX23YqYtAV&i%RnS$HIEiDI$f=wrfOXFvJEoMqDa8wdo;wj;EGYELaICHKirvaBHG@ zwp~Mqu!)*R_Z(d2h^ov}?g@G-@FysKx(*PvJYJta5G)IohbL52PMkD(%G7DoXUx3o z?y6b$RNs5w?8uz^A9(Pghv!BgdGxWz=hf6c@#IraKlAK!&%f~EOE1rVWx=Zp>lW27 zZdkJPwZ_-qShhU2qUlX3-u%|eRjb#uyxscFyNR`Oo1$vT_6~jBd#Q9L+xfncGrK-m z|6%t>A8+{N(~ZyzpTQRBhn?^>?1zIe2t#lf4#5#P1}ES+oP<;G1Du94a2C$PPw*pL zfJ<-@uEABf4nK2i&^~7m*@x_7+#0ek!T0u=;X&RzWM8n4^Zvo%UtllKAF$8!{=>Zg z2+#M~7kPd&&+p{<9m5BC{*-;vzV`cx;a}m3eZxLzpXT|2-*)l-e4)=iRoKR@qxK+J z&;wr$?;74+_>x|1u58bd&@J+pZ^J#8f<<>Rmv#)b&w|$vg z1Kc{mt#h!sumv_1wnHAa!xyjvw!v=LQ`iZ+U;w^_eTDNQeIxtrvwv9d`N)8M1-8P` zku6cmC9;_MqncH)A5trEc;m8#h~iL&`jAA$&!lQ!{O6>tOHZjzmqG0)PK~8Ri0(Y! f>BkFvxIIU`5u2&MDpcjK@>lz+1Lc!~H<|x$Q7)ts literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/encodings/mac_cyrillic.pyc b/PythonHome/Lib/encodings/mac_cyrillic.pyc new file mode 100644 index 0000000000000000000000000000000000000000..3dd71a389221cd1c1c5d7a06f04fd2ab3928ee5c GIT binary patch literal 2800 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 KxWIdpx&H!obd3N2 literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/encodings/mac_iceland.pyc b/PythonHome/Lib/encodings/mac_iceland.pyc new file mode 100644 index 0000000000000000000000000000000000000000..05d04b752593b4d1abfcfe6a7d530d9e81345d28 GIT binary patch literal 2793 zcmc&$X?qk!5biy*SrWpn!HA1j)`P_RL<}SWqhX1&NFYX+$;@mrxJR6sh*6Y2Es*MfT@$lbU~pjE9!zwEvHRe2~#JtwvaG@mO`u# z9SoDF@n{7FVB!>M>9xADnMi$?Y{-hG8Ih%OcekGDjMQgUO^KvsC7~-?O3tW}PA#Ju zvZbk!q>)WWs+TToX=#criPx@Zj5REi;F%uwhxKdt#H;|GF3u<->qW^Tax8+Ah7llw0^ELd9OK8em(kkCqJ>DIk=%oA$Yy^azrRtTp=A|t1@M8XP-O**Ug zq;M;dPNF#7)5K~5KuP!(E5%{bDM4?U&zgpdri@}}X)R;PsYZdKp`cVeMKaC6twScf zOe%8;L_GK>)U#3QvIgmc#PJbv@RC=?qhvOw{- z*b|AE(4rW}!z-21N#!^RtBd87sR>wJ(-TINQa5$Xe$aC>o(+ON{|}y&Xa`SX&`o$s zRJ+`GCjupLZWfMzhf#w&)G z%Rjcpwih6Ft3j&n*c&bEV<9RmeXJxNC2GVhx@J^kOv)^l)Opuilv`p1oprZ7I3?Y< zS?p9XL!=G+2&N4OA~sI2R^(9}>=apYK{T$WOfoA9lY6X0w@M;XNQ8$(nYs0ZS`=2N zhW=pZw2a=lxHXBT%v0(Kddlz<6rY~mL@STi=MMx+LZ#tJW#yAArc9kSea6gLcidSy z`>v|H=iC#Sd+&YsKk#66^r43zd30V)?PHHW@#IraKlAK!&%f~E{FfHIT(@vheM95o zC9gES`dahS*s_+_rTFqUR;%N>fUB|E$HHSeU-nQZsFhH3S@xAy(s z4?bM?(Z}ndA3lN2FaX=&YuE$(U<5|t0PKf@a2Srl5jY0N;X611C*c&Ffgj*|I1A_D z99)7Q;WGRLd+pQqsJ-7l%yXmmdHB{oX&>eNqxM<*2p<@MO|X;ahwU?b-~b;uXdkrC z@%%=f-^TM>|H$$Dar>Bk>Gz{>2rk-J?0xnLo*(*ckPqZ}ev^INzRYun>=DR8AAEIn z@alG+!|x8B+rx8vd2T1q?Sc#Zn=NqV>P5bxpKm+?U&3h^hF{=k`vT7m@!T-aoraCD z1vbE^kcZFV3)l*u!FJg3=l&}&2t%+NcKv#$u&J=eK2_LR*i{&^FBbL|b{95BDUnEE z>WOMr!5&Ec!{Lm}6e5X37ivBd)jW%8{Mf%E9X)zVby^Eb$MIWA1s{gt6gf2F_5R~0C&2wr3UzX9iqo2~!= literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/encodings/mac_latin2.pyc b/PythonHome/Lib/encodings/mac_latin2.pyc new file mode 100644 index 0000000000000000000000000000000000000000..53175dcb552dadf87fb01b3695b1658dfe5c600e GIT binary patch literal 4772 zcmd^?d3+S*8ONX9Y&Hi8R}e@zI$(uGB~sds1(6cMVcHOJ5)H((VcBPr4D1nSC(tNT zHK=&s_ia6>x2SmE2a5N7;(hjR?S0wb?_HBkv7e9VANog=%^Tm=1#t7p;Je5ZwVbQgjq-v}h%)N^}fttmrt{c+qdbEYS(D ziK08gzA3sBY?A0?SWI*ZY-iD3V7rP=g;k602Ad}OE!cF?Z^OPL`dyeUx;yN9qBCGK zMfZTs65SIvTlD*|IifYNxuUhOd7|@S3q%*f_7bgw{Xq1GuzJx&um;h+VT(ogfjOd$ zuqM%cVf%?T!ST3lo$B7;fJ3;hB*fPHt zQ(>oxo(?-h^i0@UqG!X-5j_`np6L0o3q&u3T_k!j>}R5vz%CWN40gHb2H4L9m)d%T zAXjX?QuHd=)uPwHt`)rwcD?9E*bSmL!fq0zldYRXZ-(6>dMoTU!5Y|lyXYOTI|Zp` z>s_LE!|oBi7j~Z@)oi_A^a0p|q7T8=i*ANJEcys+iy-4{%tIfAJtq1%>7L)36Pq&%mA)eGc}#=nJroqA$W;5+t6jFAFlx)>j0nX6vhh#IyA^!AxyDxo(BM zF8T)SO+gyk`j+V1uy+LcXY0FyVO!r5eINFL=!atC1q`t`l<_6x+gQ%J(HQ%P#uUP+G^O_YOZmdnueyO)!SS(ecH5X z*1~R2GuEnj+Hx}4YyuA-=}Lx{qL!-fmQ zX^a)%q#(-E1K&#o3ATAeaMZH90uqR<2+11!g(V0}ZvmnlLVrX4aucU)Fc`fFggX`Q zYRd&LC_|S)1ilUZxodd;teb2%6Y$bq-GO-u*Y`7iHikhlk{t)CZmsv0xAxs5+nS0e z+LH0WOHaqbe30{ zO}XhHo}6zY=qJ!?e)_X$1e&=l!ndbNK697=pAB;rdh_Xmyg|kkFk_H_m5njpw!wpl znXU=B!+bMAbog{8Kl0Hv3DWMR4JDN>zbhE@4UV7 zWGqMa-98%HHk$KH;(R^PEa4=Xk`B{nn`k;i*oR|#UoVqyV{rce4y40(?n~z6FkH%X zF?U7`xjK!3@5WQCv~E6n%(S^Yk&BwkMN}@Zn0(4FYkp#ewj)jW7L3R7*=KOvxPCRy zz#1?i{|x=FAeYLN;5mTYJC)lSV^hp3jF$_qRiuw2+!G_QHOhjHZE#Q|TFi>lD@Bbl zrbR=*7mURv%iKU6otmqo`O;!C*~{03ToL!T?aoy%->ezFIk09p5U&9ptIZ;s&&^d< zK7skFs!O+LOhw9ntiu<|VMaI%hr@OG!mAmuHg>pp9DH#He$ON{vrJG4m4u?9GWqsw94yU|EIfC*Q^x?i5BEi(k9Afls72XP&QB|PJmoNs^kr>Bwa;WHW6|)X-5uJQ?6xmH`30O>)FIU zR=kZQmvjSZ7mnUYvPn0Q!Wneo+MRRkf%r^NKcc-lAa-rBRxwRO?r-0N%{+E%TACNNsD;Dmq<;dmr47Q zULh?Zy-J#4L1t36vbmH4uaov8HB;VXa~Y}1g1pVGz~RP%>{G4VaO+-*kA~%EO%_0NnnSD5pi(HfOPDo!cp4WI&bt{I5H+ qyPTEVPtGpJ#o3{l6}E$s%HqmMWn^r@*us+X9Z)Tc{%?N=75)br|E?(j literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/encodings/mac_roman.pyc b/PythonHome/Lib/encodings/mac_roman.pyc new file mode 100644 index 0000000000000000000000000000000000000000..9673a31cf89ee47754dbce2d8e19f2be331c442e GIT binary patch literal 2771 zcmc&$>30-G5br&+SrWpn!KjND>p|juB9aS?CYv}L3B>3!*_lli_lUC-F^W1QF>LVQ z5l|rn%)u2BIg}gU~^QSYNxvDSHG@`>(65U z*_MsrD7*f+@b79InR7TPjJ4wIV2YC^9IO==E~YxzCMS#G+RgeI>tk#~tCJ}np>PR> zH?MFpr9dd$LgC9R+)OECs#EAZEQSXBd7XzTb7pj2p)1Pkyi6&kO=|&D=CW3wFo2eP ztPdUZlc(We2?dbGDbUoTccxQ;>P}gcqq?dE8sx67c&Z~%omSLnASp*9S~@AG0v&2f z)nr{&0x=W>mN!&3HPwaIhAY<9hH4t6a0Tw`Yb&J2hRRTR^ZMrHfz5HflU|FGrSh(x za=$-*4WE$i!IOpkJgQEVRFP8woK*B4(G$S-qth5WuAPk5E+&P8lmp#MKi9Q*RFBf0 zh8ssUi5KFeGq%aWw&2&vbSLX`VcZUshwRsdXBmAiN}~usQtpaa?h27uA`}r_ZcnJz zTXaH3O~gb9@l;p0F8ok6Ev;pOsAOWwl;Ntptv=q~He)5zmd6sYu-+2T%psE$KXcqk zAQHWLQwWGQA}&N?d2$7E?5WDVkkRZ{0I7K2UIjKe>x?gOPX{9@X zTZwcMMQNWURiDN1d=AaRf~E}{%x?b2|N%!cAPF%hkRTq42=2qp4P(8I=7@FNya$q75? z+2bXoD8d_|m5S(`Vw{A{HF6@O3P^3k{}N3~+WZ;oUdOFi)(G1CKUh+dEi8#Uw_qtz zwX&m~9Y*5X5*+^wqcjgycg9CTZ}E&_M37Pw)-_d5wrFuIo_QV;%c|&ylu?U^ShjG@ z1effb+F^;+?6DC&N^ywTZgN3VW#vC{fr=~Dx9cwCgQhf9lYBK!)@`ynBlbipz<90j zLb+$w*x)?GX~j#m9J`>79m_|hq>mMZgG7mtPFIVnN`|&rKv#%nWS0~{;<#N9tn#hh zDz>VYCK84{0~3Y=(YisfS!7TgYn4O|8H z6}`b8scSvUaGN1+GDo4q>nOsHSA4q1h)xct%kA+N_zL}Vii+o!%$vVp;iAP$?z+2l z={;rl-gkds*#i$g^zb9ggO5J;_!BG2E1rDn>1UpO?)ev9eCg#^R=&FGwbhkX)it$i z*1lf%#+&sGp~j}Sq;T`w>sr=tXnm*c-S;9J<@Tte#yUFVo8C_(Q|Yb`w2a>U;pUHe zKK^9Or=NWe{qO~BgF)B{-@yos!6=NwL70F;a0DjdC>(<+_z|YzIGlh}@H6}br{OG| zfs1efF2OI{7&T9tKZf6b$HtZ?6np z*~Ja~?&ih_H}-R54>$J0IsW~2xP0Y2-`dZ6r@3)~8yBxmZ@oI*%Z)Mf95;r!aex~q zp%=EpR`?RK@HKn`JK!tW1-q|KT!tYShJCR2*HgKH+=zK1w{C>CX?MM1Zy31T;p28CEHRk>c32T-6 literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/encodings/mac_romanian.pyc b/PythonHome/Lib/encodings/mac_romanian.pyc new file mode 100644 index 0000000000000000000000000000000000000000..f80ccd2fddf7cde3263951705d39950af9b30fc6 GIT binary patch literal 2811 zcmc&$>2nlS5Py4Svn1h0gHaYQ)`P_RL`(<)qhyJ*$PuHvXdO%3e0WSU+PMTHH+W34=!% z{6&L@DJ8<-6^203;AKiFQ{BSmV+q_KShV?=GOb|q3tL&y=4VPdEm}&LQo&jRVguYM z!1~d_AbA=MPp1I7aSAo}8XcK*sJ=ti<+!2hp(eSjOG~$h>NAQO52fUIOwXj`v?ixR z?P^-pWkXd$3DkuaHPtmYH%3-QYt}YImamqgHMm~YP$R8ws*5z%MXJ}VU$ZFGqZu9a zW}Nn`?&_@$2DRJxL<}FEFHR|9>qgBoaxH|DiZLLD0^R|19T7m;%}DkzDH^6s7=HS> zp=)s?PHP%o9QCB0jg!Gxr;BaEubUZe*6+dSU8s*ZuM5wzMg?l)2t!KlirMZ8l@Jk- zm?5_%Rr@VEA*&`6A_Ohn)olnrR9(;L*)STJn6e8{s%~ASwY3&@$+nJ16ydO66zEK& zT?qo_no2AZy?R#^2snZ+R6@Kv3W@NS2tTO=rzyB??@zehaXU=F7y+DOv9z30V=*Hr z7O9NVoy4U?Hi-gtjuX;kppx)4R*EA_$N1f49%B{?jp?|qrqr|{CmRHgdK|UlDe`F! zE^R*HjZ&DyA)>-R!Jdy=hd9U}+j@yc0Ze5Eev9 zXlXg=#678y2`>tAJit;J9aWB#*mi}S%&G!dXYa{lO4*xPIKc0ki0E=bq5lU_O0|tB zk!S*<5|uC~;7Nf=yqkyP-@%k-plQn7Bn;;k_C_2jM^Qsp<U>JD`s!uK20UW1BRvr3I+I^s|y^nCKBP=(16%$r9jLTNf9)l~Za2r!}Wa z*u`C+sJ5$_E;5H51v7^OF&n4o5vdd>+trqQ5G|}Royds#Icye)d%~MZ5^XzlazwqKqFTe8YlGm2LUR$@U zetE-+m2Wh@`PQnY$m-^|rRbV>)~;K>q2=Ay_uh|fl-uHpnrQFPIzLFJ(wVLg^{mnT zQP0P{pM1LMv(LYP0r(QO!XWH`?_nPtf)N;nBXAgw!ZA1j$KfQLf}h|toPo1&9)5wJ z;R0NOi*OCD!gctSnyP4GXG&4+_-gxZyw-%r@48Ro7cvM$M$mbkad}x z!`wW;&2!KP+h8+%1v&TzzJ=}ZHSB`je;&R8J7F01!qCn0`7QZ<*4g}?{7`<_x{}|Y z-<#hWreq?GsX;24I5tG;B{p#!x)4)r&QK$gsQMXH?hF5&v~_Dq#cngG9Y?Ck)Ckd@ hm)H$?sRv)rQgg&^>a7e^dMmwEo+@AIbpLJU{TqDlr6m9W literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/encodings/mac_turkish.pyc b/PythonHome/Lib/encodings/mac_turkish.pyc new file mode 100644 index 0000000000000000000000000000000000000000..7c1fe88895f071cd3a4f6869b56e1b9a71214b5c GIT binary patch literal 2794 zcmc&$S$7mw5Wcf!G9>Jv!H9z!<3i%TA_5^m1culXwiq2c(>+PUEU~*IMp0W5VS)>X zMTHPT2>T+7vI(BUIbDe_bB_Lp`v-XN2Vm80W;&n`fd}oGdvkBqbls}2zFQUFUzOp@ zYu3k;?Dpfszw>bzS8!4oYsT5b6faAASTinsO!cr0UY5eOpY<@-&DgqTFH-_S;S-8r zN#SEknNawJB2-fNnNrSFuh0cp3Jruyx&Twg6?H+Ot0?J$OsS+za~V^{v*wU6fR;k6 z8yyUjr}5|n3c$cA(%5CT=dzKyc3GE`rm9C)$Q>P8wk=YZQ`BT6BPSDPr@m1$+9Pdh zR@G%wRU#=pmx;_?v7oWBA+{u5yShHMXr&ad#r^X7+NM>~vWEE5nx?f)vm=`{Q@ofY zYc(BRHQ}&!3!j)7z|+MUC1kxQSxAmWa8fY>L{Na+gN|eTxb`wy`LU&WNd?nZN{&cnO@fI!`MA2kGZc4&kS=sN|OjeM(#+cSrQ77SRxz= zQ*KSG&RcYXp{7$J1TEXqX$n77UC-%86qQU&#!Ot*v@F+JTZ&eUmQi>j8qRy-v~gsV z5MZAB2}Pn;?+60%E(Rf%cLpI5{1U+@mEm;nUOVOqwcB1t2^KSiQzDU-GioAXhQ%h6 zQ##YQl}IO1obG92H3pz0e2bOiFzA$^x58&m#zjLmsjC?^Ys%?*fuf#7sd!3cnu=S8 zOn8|T<`Rf_@K2~`pwwjz(g%s-BjVsCuZl;>Y)r$6iFgI<646e;D3N!9Brd*!B`GZ{ zr`@o}5;37gF^+~;s-Tl9aS~P+%V|Ruu)3zlj3}jUQqg|Ub2pxg1bzM=JSou*p2VQL z@RX=_x$%w#O5)sf9RCibG!a$z%S%FVTG2G3NC}FYx+-VZ=o*&O5+8|e3+acHSBH;S z#Bj|7r`*iCp^4R4;v$H}=_PQS!XNhKMt z7+x-aagA*+K!Io?4U9)g&5KEb-+!ORv;3p_Po&7{BkJsl91j|C@;c*p}<0njXn9gK#9Utn3+4<3? zkGnqkbn|DQe*r!46>NiE*a<&CKOBNV7=j~k7>>emI0+}<6r6^i;0&CFb8rEEfuG?b zT!u?<4St2|@Ef-V?eq4Keb_$Ets(m|9JJ5cCwb41ebGL_dk0}F?B)3Z`vUJh!h4U} zN9{{IzlG;_^8AiJEuKGZpR%w0aT1QfRr`j0$UejKeZTMGy?LJBYM-{RbL*Hr2o`k1 z_anPTc5@5Ad$`rltpnWJ%dLHIh5xu6Zj4+V9vD72e17=C$iT=!ZXL3(aI2471Kc_f zTVOkU3134VzJ>2#2Yds&Vb9IOH((d^!G73xb7-)zwa{;$E9@=oEA-h{3kM4O3)`ZU zNn|iJMJ1QSCP)p$A&pBFVu`~S>OK+`J(G%j@&A$5PA#oCy#=MC2sMV{AUg6~rw7mT c;oAl^MC_pcs!)}`%3tlP4wO#_-eUg00R*g{k^lez literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/encodings/mbcs.pyc b/PythonHome/Lib/encodings/mbcs.pyc new file mode 100644 index 0000000000000000000000000000000000000000..35153404c0bdb0843a3423d2e10d8370e4becde8 GIT binary patch literal 2003 zcmbtU+m0JW5Uufe?e**?T!erH2{kWdRtkPVNJt2w-53xnfkEv^t5_=ybcSe( zJ|NSfBA~KE(+-s(O+yOU8nSg7kcFd52EQYE0m~7Y9@&7N_Gpe}eR@Ikoao84N9I@@ zeQ^wSj$<;BI0oW4**OMePQ?+4Oncnng?oB z8=I+l?bLN%nfkVgqG(jql{IR%Q9q~dnffs;%epcuE|=}-qIs6DR(WOpFssX9x;|HP zSC=YnvOFKIHV>oQWu7h7ZQ7_?mwRuk?P1yHmz8l={bbA8+AVNoT3i(EgwHx3Mp2xd z1J!Ed^2O4t(O6$SRF_4eG|wBQZDZZ<)(qA77j=E9_2u~S6Ku=>#V76{LVtpeqf2a+ zA-w$@p<+JvJto7uJo6cE;MPSOvH5Lup6Cz!0`dVpXZ8XZ$8xylq36|)-P*SI9buMN ztF@Pdt#h?&V%SK!=2MJDU*EL6fAQ5#kJ*;mS69xWV^jB5p zY-uZ>7T-%iZYM`x^$4xuJr=JmVlyN%3rV-gGgj@(CPDIY4l>|4pCZT(%lK>}@r-kL zsg0ILn&XRkzr@|xVy>A0&-Qs0Z6u^?H`94!yb-P#1ts0!?mqZ1^OQM0XI|i~#2zqzEF=GcWoTjGEl0QTk7rx&)?e;pS;aT@A#P{ew DJJgn$ literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/encodings/palmos.pyc b/PythonHome/Lib/encodings/palmos.pyc new file mode 100644 index 0000000000000000000000000000000000000000..07203bf5fe2a555fa4e311b0ab3b0827e51407d1 GIT binary patch literal 2931 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 literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/encodings/punycode.pyc b/PythonHome/Lib/encodings/punycode.pyc new file mode 100644 index 0000000000000000000000000000000000000000..e60aa60f58e32cee0e45f9b30970e3a890838b26 GIT binary patch literal 7685 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 KmY0f4BmV-ts=9#y literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/encodings/quopri_codec.pyc b/PythonHome/Lib/encodings/quopri_codec.pyc new file mode 100644 index 0000000000000000000000000000000000000000..86db8adcc6c2508348e43a3bf9253a92dad61a1e GIT binary patch literal 3430 zcmd^B-)|d55S~3dw&OTWng(c4B(_gIL>dIGii7|Gp-7Rc6s=XIwIZ3z-P*b2d}r>~ zRFTpb(!Ys6idWu&Z{}=YNGp-%p)Xu~lewM!G4sv0vs?Rfx&8b8&)txw&jS8`i?{d- zA|mQRDvCTx6!oB#x<@^aPS@qLMoEoEb?Vhg?WcFBZWrjJP5Dz&N^yU5sLwj2ik?Mv ziWcY<=4%k^4bhtvHOVSEZqWdPTJ(zOoalM4MbV-d7RAt>8x|>A5<^=Iow=b+(K6YV z*p_JEQFLQ&TcT)XX6uM;b#CiWbdx`N%N%gmUt=7G5Ib39Lp{iH{mUeCHo7;?C_!%sV*EQ7#3SP z&76Lk#+buyx8uL@?D+~Sx)wxNdhI@O4R!<{p$k2zoTED49d15=IFrPjcvP&BBl=B| z!_T8LK&bfl(&HAu`Laf?M#ptJgSEzCp4Ui0J6;eo40XbKBs$P;G6o!eHgPcN?C{uz=#kiT=#F%lrNv}qqmKcT#$)q5%L^UZL7dt` zrj#aq1mF^$&}BLpkCW4Fz3aGNFi9LbW-|P43C7*3`-`JEJkkJ~z01<%RELv1x2c0x zOvd9ZN7|~TtAU(U$q>gDPTez{f|!Nhgm5gjHKj6@&jgo6`~3! ztfX*g-LFA1vC{KSq!kMNVE@a zhK*8L9K%uAWKaeEc99z1O!s&a_MFsPI;)uBk?b=Roh4>Wj)Cpgb%&F}6(_m!# zeaG4C_eWVYN$@FN8y;0fE810dxmm@yPw*DJOvCGVj*qI{G|cS?H7`iYQk}n^)OGYL zlWHZGoK#69SD)9Rj;=EFboYnhy zF9K>fN^=WBru{KU3M)WXb6*`p4(;>V0u6N;!Lm}lLj;+KZ$i+#2SXL$mB3?OeKCuT zl(4Y^&%Dn|U6*?wVDQ7)+`x@%6D}$?813WuvlU{@C@CZ@C?)4mFrZHK7fM#gPntIgSv^kFs@}0u2{HxEf9(y zZoeQiuD&=DaOrhTT*I1OpAUdNsf}Dd&h23D;v#?`bK@Twz=>RhYz)* literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/encodings/raw_unicode_escape.pyc b/PythonHome/Lib/encodings/raw_unicode_escape.pyc new file mode 100644 index 0000000000000000000000000000000000000000..7cfb6c6ef5b1ef1b9285f36b8e90df89c2f740b0 GIT binary patch literal 2093 zcmc&#!EVz)5FN*klejG)1cIPS_yDRa(R=_xs3Cw5X zL1w`a6&s`lr!^R%?!X1WIl$qt21%U_HXGd1U_;VigTsbqX>cHEfvmBu4kL8nm9{!0 zYfGEUw)N8HLb5@VVS|Di1h**GuPFQv3v)8f{Vf%p?acEuo+fff>NuLoEx(78*z>#t zl^P>+|9IiQi&VVR%@Za4eK|RvtFa$UqHH%SCY^XX+3t8=5O3q#vxQ2>C&usf#ojZ& zn`OSBx%P$BQhk<5$M3)Q54u8h`yUVSwe%-GeN)H4`0Ns23s+uI%#Tn=%)_EgPi+`F ztkhxXf*1s7g`k1LG*N_M9!+Ez8jmNFX)@1f>f)3VjkRf`im8W}sfR`Cq0Gt78!y$r zY(yu^jfGl-fL?(${S>v%(SCY-#E#N@tdFi9*qJQ^y|aNsJ1AVIWtqFE?B%hN6PcSR zd&5Dg5|kR68I*gdl%QbuU0~DM1P8$uQ*SOu4|V+jg#kFV;0yktQiF5sBn#SufPD5- z6cErmf&~RsV4>7hX|@{1)JjyB%R>+^KexICD3}6LxfS?QnEwJ;q zQKqG!jnxUO!ra8S2{1m!y#n%UF6e&%nVM3xC^g2MT2`!)Sf@1{D>oF~18Upr0TtA1 zg7#F-SH+TO4Ut85m^T2 z#N?%wlVubNVso;dmnOZ87h_yesAu%zI+0Fq32tzzg;O zykHN&3-$oKU=P3x_5i$K55Nod0K8xizzg;OykHN&3-$oKU=Pe`F=t@j7xMwkSury( zvtmAknG^F7%)FR$FdvHvU_KG^Da>bL&cl2z<^s$YVlKjbDP{rYl9;ZVe9)K6@0eHb4fEVlmc)=ck7wiFe!5)AY>;YV#qb$bhe#T)!%%VnV zk66UvifrU1N%GrDnv~^9v1po<^?iy{vXz%y46Ws*R=rC7{SK(y-t=poxU#qwB~ioM zq;fOrc3r$$S?n0ws5CoCCA@WKZhmHTw1Q8~+RB>u-Se}vy++zwnQ3%dog^}y8Ebm8 zzio8dF18!9NypF4&uVXDedJo{cK^GH^WMgll}!wkG|pa%O=2rIYS}664t5({K=R3cb~Y1 zZ}6Q@5ziv4_XE7hdQKkUmlvOxtpZ$?L;cdAdxLIC{T|dd;Inqrt=pKDejHU=g!k&G z&-#!*wXLQuz{TC3*IC#k=_F|tjiQiFqcn5>hFiJ6!;#*H7whnRcQfmv!%UKoOPAd1 ztRZCAf6N}s*_pi-ch5eg*F$h(Bk+j`xP>Px$0dM&($ zYzxN#gMqa4eCLGdAdE-K0m}LDf}cX+dfZ5C+r~a>T~*H|4b>6sqC)w9yg0%IQi35R^Mn_}y{yCY zGFwUYbrk=7wgW@%uh-DvK6Ilzloh^XL~1^t1&d1UKdcv_6{}+&LCWKm|?MruziXs~khr|psYi!9-tx6dzd2S>okd%oDIr8k>{2+CxYTaP(XUREvvO3F7iN*;h z0^;;g@D<^E!q970aj`O>ghdY)tfd#MdKgR>vZMVX%jshPPUqtE@N{vy Zc&u=&G%|4z;vV`>zGJ1m#gPKH(cg(WVyOTC literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/encodings/shift_jis.pyc b/PythonHome/Lib/encodings/shift_jis.pyc new file mode 100644 index 0000000000000000000000000000000000000000..65d6022bf944b5b187989d0bcf67e445f25887c9 GIT binary patch literal 1705 zcmcgs&2G~`5FY=;`Kgm21gQLo1E-w&1PE0G4wayX&7s1IWD@Tt*ovLX-U{^`o{5*? zF?ay@X52VY3x{0d^{!`UX4l`$&bQw0e(&ei*GWQmkB{#;di4u~#_Q0EC~9PfB4?|2 zDe}k=Wj<+_HZZkFL*q~u&;o8g{UF*9eTf3nEixWuZ83Lf;gSv-bB8nxFn7h=6LY6A z_ejGKh{uU|gtYKT_Zp9oGz_&zUpxll5jGwJ(tVypLyl=O8X&&(51vcg<#@lP3ma!? zWm}ky*V-gaP8?|7v(F0*h!+_!E@hsC55cF%Cp8(tN+VuwI~d})nB^vpZBHioTHmaA z$_@$dZv#lCU|B?{AlAFULLybKAe~J=rSqw{rp2!09^nF@%dE zDNSw)J6nB}Uz88S;S@CCL~av;2fcE65Q+Ca7*!jK9-&vfPvG9i^g&`hGA2HiCwrJU zYZF_VS+2}Xn> ztCG{h3F7qj6yGI*@;70Y(5(`lkC}NF#bPbI+5KE`!78p0#UK^uFpav^cv~qT_VO`OV6v^IIz%Ni35vpC@vuV0T%eIENB~ zA=#RQ6UV=kQFt z43EJBz&GQ@2`yZ5iS1p_&dl!4-#5;$Zs*6{4vYoPJ63##2~Hynu}!HXF#zFG;F1~*Af*9sH!VzIm`}1e3{6KC z*;3yuc*zP8pKm-+an7`mV1cYofrNxAUxGRre@v!hQBCrBIsV(?lk1gY6Mc-5ljvD( z%RB^ekw-YnXO4zMPd$O5?Al@tx0tO^}!o5{~VJ+CjjX2 z0ox84v;=SfQ+Gq7Pc#U%59FiR0eRCT-D0GysW}?3 zW{SJ)3O|Jet&}_>m&oG|eihe>Vl~C_*b4~e z2s`I744VUy#p(r?B?E&1SI_eCdh!mKS#^!dzA(L3!sD2S+0DWv)0Gk2M269sO(SVJ zI9+xq4y5>DICY;kJMQ-b@$SD$x7ZZ#&EwsZc5xzc`Ioq=S&5k9cC=sEIP`C-?)jE; VQ8H$aE#L0jPu;fl#NqJ@?;mAYPrLvC literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/encodings/shift_jisx0213.pyc b/PythonHome/Lib/encodings/shift_jisx0213.pyc new file mode 100644 index 0000000000000000000000000000000000000000..9740271c58dcd709669cbea84a8dbec4750b249d GIT binary patch literal 1745 zcmc&!OK;Oa5FS6`JnAF}0V*IN!6~PT#}%Q9z@ZZKusKv%kxb%sg00x8?5!Z@@SFHE z{0x2od^2vG(848`*xvQ*%MWl%Ac4tK8qGaK}}l}SR1}g zfkQD->XNo;4N-$MI2NTI&7kJeccL}Xr@$lKpxB|bDdHB*Y|>sWZjpun;~uibhW~{92<&y3328&pwR?J@}XW#&d3%EWac(6Q)V| z?fJ_WuS^51;Zny@9T*Fox2*UG6P!jEVw+M&VgSOWz$G;rKuQDNZd#baFrQ>`7@CeO zvZcOS@RAiGKHqqt;+$zA!2(&G0tpFKJ_U6${*X+^qMGFMa{RZ&CzmV5Ci)m9C(*Oo zmbnY!ERTvfi*qwsyq9~5+dgpwYM%nT_QL^R**pow=k8}(6FcuVr3A{wXGdP5{v3 z1GXJ9XbIo|rtXGDpJ)(jAIL|s1M;Rxy2VIYQ*$(6$IlHH8G}aQPl|z}7$Z_L$+ng& z%oI1-6@Cf{S}A!%E|JF_##f1=+$N9{9F~S}A2KA*^4U_bw7pz${VJ{%#cGPO9lo3uAb%N_2eBev+5d^ePMd3gvT)tv#W(krYj@3i43DNn?}-d zaJuYJ97yrQaOys8cHHg<;@y9huCXcJoBO*b?czk@@-J~!vl21I?P$NSap+%H-SZ9S VqGZe-TfW`5AG&Spfy3h&-ah~^P=o*g literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/encodings/string_escape.pyc b/PythonHome/Lib/encodings/string_escape.pyc new file mode 100644 index 0000000000000000000000000000000000000000..4ff4ad65b30c927d121164211849bbe678213af8 GIT binary patch literal 1952 zcmc&#&2G~`5FY=;N!%6?Afccl`Brlv4}cJ=C?Hjo3T+M*Q6=Nro8l^QD(|*cByR1K z@DRKh5?7dS+}IWLKzjfuJDJ^C&wlf>U%c;Y;kUg{ql_*ekAF9Ln6E5yqA^Q{a+jtK zjal(XJ9OmIgms@Th|Y;Vj$O(-V(`QeGzO3It{8kV^csUtd7rc^whm3$LD<+jl&>sp zf!J0XTR{05CgUzZjp94N`i@2PVPQYd%VCiYJHHz6vahHYdu}G3Ko#`a8p-g7;{A7x0z|#yMja_54#+~RAYht`quNZmr(panY zQT#TEW+K*x`#Z(KzPwzNhi2c{ihq;Z|L}OBupL;8&mwU9j=j&yc9~Urrc0Yn-w1}P ziQ8qf#Ql(!CT{MI3vLPz5hF7hdS^MdST~PYSfV3`zVMe7m(ID;4h=>zeC`%3D8@TV z1OU~cSJk{SVzF2>dODGU6y@=W6>U9mdi??OjS@4+9ACntt)1@H-+}E?eU9udB_RDAE|vU75opWMYpLwqLNIb{%Qqc6>B_h(n08L^uqONROncRJ+0px zWDr;S!O}Tr5CBKE(&-FWS+}`st|M|@x8?Hkp_*-7Zv_KIL<27i*}_md&Hot;bSvoQ z5=O?VJb<^w!#rnEU$UC0nWC+bQtpewOxr)C_yd34TlaneYCvun literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/encodings/tis_620.pyc b/PythonHome/Lib/encodings/tis_620.pyc new file mode 100644 index 0000000000000000000000000000000000000000..d83d896c75d0000bac322ccc06bb11b574165e3c GIT binary patch literal 2803 zcmc&$X?qk!5biy*SrTs0VAREn^&lWBUWiBljY7oPXdp(H&CYBxagR7N5u+%_2Eu*c zr}upyQ0)hKp8h5E5B%T{z^Wdy6Qa)(;e+mOcWSz(tE=96yDE`C8L)^f zm(g%9(PRqIMRQ1)VNnc;E)pWb3W@%(D3BZ#!$MSrSl<;EW=tz0S`n`)BEqcGil|m3 zYKo{Z>xC88x|k@Cfn-e=6Xv8*U0mxLYPz^E8~LHDPMDKLS3(;gO9@dW2b1h+COw4% z=%XpMcF60ilvAyJIVYF*EGM-lH!xtAdsD3y)5@nj+s!Usv@q3cl`SXdS!Sx>R7$CN z1A5#1lK-;1prb7_pWbWfSl2NxwbAzact@U1v;Cpd?-E-``m*;05Q5vnhJcA}ri2jh+M8B}`!lD|X zfJ3z29&Fd1x!z=2%~RwQM%H&%FKLl5$a=Y+qUG=66I`oU&>`66fk99EVL494anqy} zdUEHG)Y84$?&%)2;&xvJk&y8BXkaF>L5^O8ZX^tYw_XzfVNH1JB`sbXfWgok44qL& z)Af1mn`X4GdYooByaY|zY&lo5vRN;wA4(N-ut<*v>kN)DI7v$r0A$b(QBT9=6XM~9 zh&P>twsPLFN>Cq<;-5OH_q~YBE9b!&Yz!ahkktM=pq1)V) zNwe8@ne3H4UG^-f3b4xN2q;>~gLcggjBSj1tE;7FMHyPidq{TU?bZx|W7B zF#E5NqHPT$7a*`X9$g{q`DCvGIFy< z%@TT?l#J(Cxl*TNQ=P2wkJ+`HU*uf+{G&oevd|m~vKfS=rHSHVS~Stnab4qpVdc#K zzyU6$&4B~8fH^&_yuOSk{|5ODkXj#?Te?bgiK3%2^|2T;*^G1Lre^0+V@h!GsEWEw znyJw4@pa-l;&N@Ga>>0UC?T49?5p`wdVaIC>M$Y3HEjD^7&xxOTNOwL}5e4%dWIYV>l(Pc)8P<<#KYM^gie+Q9i z6beV8v3OmgJ~^qOaq^U@)27duIcxS!H#g0>rTNy|Zcoj<_>_ga(Z~);T!Xbpi2uBc(A{;|Fj&K6uB*H0#(+Fn}&LW&c zIFE1v;RA#Z5k5lr7~vCyPZ2&t_#EL2gf9`kLiift8-#BWzC-vP;Rl2t5q?7W8Q~X% zUlA@MTtWZ@iSQdaT>BwhM!5y$R+QUNR#6V4+>UYw$`O=1QSL&y8|5C9dr|H~xgX^L zlm}5BLU|bF5tK(!9z%H?I7_gLcvM`wy*-A>;%FMR)5Zet%vXp`9)_OzN=FrbJV;DcT%qj@3_z IUlGy206g@&O8@`> literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/encodings/undefined.pyc b/PythonHome/Lib/encodings/undefined.pyc new file mode 100644 index 0000000000000000000000000000000000000000..334120a285fd1f846927ab9fe8793977e5b39358 GIT binary patch literal 2454 zcmd5-QE%f!5MIZLo90?T2oRNuv=R^JleoO`hERLqkSZMkZ4RodDiznePPTIFYIj4( zE4^RBkKm8-1K^u+W21u9D*}X5Pj`2`Gv9nOI~)JHKlI zkcZKP(ZXgO6 z7`3{A(2usdgmrtZE)ja4CTBYYYL>o5SU-(~kl$>=qORoQRi#Z~E2AIFNv%yj8c94a z7uL(1=5lSzQfB2k+j!|R>y6ChcUieI&z-BCG(YC%I#`%mFH9vbjjiTvV&#n<%ab5s z$yUL@kCp{?Kp`(TGAxYrHkk4CMi#a-GSt$qZO9k0E($i0twO!bg3YB54tD92Z!1f< z0M57^ZpWk1sj~t0$>>*^%by-s+8O!6EH77XF4JXJ9+k~xoY%`I*pcQ>5bgEG+4&;K z$yA+uB99TKqPdsKc;kK`_|vcD>9JDB)0eNX&HjdG8U`SdxoXRxhm~hUt%NY38|mgs zc#SeZvM}xm8plG-QYxB|(C3IM4>`^0B`XtJeg`7({+mer#I|NBX{Y{O$TnrtRNw-{ zq{yfUdl0wuaBdn$eXM#@77W`~*Q>z34Q0=#Pzo0Q5To(=3wwFKwd&7XPe@X;iyRsP z;R%n3{weT^%rRg^R478Ni0FqRM9Bi-``CGlFeOuA2yt;yWlM8$5k@>&)_PT9swfp| z2cq-!W|S!G5tJ-XK9b&E9Eh5eDtBgSs*sh>nJ<@Pl^=@o8D9S$L{lg@)mn7LL7DtF zN#!!YfzQe=+Iw@)6de%mChN?pB2LvV1l#;FE4|?lJHu~CBjw}6t@R|jOX3%t(*F~Q z>JiX(VcyRlRo6$`2t{;fGRnN0sD5Z;FSk2?r$(6m0G^&<#$)GPE-{NcpKBJ}7o zzQUE;-;Qz14yc%QLj4(6alo}Xq~>uWc4jG+`ZUl{r#=#B+BV3piE#DWt_5&6HSX?m z)2AFK4EF#Mw&sNWVF8PvkKJ zfN72%<~FpSuOt!eMoF}XU&6n12n{Hr&Z_Gio%92Y8$^GBL(vg`Fc|XjS<|XNCt#l9 R0*d~@@SuOtKa39tzXMGr>45+M literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/encodings/unicode_escape.pyc b/PythonHome/Lib/encodings/unicode_escape.pyc new file mode 100644 index 0000000000000000000000000000000000000000..e3985181014b6a436cac8898db67a01b55f97f99 GIT binary patch literal 2041 zcmc&#;c62>5T46jF3Gi35k(^fPY`+qn+Fh)#;8!JQ8q$pD4f^3O?u&S3A-C5;J@~l zkKsf3Vm^S*%r$pb`@{B!Uc1xTo!yz)Z)U&R-#5H(2OkD8oPRd{-Nm85qDTOSC@n~8 zkXbN9#Rh4?qy{6@9XJCx1vnhmAgQy#W`kQAY)BexaM;i+4GttNkTtf|VT2C6(pHCL zZDn)WwqDv?NH%CPY*12z;0ERT1%>}^X-;OjzqQEIc$UZ=spDuaxBMPXV$bsqRBDXO z{o|$oCQ|WEH&2xG_vQ3>p~ikNjk4XWm~`UVbi3nuLA;Hp=S!82PmJH|i@hg)H_LoM zbL|VMrTQq7j^BUlA9RK2_TL}kvGfOieN)GzIChDxg)1*8-v=lp-oc_f)3x8f$YG)$?nI#kE73lZ`i>tCwuT!>dh& zT7*V#z?y!9TIXm#Jw9S5X+G9R7Xx+XOF{cLaA*gG>$EI$8cOD^Jn0GAq2wCGxlHMOT$Be70vIIh%0)bDK^mjfxNzXa{69A5=P zqKW$}?}#C#I50{^Q=$b~p;x|9LcM6s)r+KpR;9gO9yig)CXQ7tt2~5^l7E-SEzIFz zl}C&!f0SPjhklBpcxnaxBk>#Ns>ERh`MXZ-ow)SCkmL;#a+4VA6dHqo+M>@djmS$A z{18kXvQ>Eg%wm_ zL5T^vv>-&TRZ~MfKbDx%7|Bj8ALCS$H?Ufki-RQn1QZcrB1%tYaTpdHMLRD`MiARw cFCz-{toTRqoOH(Dwbq?>qwTbvO?$Kc6Fkj})&Kwi literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/encodings/unicode_internal.pyc b/PythonHome/Lib/encodings/unicode_internal.pyc new file mode 100644 index 0000000000000000000000000000000000000000..68daa8c5969b6b683ca724e11059566b0e055b6f GIT binary patch literal 2067 zcmc&#?`qUQ5T9Ifxx2Jg5k*f51{6%e-UEn8&#F+Ur|b!(M5Z{aZCP)L9gN(W>E zatB7JxS$+3Zon9I56%Ei0rp1?kWDtYZ15|C3$n!qj}7h0;DPLbYOt*dV{{NywkF7x zrOjvCYGw05uF+)FB2dHV24Ve*B7DEFN3$Y)GB2`pCe>zESfz_3e-duvG!24aPiNMu zB0OA#Zxfwv_6w<1xT~gzb3F;8X_9Z{<)oL+rW?H=h|&#w`(&ZB$&n4W2V&=G*w6D& z(AZ*TI#Sg!lmpg;6*Z=dlYTkCi5j zd=SG3tq`?P*fxqdE|RH=V;k^fI+OF9ran$7)YRB}sGbKNF9VNNK~~;&u3owg9W1w% zYI!_*1lG(W)OrWI+2H}Z$%=_NxOiCaWFhE{H5|r6;d>p&-bQ7oNVS@(!Y27^2BfQW zG|cqPbC98ch~5z_ z2vC^^t!LV>#nPft`IzgJ6(@7c+Bn0esZ;RR(NneWl1oAWPDJhn;TN>PuHPiNQGzzs z{;!teHoi;A;zRsD68wrw`5zKYttdJa80VWBRjiO$r8OK^Y$fXbE{@BSDX7Z??WtW~ zEssPS_m}=Lj|6jQwMwQ$5~|K%bz>>>Ws5HFCzZ7>@O6>gL@(<&mKCj$2$jfxiR2cd zcvvGzQRRmaZsRb|P?XoM{3PJVz%qMDj}_$fCN;YB>9Qg5TO{c=ao8!eh7q;LfNveq znW5t@ay8!#E-X_=R#QhwVEW>6Nm!ceXSjZ!xqiPbU{NuRd^(eXB^*r4JH>d$q*Wg) zsLX=8Lr~a)Kwh)5mim995Yz<8PcI(hl!FGR6@Pb-i_Wz4;5GsF&;j literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/encodings/utf_16.pyc b/PythonHome/Lib/encodings/utf_16.pyc new file mode 100644 index 0000000000000000000000000000000000000000..14579d22916f0837440ca267a680899f82d32fb1 GIT binary patch literal 4908 zcmb_gZF3V<6h6Dzv`t9m)k=L`L?JlP5nuSAj#5w@Mhwgrtag}*Y4)Z~NjA*xjhGqu zAmy9C!Wn;qf6O1C&vWi}H?19L9m?FxecyA>dCqgrP37#J$sT9bt9lkoda+P$=##Hk5ync@04-3Xh*&fx06b(XrL;f1Aoz1h8h z-47>ee`C{z*IUuei{bKM5Jv20VPrCs{$k>#uys3JU5=vV*4>}5t^W`HT6TsK*|gua zT^~)B0OdM|PolCSTb?`?dF+YxWxIk~co=UrseRqvrRbTRM<2IoU%t{tA7hpW-A%`) z$y03=RX=$+wz|or=_t*b7!$3sMYNXg-|Da5Hwkw4la1`YJ8tRWM7Ow8k78ZM1I4o^ zP~S|tsTrEYb_U;Yqe;7*r!HN3dx7)K*lX~odhhZdhyXuK_`#Fq!Yq&IZktX@zgX=ryY?>+`V+^KtySy9Ba`uMEF%>YOrm}U+A zsLo1TRM0e*oHF$Gma=D)%yQxS#F|kGbK7I+<-i-5wp%|vxV|&kyd^(F_EH+mJ@&Y`yvQy@oTU9%l)0$-R-ac<11dI4s~uh*h5v@JneABf zKIP)sQY}2J(ArfD154=%`Vz!zdy;&RLlxo?ksk^iXsfz23q+zjlXtOeMa6AJ4II^^ zhn1R)Xt;=^;#`wpijJdlHzZgTCo1Pbm93Y9!F1C_9Ffsz;>~yspYUkXJ#zv`Izs~j z;DUC0IEu%>a9jOXzk8!I$V_w!vueR;fvwZ1N?Ek^eEw9%AzP{-5F=>RYe8*xFN1!q z#JvxLp2J@A9|k3TVh}u9(MCYBq-(uIvb3+`yldlL&!i@vBKura)s&i3snf*>N1e{o z4^5j_s3u-QX_E~ihR3KA|AEFXC;5GfHkB|zf!l%HugH@?o>b)tfLL(nce*%GXo5Sh z=u|~P+|wxsVobduk2M-Ss7m@92@?Scgz*&UhX6RCDm|nWySNsdjBhhUGh#Wa)i~cL z52^QN^tF3;Zy@Oi5%*1J7{()$g~`aG-$`xwsBbsJYq!5wkVbD~`4llvajp4vC(cg| z0=&)ydk8omqyyed`V7V z!a<+*)TO0D4nhcTV%w)E8IeLlsLfkiXGJl=EOfs_>H=1n=g=)pp7 zQZG7-#&jrTvY^@J3o5XOdcaf9%|5P+B11XJOW?jy`nVXh?eZB{4^t+1%Cv_U~=ZdT* z$0dNt9@HhhB%bFbp8TjrAd$D+t=WutF-J9&TFGwN;yt%MwvJ-|C+0dhEzeqxc@?kj z&3i7W^EUicaghnX>t2cK#K0IIiY@}~1VP3!_j>q37vq%yRt_ZjSi_u)fU7#?A|R$t zGt9+M0wUljkAP2o4S(1kX!v_6fllL(YV#f3C3=HZ$cp!j&aiqHm3s#6j#Dl~t#6sG zjo#xzW|AfBUI1*KzloC3S!7ozYIrV@D%oC9%^l_O+Iqn^xTcMw+&1IaW=R+NM^P1u zpP=C^2;0F-;BZ(Fn#Y3+SqE^4Uq_IQ;%5=&A#;LMYg=Yl^y${ZG&lrVton`nJ;Noe z6jn3Le)&ev-?n>)^Sn*{%`rGq6F%-3lia`~jY%#mp|SK8c%8pJ+)R3-@{5}5MvQOH zInJSVD3w{77*CVbY~W{wbTUTQS;(s)g)jd#DV(OA?RGrsB5hX?>5D?y@D%19h!kR) q7N}s9$w_w^t;0z-haF$Ihr*X^t7tRc>7eE}DvM_q7Zy(~F8m9z2swQK literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/encodings/utf_16_be.pyc b/PythonHome/Lib/encodings/utf_16_be.pyc new file mode 100644 index 0000000000000000000000000000000000000000..0f60b753fe561e13563dc67faf9a14465cb1fb8f GIT binary patch literal 1894 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 UjbI~cg`L{w>zlVXuWnxZFI!-4^Z)<= literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/encodings/utf_32_be.pyc b/PythonHome/Lib/encodings/utf_32_be.pyc new file mode 100644 index 0000000000000000000000000000000000000000..863ab3810efd123b1b615ab4a88ee0786bc40e0e GIT binary patch literal 1787 zcmbVM%WB&|6uq+ij?*_3moBo4HpwFCvXm0Hg+MVyE`*wZYHP-+f-MJWObKL{d_=#b zKh_Uu&$)7BlWgipp7H43nLFp6`|$s4w|}2}AH=eJeEh%1$bVrnB16ocn2Jn28G2$p zIj_jj7lU6_ZXm3Rsj0js6YQ+ZjmWjgw_#08Llt#ZG)qN8OiL9_RkTY*Q_PksTB_)j zik6sdehk}$G6)_K;VVq-FPHAeJl)w{xXIq(!QR;J?)2uy#_i-Up1!Mdr^}Mq#T6_$ zsu(?rpJQ?&=bl`NTzTRua_z&q2YEjr6M8(Rz1%&)H*Sdz52CS+AcEM@*4J!d0~&TU zOi6mNaC**W**wbw$V8|7HCFqlpOf*aO>sI&&+^mK;{L^@o+=Etu{Ebn@!T`a$7!6| znN8hj`jKaC7E{TGyN)pO7nm$KLX;{D9fRXbSojmuo!iml_LrEJ-YWr!>ov}K(jBNb z{RA6CX$Z;49Rkz^8`9;1DpHZ#=_KSrshA|`Xu7HYg1bx7$dR2W zn$68(%1>hWG@9l%+`?*g;s3E7HgISgL;0@Xx0VhAn9jy(ihMtBx zHBE61w7JG0XyIUA8v(O3=V#fBltu-tRh+Dx!m|GM4)F=lU zC9O-|*kg}6PABu#jhfdX{R`=Q$lz>Bn`1$pSpYdh@5wIN!E!c2@mgMe?G3mQjIb`v zJdUCw=gU-54iu4N+dk3?ux72TEz7I`Osoa!E>;_(=CyB&_VA89Pa)U6PPJ9(_}yyP H$6NaceP>81 literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/encodings/utf_32_le.pyc b/PythonHome/Lib/encodings/utf_32_le.pyc new file mode 100644 index 0000000000000000000000000000000000000000..bc56ccc15052d9e71846eacd307f3e823615c4bf GIT binary patch literal 1787 zcmbVM%WB(D5FJ^5$LSl2OBdNin`Du6SxSl9LZFx;7eY-yb)>6QMwWwgO$lU|d_=#b zKh_Uu&lx$gNj7yP-|^MVow+k-9`2v*?(dWDqfnNQi~sjn#V?RZWDM#^RFl+^u_MNj zX-&qiMEKR^2F$ud4dpi^#>uAKh+K<&8#g3ssi3KXb|q*@)KNiO1>H)}mS{@_9ToH{ zK}Vu(evG?xW#m1ghp#}oUoP#BdA75=u<_pE!Cq>1cLwvwgx%yXo}q2>q|KAihBa)t z>R1D^pMzMDsUue+SB}`4T)VLDfIswzgsO+MSJ)@`#x23&L6DjNEU+zYea#ofqhZ?s zNwSNDRXvmE^StoD6D7rK?DkJTCugT7gLaag7pIlQ{fkT0Dh+pWw4hCK>@(2gEX>W! zWOkB%q^`+B3i~C}39^h{0YF}_q31|{q|po$ z91w-UCn9$M&=8EzkV~itMPbs|=SHE3lWdZ18h>e56I{mcsl7Ig20=ENnIN!4CkSTq zXn{-wde^5(S{Q!|g4Kophq~W_(l(aj-MokQ2hH>fZ(^Z%KgFiPd+M?i05+K75f#5j zLc;3eFaBZ1QCZZS3x2nBdj7?(&+E&CO(Xk|%bpFdph?8wMYSB;8^a-gnJ6 zll7W?sB6T~XG?F48k>j}zjUqY9-^u3@CKW*9m;u!0f%`I)x~1cH3XfG(S}mPOhcbW zZLuwkxz@<*Kyj#pfYn*>vl>PUqdKfzoUFRIEc5&>yX^klGN~9_NGcYPTVwpxEPI+I z?MvP`;EX!X;`!=Et!tn0`3&A?ayEs{vZ2lm9687A$uBv<3JyYXI!<%#^>`47urH%| z7zAa_SEZyFs7ID#`$#*$L~CPh*=D7~^tJT5kKM*z^V+xNczDN|r!F_0UcFQ6x&3OCzL?%+K2E- zd@&zDzi&1sK?O;ZoXI&eXXea&^W*;5ZGJ!bGKggPaq)kEm45??MTVe`#3dO!GIYc^ za#50@D=~g$xdF2*aYgwR8R2GCZbYs{J`XDr*HlndL475tN!(CDT?NgRpf2%_3K}YC ztpp8;cX=2#>B_*nLl2KYIv*DH>oo1`&F$#r{$8gyjZM^So@9x&CheRpI)_;jrk#)T zBpu`5JLB;nzcj{%vspKqPF{4I$xnRxwo0ouOClSUu;nUa^~in*Vnr?-xe~c@#FpgR zg(nX9eUGTAdc^m0+rk+h1^WSxU|HJvl+BGtqqYK)q_eqI9g}6#Ecd_@CHYhAx~K1x zvs05oJ4w&;Q?=HeEmWg0x`S&u?TKR_fF7q&W+o=J;rJc(Ocqhd4{se}<&QuNa6~3c zOfM7YieJPLF^u1<$Lmi(mQicq$o)0+9BB_Ul74~-a;CtT~t{*Sa@gMtUwF@mtO88e_(<7~jWch4F>U4gtVmibrpJ7Kgt}LKUCZE#C>w=A)6xmL;>5tAvCl zps>JIJ~6PF2`B7?jY7DslXV!}9zi1U_@8e1Cfuyg+qy;Ue75aYXb~y)*b=Q(mk>oQ z`&ZZ$Wnaub3_J9DTo#L|R}pkG#vDou^9}tN*TvQ_@@fOG0mZ&HJF78gx^*xqbn2*f zYO?OsqNKAw*+qwEnn;W!BoYgVZ7?o1vz}&#_*p*Qa@y@Qp;_Z+b+J9UymzEd;kCd literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/encodings/utf_8.pyc b/PythonHome/Lib/encodings/utf_8.pyc new file mode 100644 index 0000000000000000000000000000000000000000..25fd323f06f04de54a1aa50205cd86c14afb470b GIT binary patch literal 1926 zcmbtUZEF)j5T46>uC4DV5kH)M@d`E{M6ifR+o({`D4RlQD4faNCcSdGl)a4-=oe{! zgulc;<`2+k=F%jnUyPUTba!TF_nBvBrubvS{eJkV6VmJ};{Ogt_6;H;>Owjc6)172 z>yUQnv_Rb=MffYxC6pzK%AzmR06QymNpwMU)Gbp~6+=Y~wYi~6QC$o*F}QO>jiNO% z)WxtqH`FQG;6>MEC>{SABm4^CeVp2paq2yu*umEJW3M%ibm+S7p^2^4sn?%+?|UZP z+D#*)y?1)lpO~TNk9x^Yk}sO!c(mDcT|eA}_u16M!xQVZ+G_uax0@uM;&tXJooVw~ zM@_H&!8_blYPWrG1h@DnzP7C}AZy~#h6PM{lrUPXz71iCP8~WYI(Ntx=%R=q9O&CV z6E5x{L(l9w)(9rp4zPsE@;L`)qJ2KpmLcNwY+}Vn8#6YU4;_if9%0scah$XA^!afT z_m6dobK-QE9m~1Rv#I#z$6tp-#wU|wZ$a*-q0u9q+FtU8{j>?$$RF?8!^rMHXgmhe zp};x9Sx_XEM-*~ESEI$-??KGs7YdL-7w~ha(UF+iF*cA8p_r2;3Iw`V9CS_;lac9U zpm-u=4C1txtj0ioIzP{h0bfq7K@kLLZ={33y0RFJqe;R`M)J0oWLm9Zwz&3R*jH7! zGS_lzsX_EBd)cjG+7mH4F~=YtISU0uK<}*p^1YS(|Y(NIw)h z1+vt3yr}Iw_08|&-acOOT!2@c^-{gCUTl;aMf}RY09o{TLI3~& literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/encodings/utf_8_sig.pyc b/PythonHome/Lib/encodings/utf_8_sig.pyc new file mode 100644 index 0000000000000000000000000000000000000000..dd0160d89b9bb8a9b17fad17387549848e41ba4d GIT binary patch literal 4725 zcmd5=TW=Fb6h31+acmqKpaKGvY#&S_jdhNXGGwlTDm;x;s`H zi9CfD-umADj{dR!fcE>&*lRb02Ir|kGtAD;GMWg27g8T{|#F9 zJGw~Z8G0j8LApksVNjH)Brh>8=y*!Un4A`CWV0k4tSQS&kpq#RpOqw<(HB$tqLROu zmZ+*P%KG9|{-P{VO<&CDi`o3ej6|pT@T@{<8ufQ5p^>?m8{$B z^J?|u;87CTq}_`!e``059pASGTlIyFg1e7?#4+7&ux5ju)b7|MvXQQKHVIl8kFN$n zCr&emacXU_w&!eib8rD9^cSSI#fyTt<0U%0A!w!csN1h|dB!{R++3J!E8f|$(amc7 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 literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/fileinput.pyc b/PythonHome/Lib/fileinput.pyc new file mode 100644 index 0000000000000000000000000000000000000000..7e70114d95fcc598334c3c97dd2da2f833bfb17b GIT binary patch literal 14415 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 literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/formatter.pyc b/PythonHome/Lib/formatter.pyc new file mode 100644 index 0000000000000000000000000000000000000000..29813be42d8c1b177aa5fa7064616cc025e36a1e GIT binary patch literal 18023 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 literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/fpformat.pyc b/PythonHome/Lib/fpformat.pyc new file mode 100644 index 0000000000000000000000000000000000000000..046091a736044e7bc089bdab2df89ec8c05dd066 GIT binary patch literal 4551 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 literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/ftplib.pyc b/PythonHome/Lib/ftplib.pyc new file mode 100644 index 0000000000000000000000000000000000000000..b68200ee3cf1a7213a7765eaf16c5552b8f382ee GIT binary patch literal 33147 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 literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/getopt.pyc b/PythonHome/Lib/getopt.pyc new file mode 100644 index 0000000000000000000000000000000000000000..24607cd840b00997e3b62e30ff00e570e98f4707 GIT binary patch literal 6604 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 literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/getpass.pyc b/PythonHome/Lib/getpass.pyc new file mode 100644 index 0000000000000000000000000000000000000000..6d70489b664f3fbfffb9315b08fb996eda30ece6 GIT binary patch literal 4708 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 OeVovZID>hdF!2A>welVS literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/glob.pyc b/PythonHome/Lib/glob.pyc new file mode 100644 index 0000000000000000000000000000000000000000..6ca6f81690ec541c2cae9456f3c04a81aa6e2115 GIT binary patch literal 2857 zcmd^BUvC>l5TCtsoSfq{B~|Gk3A#v>SfxaOkdRQ-q6QET5LM?wikotr?>6>1=R5ay zO=2k#59wFnBk&0jedbf}MR-Mm-^^W8c&YNv**l)wot>ROznQiF=UV6a?hpNhnr8{W zpJLeOASuxRR8i_tu4n+J<~2hDsVmG#W8oOl7&c`w#0l|thRk79SXgm+chL?B-(hHrGg^RO7+iW_^jkaTx=kHm! z0DqX}X%bhdxithnXAedVg9v z9alJJW|Azv$SLzgTEI9}vGZG-l z8png(f0?FNX2{3p4Gu16hyqDR8yqJn!LWaUARTos>@CjA#G{Gd%vA3%^Q|hRhWgEF zt6AOi=tR+pN5_h6K}R)obsCfFAc2RqM$U^0TPu0(IvOs|O zWmW??oV2J2m>&tx)Q`2OvP4Cj5e(+&4js2}$VY6((YtiK#M@pReVvbPEEat* z12(~uKWO*q@3l1&YZ-tNt2OnyO4wg6B`%w74Eq}hP;56C!V};WmcewX1Sc@7zL8fEGE{VpKrovELyTxT{@hO4aLO<~>G$QIh0@P7Y*Kl8OG5tblslMa^z*B0L_?EFp!!lgm9B`twD_OXv)FMzsj9LPWI_ijUQTKHy*M1oRmIzy1})nd zfcAV2hwR#Y40{!X0I#mP0kCZ-UtLlc)e^?#8eANF&dfH3eF#z~_rN27x`r6qGP1&b z@IliY`^DKB8lB*9A`q){{U1?AjP$x42qNl?TlXG6`48g6;Y(Pm?XNvdaX$pGml3ujxsXbi z-V-HblN?Citcj~+EG=ZGEKGe#@}BeNhjaTq%d@MbdhDmbAd1p5iK3AIfk~94<5ecq zJaLT)M%@*60Eo}euv88wCUK3DIM1Pk5i4y^@DOr@WIZXTGoUxT$?I&&%Mc6qsyNrR lRR3qYD=xnY1#Pbjh~eY;s-xEY>web@R)d?tg`m6c{R3?5P2>Oo literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/gzip.pyc b/PythonHome/Lib/gzip.pyc new file mode 100644 index 0000000000000000000000000000000000000000..402a1fdb459955ec2acc05ee6dd11d4a0df977fd GIT binary patch literal 14921 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


-jvplK0#q#Pdh8qrS?kH)lGM9x8rT| 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 o^*Zu7(L6gvFeSeYx82{5eQ+}PKSm~&@Bjb+ literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/hashlib.pyc b/PythonHome/Lib/hashlib.pyc new file mode 100644 index 0000000000000000000000000000000000000000..c81eee727cfeb1891d9b634703cc158b42213ce6 GIT binary patch literal 6650 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 iduEz-hl4=g+`?>d;0(u02OtY)c=iT&) literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/hmac.pyc b/PythonHome/Lib/hmac.pyc new file mode 100644 index 0000000000000000000000000000000000000000..1d6315aae08568033421895e6492e88bdf46eb5d GIT binary patch literal 4392 zcma)9Yi}FJ6`kcvA}vLZUvZE&9kg*n1q#t9b{@77L{%EZNFoa>H)#mBi{b8&9BLoT z&eAdqyI&Oa@jLpVf1$srUkmhWd+wcGlCo7hqINhtd*|-Vx#ylctp9tnGuW|5p(y`a z`2G}^{U@48h(20RL^Tn6qF>{FUBq>fG(^8Cyr>~2Ein>8uZgHBPCfD2@2`pey3lQ* z*G1G4dl>seO?-cg9`-xpWi!?mGe$h)0=>MyN$=>tA|m+2NL&0M#HkS9^|$CT{ddF< zu)9e8qwWUn;4zvnzTVrH-7ocANAG^2?AW9uIm~kTwYFA`wA`B&W1SWzRE5dXZFx8^ z##t(pESkl-*Xi6#rm;?7VI>SDyHoKf%S|y(q_Q&7Hq6aHM{+Qi{^$F0_q|`;>~+k4 z@psVmu!Ld@O%P_uROLE|%t+g!z>qKkkIh5seSoHDprIEmVo}GyuW{K!G#dLyAkcCY z`gO(vaMXC?O%c@zlzxj4rVa;$IvfV-v_-VWk2=CX>bA-ApU_mRcDoB>Wo=K&z1U`w zRvjB{>b`?bocZ5w8%!envP8<33vJVEDZ@_ zE4zokIh4CMKiuxI7xO8W5H`>d^_sY7+x8#8=7}c&)bYB=5mrwe{gt^$_cuA@o``GW zX+t~#3G3o-LZpl$nbpN0f3m%j)x1c*)XXRjQ`(+PO%%vv7~CArFo~cJIxI@U5NVF}{5E~#4_#&pB^LTfp)oO~n&OP4OzfzdaW6H6QL!}XbXF|p(ySe6 zhH{!`k4&T^M=YA}vJKgMTke%fT``uFpkyN0{?2{>9j0UT*7AFg*A$xpQX#cPJ_`$| zN3M%mo{|T*)pOUq;^{LzRI`|pB&+=OlIYfQod>KJ#X6WD1fh!KAn-{$LTc!$;kt~= zZlVFHCrns`?T9s|RGK;-0(vJqG%a#nO7#U4UEDZ7y@y|!!NYN)!rpYwFTWeBWDu!O zcFBb7KujS9aTXp2*8EYMi}c|3nK79S<&8*MtrOZ{CT)TZ+>tX&0A;fr8p+#thCM@j zv3JoNWOC_Rs-l39&cGiC@W?#UX&Jtf5qIRCwX=kr-iUez^F{Y6n&JwY!0HfD2?i=W zj8Z0PAh+{z*0sCr<-dbG1n8OD;jWCl6WmrkhJ(H&Bt=JF}KE87k;_b@sNGf?s=njXMciIv0^B2o+_BMn0xR??_TE_@=X|2i6X`%}988QtP? z&GXx4`y)KJ1n>k?767hj@uEV6vph$(fipmM1-%ClAPu2H>B-V~ zj=F-J2TJJjfybq0cU!6y#YsP|?w5?~l2kAzKJAfN)-=OAf2>iD&_M!-|eF7s(r%|y6 z?W#)ekH-B=O#I3m>#}rpw|68;T6thtffG>xpH!qngKA0E2FC+~+N0IV`Na{4Hp3~p zq#$pSh3%!g`Xy#lhPYkTH@t%`RRhPjAXSMD0xt7G;C}YtmP8>4qAY|OkX-w84Dcm2 zq^pkW3yghw#S&TWouja{W(tWVL1{HwUaPistKDpGwA<}YSjQk;g#A7)wknwA$aFe! z)+=&Hb66I0&|;Xw_@nq_&rp*XCkla&37f!)9geJHRh@uX_TvcUZxm@|BSct z1VzMf8sFV!uZhNQ)M$rAiE>BTe3LMQ65E2POYfHIhv=id~lb7!Z6=dggaBd7Wec zhQ#nOPCp}!>Wi*_9j*TcH9w(-3CgeI>c#m%lb37$KeXhP-F3|Wgl0H;);4Mv>$~1= Lqt$HHE)V|)+M&W& literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/hotshot/__init__.pyc b/PythonHome/Lib/hotshot/__init__.pyc new file mode 100644 index 0000000000000000000000000000000000000000..4214cf3264d7379676c1801991f2342f7aeeb183 GIT binary patch literal 3319 zcmbVOU2hvj6rHu554$NTMJ=DI1|CRMrIt`7UZ^UdD&hf^YJ-G`DlO~Xv9ry3XEif! z5-EL3CH?>p{1RUHS^NMv=kBiKQnd=TJ>xsycg{Wc-s%5+b@b=YzwT$M{S5H`HH!ZQ zRj$+l>PY21RYvLn0)BnU^PW2Bsfg`?D*I|aPzP%&GHWWwZ(ZdZ>O6{~d{gBkl@HYm zrOuW5ct_Z&gc07jCqtZMxWzj=3Y@lj&St8m; z-?yBbpfW%dkaeKG5EOwZ;5q0MN(uvFNI{UKAb3*PP(YLda1~Gwh6I>BBNaEe7C1*0 z#3mb{T0`Og0~G%UsSy1b-qYHr` z`Cx0YVw&egHMP6kr5Q2hR3?L=(<@2uU)o zPaA#Pwm89cu8eL(A4luaCu`f$mV7hr+7+?fyXa^PK=d&P1McsVb^Z>j2fU0hmiobS zbXw&)7zdcr(2R7@j33FmnApXnv3N}U4keV!+(VXqgt?v?sNSpk(k)l@-Iqhe=VKEV zt`cQM)7<#X6?L#q+o^PSn(lZ81kG9F3!OnUrPx>5x6qt`-$Hq<=5IjyJ*?X&Szgle zB|K@=x6q2qK6^{8c%yv~_w`C`y`55A_W6oZbe*mUDc?uO(#VVuJ$2q>g_fFkG2xp$ z2N`whCPi?mJJn@6F=dHh`z$RNpr&0_oCbdhP!dT(gAg?E{3CNJt|;p-O<8Vq8>KTm znM*fb21oA1gob3N)N@2e1inZ;N9;q$LlgId+-K}-f|dUZD;_twhgUQwCcBf_d7Xx0 z0vGhbF_$5yFqJeUAL;gEs%M3>)f{1MJX-cLOU+6Q2v!>THF~U!-CuVA4izZyr)Dwf(i@!kFZ$g)Q z&C2_N6FDMumNe7uB%xS32(-tDaqeLy=1-ixHq^CqLmEasYog4zrt#SfFcyON=sc^--%=> zT>02KFxkx(bOo>H=_z2;HL|tImu5*zTg|=_7CYk?W$03coQr3ilcZwuJxP4#Br`Qn z^w{~rH=v_EhTRZyV6)oJ$dIfwX;q%?>ElD@O;h=WxNSI0!-{DOzf>kKJTI7Q+j#ad zRJIGaap&7Bxr&yfQE~K&`_N;i^eGCsyT>C7aqalB9u$9y>EEF=!ECd6E0JtTQl)bP zw`F2S;E;DNo;}QJlC@)|i%=z4D} My4JgfIJ43F7m*gsMgRZ+ literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/hotshot/log.pyc b/PythonHome/Lib/hotshot/log.pyc new file mode 100644 index 0000000000000000000000000000000000000000..3e161f12f04514ab739bb2e640361c6f5632762d GIT binary patch literal 5332 zcmb7IUvnEt5uaJf`e)fm?EG^`!iGx`9o&gKiUNvD9T#Hf&JdKUmBGfC5^L?qURl~z zc1LkkmAqW8j;E`u;(>y(_{p%i= z{<+ln%l0q3eU<-}@%tX0^mk|ie6<=WwOi0y?K<=KCAC|c(`B_=7TO{IctPzhsBuN@ zR@AtvcB^V!Q@b@auB+X;8aLE#L+JpMF=s&q6?K65i^^bHQyENKQU=qO6?tkZsH%^Y zdZyIRcF$0wZmSOM!hhkf)2e{94K&*y+}Y}Fbhb7;%i*lMv$%Ol(G;N8i>qQnu)~R955tJQ&%71Od2X^$mpU9 z7KLc4pee+X^13Z{;>FV`ryt|I7}tx;D88L=o#i)z>u5li##vUG983P(&$JLx&J{b`bz z$i5kbiRs%onYDO=wuYuR2uEh@Px8(*>KC2E*rs^o#76N!lATzUlXAKYIx>$lmL93l znz5W<7!6`M-JVb-aQ2S_8S2E5v2?m#YW@C^kp5(1qQHvqoaU5CJdr6q5V9ZXrDik` z+0bebwZNyONza37@7)jg_j29$z|o$}vdux0(Dr(l!IWO)B&UwgiasNsRi|F9gX(LH z%pW;qT95~bFOC$0VqLOyL?>?N&87S!2!GRKwe|}Zgy6;QkNa_wNGfxW8k|e{$grh$GmUi z$<%iGJS;xkyBLkGAwa`@rT@VDt-~;N$HpGUfeWhdk47eN2T<1d{X^Feg3yL>hJCnx>z;~^?9bHjntJP6MC0|!sYXCER@U+%r=rFP9#nKl=hQu7DxV64Dyge@Ja|B;pUFn3fO&{~UxB5F9#lVxH!Z>7Hu!_)RgtWV&Zc zt^eYx+H=%Xe8DHIM~+I`>WQPe58G-R(4U>hiL+p4df_Z!q!#l64o|5#l?*WP?V%h@ z6er`pkC37X+2M#MMxkRc9i`rDpjzBY=7nSx%!6b(HxbFhIL!f4c44#l$LOVerSx@u zRX24_7g$($Cf#;+;kjpG`vd1C|9ty@`R5u06gEMMCdvWMGq}rKl_i?@6*jWl5~;#5 zCB-6O3G*2Ef7!C|Q7lEXY+*{_qZi<#D0%W~h+8lA`5U18<4<*#t#JN(<^1fQfO0i6`Az0hHzB5R5{f&5(=nQ#jRlD=Ow3#@|ybf6`+==~k3_g`HQrYm5W zyO`ug*Ul!U#X8AjNP2jvKNby;l>^h8`=57-!&3CnPX!`3qrg1Q5R>&w*T$1gikCFSu-)&$< z)|UYHSYdf@kXeF1_iK0~-pK7{5GJWTb%c0lFcB5MO235$$n9J%H}z$~? zBh!FInEn}^SHsb#MY{YW1BQ+TuM~$)?$D9S0CEH~oNjha{0=(f@{-}%p5Q!&w;%qg z5cK=GpzQjS1&25#7~#7Ylba!w zVL;i|8gk%v^rgZoZCV9@^FFNi{s)Na?hcFy10U5?@_mMR7sXO`Wz2~TO@NRN0h16@ zQnRyk=nQmd_haxnLBlil=QM*)m2b$;JK+=EY@?dqprQ4WSm}a90$`8y53bVh#52N zzrpTJHeY4aX2ZLJfVlTPQjBts+CATeQ2+HG3Lejpc~5YmqU)FHrFyx(T(97_T3>A5 zLc5wtlkCZoN{%m1+ft&6+q{Rj9sxtLYnDSLJC^v4CiZA?nb_;$&V}9an7kUBIvXl- dTCK%uw=+AvOFx&a&xC}J)2^?SD!{W!>E9#$^UDAL literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/hotshot/stats.pyc b/PythonHome/Lib/hotshot/stats.pyc new file mode 100644 index 0000000000000000000000000000000000000000..828813fd2852a77cefb84ffe460692f5286844f2 GIT binary patch literal 3083 zcmbtW&u<$=6n^7fujABi5+yD40v1$Yij)(A1Em5=%a2x}T31c6f);0YovdT;n%xN{ z$d*vU5&j2`zzHG2pTK{^1r8j`_q}y&T104tlQ;WjcIM5z?|tvhI)5~mf7$+|6Uyx8 z;Q1z`_zq1Z(nV_|s>skt7fPvDq+2=B9qGENJ2G@+RF!U3MxJy%F_9}@!9-1>szhfc z^4L8V`KY@jQB7hagSzx#a%ujeE)o7$BwC&iElYGpqE(3+^C9$`>~tGETBp6n6SvTG zY|kczO~RtpOMAnkFXFt_&+^uLneFUnb~AZ^-&VVVskVyd+ScuBzICbHegAf7piub! zDx_FNV?`!7HV$ie_)eQMW;V`1<(|dOtQW<(S{g#tId%ze`^hj)d!x7wU9>6AL)+ZB zne6W1NCjl4poz`#kx%$(v)~ED_y8da*2pLbO{yl(#m>r8u zjaWEpB&Y}uHgIK7RsTGObE>FK9r^qxnN;MRkAIM5@$AG65}( z9JrDn$OPcj$W+$DUITHv1jEz99@yYD))kCW#qRITamqQe*5{`KY#u4 ziY5t8Dsn5&$V%IQ9_;4XL7duT1ojfwz1Rlq>C72FHK+)f2K8pP=f@XSp(L ztZAa`(VS~D?EW%W(Dc}68PJ(vVt6>xnek`vPN{cqzh`~-WXdo}<1{N%^e_#XqUF*k z9wHm*TS;9gkC(Sh>*6A(JEZ10(;~PA`cI=MI)7e?yEh7Wrx9Yfu|XnX5Yaa%$u*Dd9-Itv0|lBNs?fk2wql zK5>a7ARvjZvj^a+OU@WPI+~|jS|r%D{cD)PRJ79rir(pXu* zSJ#>H3TAISj?<{EMA0~LZZF>}G$2|!II@ev;kTeXRz2{^uU8>jNX2!`8h~z?HNd`F z@yv=@HM-@ja4@t%V7Y$~jI!u(h^|laYq?c(i;Yz~twghwt#Ef@f6oi_<{7+a2!yVcyVVNT`_mXLcn;wPkKJIdI zgs--WXF0x~6fM2hTKL2|97Ziv`_^vU;#CySKG3uX9O~_-)otPDf5wb=)DA=sC+3lr zZ9N(}7z9xkqWn-Fmlv=96m;eA?0((E-RkqpMsL&do@6-n^G}mbGfjEnbK^&LJ0&Pu g1230V?+U9;v4O_pO;l-A&O3E?{q+mg_1e1k7l*1R6#xJL literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/hotshot/stones.pyc b/PythonHome/Lib/hotshot/stones.pyc new file mode 100644 index 0000000000000000000000000000000000000000..5d73a6914f9d369891ae2e9856dabbc1e81bd32c GIT binary patch literal 1126 zcmah{U2fAr5T3P@rb!dpMioB-2}`I_5F%Uv5E3d-scNI7Qc)Dixbdd3V|(45ZKX)* z3*`uX;3V9DK5!il05fYFc*F5dW@o?o`M$OLv(x%^@@X`M@^R_^4K4giCZtzD0xAsFm|hW4aRi{9r!|tYakmCy0CCS-+*)>UWc#-kF^F#XVw0}wE%H`Q&nif zxM|Ou5VznOAl?8*WOkrYuTH~7zvwxf3Ub$Iap)~A{6WT0hJY1t(iJ%ZVh0R0t3h1n z;KYF|dR=?8#vKGPEfI~%S%;MaGZ*f@|3GwB*5T52s7B}KI!^<=Krb+a@baPx zzCbxuS!il37gaMX;50}QjCRQDZF9UqX08mx+!xMFEKgpsa4zDY5EQ zR8AC1vq53szmysymHECsIXF5RjI4(yFlg%~DhN%Bz-V-o`(dQ9*eY%O0>-6s9c9&? zN8LZ#)0!YmMQWWX>+KEp2YXgWJ9nbaEC>E@a?>PhHL@D8*j8j5a(%-X*&_qi;63vC zlY{7VQmQg3(EWUA=T3tt<3aEd=ZH=5P_!JEY}4tAme>-m*rsS#Sb=<>@xC8%n_ipD zkX0W#WK4%l*`!}Eb}52%dki!rI5oB1hfH^PpQ9|h?`J_ONnF0!K%ZUOsF7)IX?H1l wNPzH|B1#8(`HpXt!JPM(?Ee{ax0k63FB18hDIkA1ZBhQ5X16UmV#jHV-#_Z^>i_@% literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/htmlentitydefs.pyc b/PythonHome/Lib/htmlentitydefs.pyc new file mode 100644 index 0000000000000000000000000000000000000000..5805462935e68aa30526bd214e04b8ff2e329a35 GIT binary patch literal 6362 zcmeH~ho2SI701unrQ2eOEovSR5j8Oih*1dv2t;Ox*f#mCnZ$vDUl6kdvx!L1 zP805kM{q82p5T1q0>OpEMS_coO9Yn^ zmkBN>t`J;FEEQZuTrIeUxK?l-alPOM;zq$u#La?Rh+74>5w{EOAeIT16L$*kBJLL4 zL){&4|qvTM*w>6o`R}LBwFi_lPYOLx`;uLy4^w+Ys9-zEAu>u^sV4 z#rDJwiebcX#Ry_Y#Ykc&#gB-c6}u3-Dn=1MR*WWoqS%cXqu8Aos~AVLDSk@qp%_n0 zQ2dP8Q?VDZw_+kONimt&M=^z%s+dMhSNxpVSFs5Z#J}#4i=UB7Uv-4e?vW z?}*gtayZYRPh+`xZ(-oNySsd(~4(^XBE#8&nsRaUR1n9ysUVI zcvbNl@w(y-;!VX{#M_E@h<6q55$`KLAU;%lM0~9Hg!okP8S%N|3mrK_#dzMegukt_ zU>}K9=Jb+9BI6DmD>GYUMsJzXN8;WRw@BPaM)AXh2dN~Z`^J6!(jt|()jdYd?cWz) zDlcug>cYMU^p*n{^Oa5=`nB?m9ms=r{ItFIDiph-Bq}!Iq!3pc*61!IaYvlQm111q z&X&`w(VKt9w3V#WZgttmWmIf7V!JIj7cD8;ExEZfiRQ(2L~9mZs&z%SEcZ^V(rLHn z-VG}uwmV$=JHVJ`xnzqy*46HDBeFX)-?7CQRVRT31{Ys+`nFm>Rt9|uG2~$bL}ln@|Mo_aDHSmZ{TSz zyn)GP!wdZGRZLE-9NW3MU)}8VOibyj+HCK}JDpmLeEc)r=z&wMlhgkkzXdsM{G=%p z?W`G;>FB2N_}5)?fpcdiYr%1-+8a)GWL!6f=eGL zN^9J4Ahp*RmEw+iciAq>T8_e29OC}GBvH9$TMf!Y1y)!kI_*_=3pIotJKk+UGG)zP zc54_ky~D4#_I@JoZi_;Xb35iXt9E(TY`Zsmb{5*6%xjMl8|2O&+TJXcZ0oFsVpOx& zGuL9e^{;X5MWpf!mmXR4$Jd=c3O`chvRdAfnf&2YWY1|_so7q)HXkFzRrxGBFV9k~ zb=y*(y)Z-)C5dg5m(#4-S?=jg7n=#6lJ>CsdLE3SYoX9%MfxZ@GPio7OFh=BL)>Xs zdZ|7L!c(dvD-RZx>-M?3`Y^D0#)spZnU2%d@s?|kj>GDBBR8k_zqgkh%;j36+gb~h zUSwRZ*Q_O16{@9PhcA`5XE{fC?A#^?zuN8mh~Kvl$R5#UZ@UOt{eE9q$W>Cc);!4q zt2b=1_82=V)eaLkdUGAsB;x(P(GvyDlW2!wcEf+^5q8t+diV$%SD?Rl*O5f^l3n2y zy6g-O-q^FZxQuNyk$!L3BiX&^@;h}@uKdo#KKoulR~#jcx(zAhn)TJ}UC-loOQ-)m z*FL0$=|4S}@q%K>-f*j}^Sj5sTU)n;WZiSjDz==@V>Rz}I>&KBwl#z|DE0 zxy_i<*w0;qwa&oz-5Qk7|8?0c925?ThqC@k-tF~n^omO9k+JpQp3qXn)qjB}^7=}V zZ`H%|P@kH9?i!56m?!UMg-nKR&7aEY1eanP;GSWSj#9On*hX#(x;j5%_4jN^%|fJ9 zU1)22o*YxU5<*0ZIC&Z;b+cLH+rq%OtPz8 zdfKu9)rPI-1*PUnvu-zV_>i{Tw7!|C61A5iJIy0~luA3d$ohqzxJnphcGhzxwl(ta zW*2&pw^ZR+{quwr6+6UbNLX*S+lTJyh4GI2tIv&DC6%UqoY|`BQv1ZU7hMfYZK`H6 zJorD#z0;*Ox{#Sm#`5m=#348w+BduOyNana(!?6KUyC)Q=2-$(bJ%6v0$?UPWeHhIDgD`YafVXTvnkW^ut zucm5tSDuz{AGD+s!X??TmDwgqe1C1~VLn6>fscf32KTrozP+yZz|`ogd2t@;+pE93 z24mP>n`gx(VS8F3cv!KDxK`x}87}2&m>U}d=#~C>1>bfX{V9z< zX!$AE!#KgqFXw@w=weqglow^ypE`S&vAfKi+}-G^R)*~~vt;cvyBg)vs`T5{y2A<> sRj#60ibpFW>H|1GeOgv=$g8I%X%&U0l9py82|tP literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/htmllib.pyc b/PythonHome/Lib/htmllib.pyc new file mode 100644 index 0000000000000000000000000000000000000000..882aff5c1d0ffb2b0f1482745662dbe1075c21a3 GIT binary patch literal 18944 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 A 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 literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/idlelib/AutoComplete.pyc b/PythonHome/Lib/idlelib/AutoComplete.pyc new file mode 100644 index 0000000000000000000000000000000000000000..036fd01f1f8cd902557b575440404c444e6b7b70 GIT binary patch literal 7818 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 literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/idlelib/AutoExpand.pyc b/PythonHome/Lib/idlelib/AutoExpand.pyc new file mode 100644 index 0000000000000000000000000000000000000000..071649913d76f85678ba0a506eec84bbc4025e54 GIT binary patch literal 3412 zcmb7G&2Ah;5U!s6v3GHPAaR@!p$t+23n(jsI3X)Qf)7Y2LgPpg#$hy`>Gh7ip0THU zy|!fMVk9nHcmeJ_1s9$rFTex9_tmVuj$}b%d3&m>yQ-_JzpuI*e_!hM{`_q>j<)MO%SXpLlnjEt;7sO3P`0?8VZbtG%b&mt!xKdd#xHYIDxb|6)JI<+NhEwL@x zYDO&V( z*GV_a2Ln3`LA4CbB|A3Ut?VE_=!Z|Kut|j#5n;HK_;d(g8+J1=vPeop;@2;BBQ7kQQ!#<|ivBMgMGmW&OA+=v`-* zRgOTCQJqB?b-7-8n2r#(x(<`gBrlM)$HSz++|AQfbm!h4_;8dLmI)l$WdGa*hJn;4 z;aQ@(n#t3{s_fp_I)7?W(ADff(q!zAg|ElHTshd~b`Wx9o%P+^I|k=1qIx>aalj7y z4PkE!$HN@t2wzQxI3Ny}#pn%gsV(l;>b z79gy|^`@Tz-R=q$%ga_Z_X)v=550jdPC*Je{XK^4ZlO6cvV|7oh_MzxMFEp&^rXk# z=xRJY6`mk9zD0YcwMUPt$8ik&9D0mvk{3OQqK&%^slWbRzOkNXBRj%(mbd=yp`XWi z9Op&u<2Z!uxIHloMq_54snD38A}mCUn76cioESL{PBn;J>&QtU#|>3B#I2~%WKB6n zJ!#5uONvL+(RFlHbKI8WIXP;}Q6Sr}s^kdW2IcCPi##BVrnujA2*I@I-{9m{8C_df zn?D`Ik+uc9JYubq8>o7S(7^tvCAW?{{NRL_I0JEF212B+skP6T>4xhyQ0b<9;KImJ zr*`(5Ingz-M{I2X8F@$9Mbtf>fqQ@^s%zLQ)SZLls?ru&4vi>?HY%HJySHaE?uYlXFdZh9%ZWfO=#iq3n9GX{IAj+EFrr4mgAPM< z3d9XN8u_>CDJZS`9MKpvRB&(AdSr`;M5^6$0~(Fp$1UMGfYMlRNg<6M3zyE(g(CV_ z54xld5~I2nNl@4c9bJKsG2Opd{Y zIYw1;rus|v{t!aHO?K5vgAZ9cFUuHwM&s6n#>VWu{4e8|@@(oC%rszT8-(B~x-Zd0 zdJTpN5bZqg0!0A$k@)(KR;tvO`00J6H>2LJeMhuD=zn^i8|p!?OqS2}4M!xePd zR}|HkgEI*_MKiO=-(&pTb2QT;sJ8&hKCxz)4x*HLGR!R8prN^Oq#wn`uxTo@5eryIKexyuC$taFlD23 zxj)QFraB;UNO=**S((Oh^f43>-!U3N^dZN&oiQFQbgJ~=(r>sSb+TON_93~iht$Tg LEwrzFkJkJP5J?5o literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/idlelib/Bindings.pyc b/PythonHome/Lib/idlelib/Bindings.pyc new file mode 100644 index 0000000000000000000000000000000000000000..e72606cf5106375709099ddc8edfdb4c9ad7c1a2 GIT binary patch literal 4565 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 literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/idlelib/ClassBrowser.pyc b/PythonHome/Lib/idlelib/ClassBrowser.pyc new file mode 100644 index 0000000000000000000000000000000000000000..be5ef0b6391e1700c7b10a78b042a38ae1a97222 GIT binary patch literal 9054 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 literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/idlelib/CodeContext.pyc b/PythonHome/Lib/idlelib/CodeContext.pyc new file mode 100644 index 0000000000000000000000000000000000000000..75782dba9db07794ff67aa517dd791bbf066d5c9 GIT binary patch literal 6522 zcmb7I&vP6{6@IfTt+Z>&l7C2+@^gY?vJUd%D##DOagoS!P({eDksK$BlV!BiyBcYB zXFWZ#q$-;OPEiE~2QE2r=0X(*ilX=j;F3H4036`V9{}I?dUjU^ii%X4-k$E)ue)D= z@9X!b{Lk6iAMXEft1ZRf41T|h$9{n#5^19JBq~YbNfQi8ClB)D-(mdn(CMB7X-mEld#WQCmsz@{?5oD_p)g(G2 z(Tqg15}|8OqIv0_k*8Py>gS|6FVT5vo)a@Id*>y(z^>?`db`!<9e;D_p^srXD({CHdM8@9@t#8{|nj|Lj(@sZa^K^i^9~SZ}K8Ci#zQ1EI zRi_iT50V`7)*_RetQYr5Y) z?U;;a;`GHl*z3q9k-y_k1d_Un+M_Uw!<~ed(KVbrQES>cPZRpE%ud|BHZq!RM5fd5 zH%{y%N^AWz_qlwxD3}w5V4K}d5BtLzhA>bIsl6MuTKq5kZPq6Nth|h3`_A2b0>2w; zx3_Z-m5;Q%pI1=dy0`hk+Gd^2`rZqVuwC~)jm9`ih{{e*b?qdyR&`>+IR-yvYnp!R9~fqngI z{lVeuSKAyrd{$An7f?L*WDg}A3KfrTwWTZHtW#7c=!JQER~OdJ(u09@J>0HUE41sV ziWc?-)EW;q;++TFb%Ng$C)gMq=QPNTB<$@(;Z5~hj?KB$6M}6v@{iK*;jw>0VL(}6 z1F+VTbUo>mST;*y%Ca{>?ut-OK0`Q9%O%j)GXkI>FcMe@j5H$@s5~nGY8nZgRRPe~ z965)Cw@k_+9YN1IZGSO?0 z2u6y53pe{tx1A;c6dOPjc@@7Kad$U=KMRi?^a=^0_Pr!*?<;^P&r?~&WB-f-00Mei z4oR-ACBTH6Vwrs<9vUk+AJp}rfUM3050LG!_oP;)xR*U#6#sQ;KptoHq$H0^l6_9$ zy&BQ#v4(%WR&pF@NxZ(!h6U`+N`6*l=d^>eu615p&uJ?bw^g6TRyNgk9hf@CnPMRjci+KBg$5%g3agHZ>-fs-ePId zQ^3+Fi+B{UKgU5jz}Qtq4$uHdIariQDL@!t`=l&K-zU^=eX=G`CggFMOUDsBo{+r? zaR(qTgEH~|7KESa2VIodG46iYko(j+DM#0w)+?%Y@`P55DxVxRDGxuB`_3JT1%h&v z;rI%?S7hlTLMwnCT$Y1ws=5=;+6zlzeKO(o7l+b|G=x|9HV$`5_CSwAGNiRsD+Kndy0r=M zDD>QL+*W-7C$p*ErqCFK(UGEZ2cd?^0^-8b`D!ss?F#$tT@V+2Xz#%0apyR=%s$>% zJ6-+hbk$o9<0y9*SB9&oxNa@tBb}=gCy6RFM~Jc_H?6@XYsQ}L5K0#hzQ#gP%SAcY zgSWOiS=ckd3+#QF9VF5L*b*>>htgHsUE@f2dmsJ|$0DO{s85$U0v7?AqtL}UcAzqt5UaPrx7kG@*ARRM)l+zGa2@h*;jyg1V=GIgiZ|=|-evv0 z?49?{!HcW-t>Aa2{E|0cn#KE^SNJhk!@aNKvA;x7Kvu6ATtbUPH-2ydz=r_?crQHg z0ba}MZ1CT*>{lecNiT*k!ir9Y74^OSlGv1uqn2fO3tF=y8szbh>n_t!B~gkH zU1QgrvY{IZb%@i8$lT4~Bfi#KqA}954H>tHa2P+E-XK3N0`fXy_;%W3#^GA7Qpft{ z?e)#|?T--*57%S4zbjGWx+M@$G4L8f^suDL+%;!WGAq{rM1q0v$wNvtBTAqN`r--qAk?alDq2{s1 zNI-M;BW3dvuAxa`;8T_CkBUpI0RvFSV1Rg1>$tuEcFcsvX$m6NqB|@1BB5m!P!`3)JQP=|ppg|;x z;K;)e3FQfdZ9x`^C^9ySngSo-WW8`A05fC$Yodl97-Y76KlJkhB+NxtNcS26HVX4l z=cJbu8WM0@aw4PVICf{I%iJ>V+X2!{=pW-=&)S_j)53r!9+2iW5jyco7--b=t_8Q! z*VeKu&4Q2F&d#GO>~~Fo`?k2s1^{fNtes(9nKgA)u0+i6>skA$lMF4RH_+HL%G9`oe#v_Q z^)m>++T;bIWaJvZLJQo15Z9m!J_6tY?k-q@A26PJ;&KNd4e$l;zRi$li-TMf5d90) z0k955!T1l9^cl7NPJ1<>SVqXRTtNS)G}MzeHLp^C3SPx@F~b)Z|X3nXyFNQJS<;rARG$wjdlYur)r4Hn;I@dgV0@T2$cDYmO4e~r-^ z6)+i_b?fG_j@He))U6wSzg&1Zu9|m;Zd{W6^7s{>3@GhNjqq+1TSV*s+9D_0)I4Au zi@42RMUUI(o2)Sib-b-4OVER4hk5sD_DxN{!DC6;f?YHHyx^(wQ-0LhtTQNAdT+J* z$R}DYW${+4mqrH(U#B5}5bXdTa;!%6!Pn8^U_MR`zQs0TOapGcXq=nqk@Jk50Z=*3 zC7@qDm}_f_UO^}{<1LJy>cY&c)%m&StA2IT8IW0>-fFE@l(t)~V4V%L_4Yp83lRdo zM!VdF=ynMVvEs5D9%kmgU)f_DFkNzYDD@WK6&uilPr%;;BPB=_32yf-%jCg*4p3C{ y$aNtIa0f_qf)Cks3B~xNwf5z{J=}1|ag#f-izt|@)bY$CTUmlhDqf|$Q2IBv(QhFD literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/idlelib/ColorDelegator.pyc b/PythonHome/Lib/idlelib/ColorDelegator.pyc new file mode 100644 index 0000000000000000000000000000000000000000..f9e34154d1f7801740b28e2c5636e7d81480eed5 GIT binary patch literal 9036 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 L{@)8zMfCn37ALmq literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/idlelib/Debugger.pyc b/PythonHome/Lib/idlelib/Debugger.pyc new file mode 100644 index 0000000000000000000000000000000000000000..453e1e052a259a1d9694bdbd72fd503ae7617d7c GIT binary patch literal 16270 zcmd5@TWlQHc|NndTyiN=7gC~3NscJnlvj$Q#CC!-jcO;l*hr($@lXvNLhg2VXGku& z+*!^HDKZt)CUR0V4$wX{4f0Z>NgMQvUXUga4GN?v(1%{o)J=gR=oLtdJf%hZQlM@6 zecwN`yOd>{w)#+sb9nBT|NQs!v-t1hqhDS4vH7OU{uS~2efW~EAqnu~xwdnQy}aiZ zy}Z8Q77NN3T)XJ5vv<+8OKyG0Ee<)4<&tZc-TJUw9Jcb1Ymd0~id(FpTy~-7R!7|u zW*l}eICtB*k1if?!H8SJ*h;Tz%mt$^99G8zz1ndXjH%;zuj(N8J6}DBy|=!Pe{)q2 z*_6q7%d+WOD@nuPdem))TVdPk$521tjH7lt4A^e9Rj2#G>q%bv=w!#+@)XPoSaw#(qZJXLHmV6$|*LJFs`** zo$xRU$tV)%9r8xK64E9YB8>PEBFR%o_74_aa0V9Sas35%yZ8#o_*~T|czoW9&g>Ic zg$+8WPej*kw>nFae~69v_H)}Qhw7B!b`y{W0FR^Q&Z82YcwGM0QLiC`Edv8qkqZ5Z z2h&8)c{Y@E@4(|;51bA?-pgwdew1}!kT4NOw>FoQF)dI4XqfQC187<06{c)oG6Z3J zGpa4M+F=Jcq04SYo1IjExE^nYS?@-@xu({q>g^;HIQuwapd*O8akypZwO`n2s<&Wh z!i#a>H^^LW<&{~F4pt}wl0?V3gt$MO{NQXNhWKPcsz!NcHmRNyEPWD{ ze-w#mZAoa}iBev1ln993db*;v&!PSV6Sj(?`q!=8 z>u^UxmqSG%%laaV$rC@q%oL3ZL!k5jI` z0AV|vOOX*(LXe=ck_(biRYI1a5^{4$LIu*YtPBLC#Ofl%;)rSvWm0wVFeT~>SpA3# zBvBV9IMw1LWh(2BxA zRGIr-a7>xExL`_|)0BMo0R&>1q=_CM`49>q2LNDg#Kk8mzQI9FY7n7KD2ilIUxRo> zB{C2tU@Su>aI6y`Nk+n{=UPadp+t%0s1y3kNDzRztc2~h1ZOK~82S=(*6V9wjiS|r zQ6^G4%LD9!DB_<((#M+DK^RW_ZhQ$jt@Fl!t%kXyUXuz1_e)}Z8eeh&$;SXdJCTlR z{1t%sEKaw8BZ3DI0?s|B^AenMEzV?zX4!u$6K+$7j5j+1i%CVop&l?L+MeB&>iO7X&hQY#T$2HrSXDpnwY@vGQQ+nxCS25xm{c~j%rtK z`GPAEED#L^-XIkN&#E9+QN}n)3*ZSFysRwopfcbKUSb^qLa19=7cdi}9IFM3G=Zb# z4p0)Y;{mq{z5*Fk2KYU187dB{YvXQrh#-Ve0r)dK`9?R6}m{2t^UM z((exTW!)!w-6vn8J2;$mKicbl>@~V$zt(-K*ZufwbO*Pz?)SY$_w5Tj%a!NPY9gQ} z7$CSSjtijRd;}7B>k*YVzU(a!oFz*L7J!W(uxs1%3^}dMa@#8+Q#+&L8MpcXc`vvwWeOnS3cC0QUGm9S zto9&ju0K1tyv_blKKp~%f@Yu9?6Z4k#|E?6&${GaUorbxjXC>jX8|N_wTJW7&gQFC zHL{woCQ&tTmUAwdE8YpYb9>JM`DC-7&u2fE&;C};{?@&-+gZ{_cpVwqvs{&nad!MUP53 z_%Zc+?A812ne}n?e*A8|xntnkJF$d|zd-U`<#Iwg7I1gg_Iql3c(CnU-u6wkozL4O zkj{X;%_X!@qz}zpjyhnjZSiB(q~wqbAF5rsdhP1%w2hALBi$Y)udVPhEGUy zuXma&u)-sN;dUzZ^yx@kyBV#o*E@mQ=4mEUvOTi})?Z|1(=35!A#0 zwWtY0LpyxB9W|Ke^iYZ0I?Oii(>Yot%Q5VgK;u`!*78cKY`ERcPt}Ohl`5SLCcP+> zmfCPwXu>#(QlHTAsWoV;H`i-vE5%kR3sGn_qmGQDtlW*GG{UZZ3M)<0Xki1K_bD3I zTEAf?Gxyvj42F?u0GLrHQTrw3H5$_!Y#Yi^*{^rIVRk1n-8pwdIZoK&6{<=(-cuaf zaTbQ6vR9*)ytd(3iw%W*5vfwvO7P$?DaZe;-@Yh!+^ZMWU)mzC8o%TwlW zEoZ1eQ&H>Z6>M$f1%l>U9qNoWhJB@*iQpB+F=&BXY%b$eoL*IpW%XRLBd~gDVAZ93 zUP1%os$9%m236*KCd3~9IV7U3h9POgUq%f(?Z=DYpGUvz_>xa@1k|1}m}Qgrm`)WY zk&YK0@W#D6zQQ`2XcIuiidNSzHPe25$HivZWptRX**K> z2)KcAKL^nXQgFOpfQ00ZV{RJ zD(P;{e-E#ihSY2#7m_(TL>W6U4WgSV+MG{gQykuZA98B$MDcpP?Y|%8>J$%4^Su-{xzl=}g%J@7v)=e0yn_ZEw`2Kpm)oDjjw@REh`lj#14s!%K zagKDSYi_cwdK=y`!Ygg)*ZQMI`^);3Y>DLi`L~hon;CEuFX2nBAR#lDER;c* zMUdyXcNDCl=$*hf>{U=-M*B2~zYM~kER2(g3uFoC%ikdMQ)VZZFc+aNa&99-l*p~8 z1j=z{WEx3(!hR5dtS8X<4805mclvlxlnZTz?5^jO1{K6Bni0kehzy*fn3D=8Hm90d z*?emdvR!<_d|&!Y36;LE&{1Z@fY@w|B@$q{+;0^=+)v^@bvxmfP-N&*JpZ*VW>?+=83 z-*4!jL{TpqeJ`{>!!B=l(?a??q4qMS%6tyyF=-MR^G^q$PtouITfdD)7Id#H=;qkp zUQUcKC4fPg)L2@b&CrBkh+c9r=qUS!^$iUB8+_SY$+)5FJ#NvQ{gTaZa$Dez?r-n9 zt=`o?gytUP3~IS381&BMH&3)N_>FL0z>f-?F_?SVX&tluBWEljaiI3z9pC#-$#l6> zD3F_R=ic|)#C+f3oUhm`FZ|8oV-8QMz4wHR#Fg*%x0m4}_sUP(`+a2W(#PUWtH|RuN^TwFvS=&2_-pDkO!>^-a=K=^hH+cW2t}jEKsUbTI+xTn=hgAA zshF=khH{{7Q8Pm=bQE9$RU@!+Z3uk(BD!RcL?*%KaFi-(*<|htbDuyWg@2w3{YT^m z^gqrPvRXp`3TOYPnLNzoGfZd=4e;HcW8LSN{5%`*?Mnw}Otu$QUF97?dnJhgr`n_zG%N6ly zn*;@S*2B#lpW^p$`$?mZ&o~M&)DE-JaGi7Pz&A9_kYOENosbyn2O0>9?jlf-E0{xC z_*cTBbN&aA4j>^3SYq4^FY`Y832F@?sfo?OxK3bAhZ$1-1Y3oG#6ABG@bRGSt^LBy zr*bcSm zwY-05-Na;*uMVvink_tl;MC^U-Ms(VwY;UyMQH`D?zK7n(v8bN2`M;v945DJkmGYY5xsa z7Q<2mADI73=;?o%3D;6XoAW5Q%-p^)n{;uScXa}p{KdBn%YgdeefY{?vSo|JAa?gK zoG}b`U3^!;4_NBnpcC<~bLb|&5!D1Zpz3P_Pkm?5_=YrZg{kyr>P7%pZ6%DuxAO#C z&)wrr4`7NW++Fei!CsH;ovXjw#|C!GP3ND;fTC>>u2dNZaIFv2{`B>BTR|GO=cF$s zWF_nu71ATU{nAp(CVSVwUXhi%hlr}ZZVv9XXB6PIZTq7{i7U@Pn_E3bphdS+b#z#W z{^ag3T?nr@GK7dh8}D@s3md243L23ss4Z8{DTk`(@GU^r*b{W}Ls@$m?%);NMO{(NhWK zwQwhq(cX##PpLlxv-`izIerRB-%v|=i`gT14O6AHo7$E6tXYBbo3!D?H3ruI0p8GI ztmojW8<*{W7?eBi%~fYm=|99|mWlZL3UktOBtInwMp*X<6UoZ+%*oF|9mxMYlN(GR z$emwj(quw)*mOfGWk!i36lA3c?Oou~e@81Xp1 zzmEJY~rEZQvkjkuuj7p&Ha(vQ z=wICH+!?37N+hK%f$)sdWP#c`q8_;yO0XV7c^utL+)`)E0po4|H^D&b31HFBmFK^k zMRx%J(>GujNfFq=tGJW`Kx!IZ-i6LMxd(uTg51Z(h`?_k^UL!8A_GUTVt@k3qzBwm5n*NH4tGeW zGJY_lHI&rAt3$9EG!nR6v7>Q!oZao<@QaUgesANfTR=A~PN(&uf zfw~S@SsB$NCl_L3bIS zMJEH@;Uz$Pr|hgA6PO1sX9ACajUb)ygci;)VsHiziYrl&*{+0-s97Sa8+A9kHH)wj ziA&bK6MgngxqphzZJv_waX3R01*t1N4)!D}NT|8%0j$ip6bOd(G_>)Sf+Jaj>^?TY z`OBvUM5_B7CYyv(9i`{4U?jM*>vg#CPzu5tMd!jV#daAbhf;}y?hTzb>eP&CcluZ}+sAjpQTWcALfEOoX3_&B>_6fp!*|h%` znBbE=Xo92kcFRi^G=BscgXZ9F>1fIE=rPJqb^+CSu7^j@s!k%&8VB)+=i?G{{nzr+G{=1BYW~XhW{vJLu1#@cQJDoRd)Gi9||L56p84 zyF;o1l?1#wBi2rbH)jAK6Tc{knD13D%6uw@WJf)s(ICJDKyTwk%ITno0tOvYx8H|J zUlyKXL+@>>mC(L2gM-W|LO6#sGBP8|q`u8>V3q`YfOE_+IfFzJi+03*$x}G^A^~hJ ztXaHRF&2O^0TVFr=gial5EqzbGQ#9xCZAzKQQ-e2lb4zN6%(SSF3u1frG0Y?so|IN z?NCJ@J6Rcm3O^(Ten?)aCTHY7BEThl$zw=DQ_~d(@B*}RC}z2i&WCI$==eh_WCs2u zh&a_GsA=C(3|_{U{0^4KP-u?S522aC?K8^>$a8hiM>D69NWX^Ev~Fl)7z5D=6cT#C z3w2v0$mnTIBtnBu-p`k*pBU$mzaLsA%IJqTc&MJx+F?m#Fa8A&ItoJ(! z*kNU091bUK7YZ+f8zrwnD5zXw$fd=f9?2pixHhIlOrv&fC%Em39wQ+pxM(o#E^_Tj zD!#!9caac)k1dPcJSsgKoe`H|ssVyCVKX7f9btTh0*+Xl(m{{sR0ojHSNR@k&hZv; zzeT-4`flqYa{ekN z3hZKLt5J`AVxZ~03MAtqJN_Kf)+5NvKb`1L-r{f>f8^s6$)ueqx?#uKa^-`|nNPrf zH?ndtbZ#ny-&n{Wu$FAq!p*pgIP6-0lFtnBc)h-zDbXZXln~7Z8*Kpv(~LjL+zyjJ zL!vSEXL&r(-?NGvxm@pT!MY=vt;1KM-}P-ZHLZyo*`e#$hww1_5&jg57o(@33C~^{ zW?l}#4ooiae-%v%ATb4=XY&7<6Yx0le14r(1fu^hOvLKAFaLW?{td~#IUGUo1>A(V zgac3Gf8%kcg^!^$?VV9d3-mq&KAeJ1K8~6*o*@zDFjhhBkTdcYlmEoDpk9)l{TT(q z?+b1WQTPFHlGWlP%!rlH$0ZSCoZ-sz7Pbu$!sr_qbr<2sGLE5%lh24hfUAHMXxe#X z4-!M*N8~nQXe8Xux49FLALhxZn}I%X62bzmxb3f#_O3kt6_FRVJPJd&$1spFs};-w z-0nM!H8RpY1G~0^i@~zm1;*X63sSLmk@KmdN1lV;pjxEhQ(_a@&cU$2JH}`}d%crn zbAa86Yh?TaJ2;N5Z~P`KT>-fUpa6VecsLhxWN{A0G4qO>+6DUpu)&SMzOXo!LhC_t zDys+2yofUR=32?c-}aEXg{}uti}(|8E)@76<#`?4C1$&`kt`ja1F{^Vf<-`?Kzs^i zNqqll=Ew+yJR+DRZ8g_+{O_RB|2mUzGx;a>A)7EwAw)o zoq(jNK%&HdoINCsMa&V4Uqxc1hPXwMkNCw^!~*YVY^#I6txRRoY<2_EC;u2VttV@V zSQ7ZpQiQkr4RJ&W0KbF uCNDAJ&idD_+-rLir6^ytzc_q?myk>$;Vtq884Y{5IDKyN`|ilp_5TIpQ#vjH literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/idlelib/Delegator.pyc b/PythonHome/Lib/idlelib/Delegator.pyc new file mode 100644 index 0000000000000000000000000000000000000000..29e79587f08ddbc047f40065f5a7f17eb7f44216 GIT binary patch literal 1178 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
    @(=lj{6SvwmYk}dFFItpl=o;Jk^PI1_o?hr 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 XYqPt5(WOUqDm{1+_0tTxsoc2|=s1cO0+17i(v% zq>}yQh{6M}{04py|AZd^-#KH`_AS`nvvcOmoXdAEuKnF<|M}OO-jLRx8s6XFG2ekC z_$kVW`iVzc(MVBJqZ^_X(U0dIC3R-bYozOxG-&Ek70M-_vIgZoo%^J;Pr61cMXG?h zCiQ|Xs80XECs0^fCXehL(6f1F)1Hm(+?>SKdp?~&Y#xGW7!)_)+>K)6aFOkMbmP%^ zgTh`=$GM>g!qG7E0+0CuWPz(h(=DnF*)ZZ*DuQ3uqe+bxa$w=n?;fcX3{eEl1fSW- zZqNX=tgu@a8h3!q)bi%@D$cd#z@jKEQX56q2b0AEotc2$kZVR~BN61WvAPls)2jet z5@J5V>iFU`9bBYIrZc?X$K-hSI%IqN7&b?02j6?j@_NXwv4|z#;xPz~V@4nogx#d- zjKc;C(0~}S2_KL~%NeRI>$IrTM3T9{4k-oRU51vYMdvN^;reic5}yDW9~PvVFxi#J z21zOjW+W;Eqh0KAF&vkb!y`?!EUdn^0iO$*2&AWsoq*MQ)qU}-D|Pa{oSwzQsYr%p zF-k8bEg{<#X@OLPyR3_AN_0sc{vXV?h08|UNbYVkvjakESADGZ)SlN-UGaFGb+(GE zw{awj@-mrcU_&kuNtk$c`s{f>JiyjlS7ddov@?`kNQRT_dprJ+ci0|7CXxr(K_RT9 zs(}}>fW*S|1X*%b;Injvbm6DyqE1VXmNh~$mkq9ziO+SxS;v(c9gIBM=iX&elPiT8 zgbW_5rBA?V0i{?sY0;!fn++(tz25ze=vNfq4$lV^3e2iC4{clj@oh?4WIL3!36o$& zo_a$vZno(cM6*S9S9%wEaOe&#a8-Fr*lw{&cUkJy-?#v;CVS!x`|eg!pj;YVLGh>S z$3GiJ@A2mee(4`rnh!ww+SsF0<_j3{%MANOa=j$;*EK<(ahq4{l>_ zZCQxEJWh+OEN21tfe2@DrD2`5R%K~jZqme#MLO2$<=Bd@YoX4Q5sz;-Gahaf4aAC| z>EQkplG}8u-NV7?o$85@F|I1Z8c4O&6Lnv8WN^1ZF-+9Hw_88NyN&O9pm1nW1tkd0~vBm`cq)6D?!iU^(A)0LlDaoX8reZ%=H7F=280KOOPusT*rw Rb9xK|-uCwIwhlOge*txIhQa^< literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/idlelib/NEWS.txt b/PythonHome/Lib/idlelib/NEWS.txt new file mode 100644 index 0000000000..07ab083711 --- /dev/null +++ b/PythonHome/Lib/idlelib/NEWS.txt @@ -0,0 +1,780 @@ +What's New in IDLE 2.7.5? +========================= + +- Issue #17390: Display Python version on Idle title bar. + Initial patch by Edmond Burnett. + + +What's New in IDLE 2.7.4? +========================= + +- Issue #15318: Prevent writing to sys.stdin. + +- Issue #13532, #15319: Check that arguments to sys.stdout.write are strings. + +- Issue # 12510: Attempt to get certain tool tips no longer crashes IDLE. + +- Issue10365: File open dialog now works instead of crashing even when + parent window is closed while dialog is open. + +- Issue 14876: use user-selected font for highlight configuration. + +- Issue #14018: Update checks for unstable system Tcl/Tk versions on OS X + to include versions shipped with OS X 10.7 and 10.8 in addition to 10.6. + +- Issue #15853: Prevent IDLE crash on OS X when opening Preferences menu + with certain versions of Tk 8.5. Initial patch by Kevin Walzer. + + +What's New in IDLE 2.7.3? +========================= + +- Issue #14409: IDLE now properly executes commands in the Shell window + when it cannot read the normal config files on startup and + has to use the built-in default key bindings. + There was previously a bug in one of the defaults. + +- Issue #3573: IDLE hangs when passing invalid command line args + (directory(ies) instead of file(s)). + + +What's New in IDLE 2.7.2? +========================= + +*Release date: 29-May-2011* + +- Issue #6378: Further adjust idle.bat to start associated Python + +- Issue #11896: Save on Close failed despite selecting "Yes" in dialog. + +- toggle failing on Tk 8.5, causing IDLE exits and strange selection + behavior. Issue 4676. Improve selection extension behaviour. + +- toggle non-functional when NumLock set on Windows. Issue 3851. + + +What's New in IDLE 2.7? +======================= + +*Release date: 07-03-2010* + +- idle.py modified and simplified to better support developing experimental + versions of IDLE which are not installed in the standard location. + +- OutputWindow/PyShell right click menu "Go to file/line" wasn't working with + file paths containing spaces. Bug 5559. + +- Windows: Version string for the .chm help file changed, file not being + accessed Patch 5783 Guilherme Polo + +- Allow multiple IDLE GUI/subprocess pairs to exist simultaneously. Thanks to + David Scherer for suggesting the use of an ephemeral port for the GUI. + Patch 1529142 Weeble. + +- Remove port spec from run.py and fix bug where subprocess fails to + extract port from command line when warnings are present. + +- Tk 8.5 Text widget requires 'wordprocessor' tabstyle attr to handle + mixed space/tab properly. Issue 5129, patch by Guilherme Polo. + +- Issue #3549: On MacOS the preferences menu was not present + + +What's New in IDLE 2.6? +======================= + +*Release date: 01-Oct-2008* + +- Issue #2665: On Windows, an IDLE installation upgraded from an old version + would not start if a custom theme was defined. + +- Home / Control-A toggles between left margin and end of leading white + space. Patch 1196903 Jeff Shute. + +- Improved AutoCompleteWindow logic. Patch 2062 Tal Einat. + +- Autocompletion of filenames now support alternate separators, e.g. the + '/' char on Windows. Patch 2061 Tal Einat. + +What's New in IDLE 2.6a1? +========================= + +*Release date: 29-Feb-2008* + +- Configured selection highlighting colors were ignored; updating highlighting + in the config dialog would cause non-Python files to be colored as if they + were Python source; improve use of ColorDelagator. Patch 1334. Tal Einat. + +- ScriptBinding event handlers weren't returning 'break'. Patch 2050, Tal Einat. + +- There was an error on exit if no sys.exitfunc was defined. Issue 1647. + +- Could not open files in .idlerc directory if latter was hidden on Windows. + Issue 1743, Issue 1862. + +- Configure Dialog: improved layout for keybinding. Patch 1457 Tal Einat. + +- tabpage.py updated: tabbedPages.py now supports multiple dynamic rows + of tabs. Patch 1612746 Tal Einat. + +- Add confirmation dialog before printing. Patch 1717170 Tal Einat. + +- Show paste position if > 80 col. Patch 1659326 Tal Einat. + +- Update cursor color without restarting. Patch 1725576 Tal Einat. + +- Allow keyboard interrupt only when user code is executing in subprocess. + Patch 1225 Tal Einat (reworked from IDLE-Spoon). + +- configDialog cleanup. Patch 1730217 Tal Einat. + +- textView cleanup. Patch 1718043 Tal Einat. + +- Clean up EditorWindow close. + +- Patch 1693258: Fix for duplicate "preferences" menu-OS X. Backport of r56204. + +- OSX: Avoid crash for those versions of Tcl/Tk which don't have a console + +- Bug in idlelib.MultiCall: Options dialog was crashing IDLE if there was an + option in config-extensions w/o a value. Patch #1672481, Tal Einat + +- Corrected some bugs in AutoComplete. Also, Page Up/Down in ACW implemented; + mouse and cursor selection in ACWindow implemented; double Tab inserts + current selection and closes ACW (similar to double-click and Return); scroll + wheel now works in ACW. Added AutoComplete instructions to IDLE Help. + +- AutoCompleteWindow moved below input line, will move above if there + isn't enough space. Patch 1621265 Tal Einat + +- Calltips now 'handle' tuples in the argument list (display '' :) + Suggested solution by Christos Georgiou, Bug 791968. + +- Add 'raw' support to configHandler. Patch 1650174 Tal Einat. + +- Avoid hang when encountering a duplicate in a completion list. Bug 1571112. + +- Patch #1362975: Rework CodeContext indentation algorithm to + avoid hard-coding pixel widths. + +- Bug #813342: Start the IDLE subprocess with -Qnew if the parent + is started with that option. + +- Honor the "Cancel" action in the save dialog (Debian bug #299092) + +- Some syntax errors were being caught by tokenize during the tabnanny + check, resulting in obscure error messages. Do the syntax check + first. Bug 1562716, 1562719 + +- IDLE's version number takes a big jump to match the version number of + the Python release of which it's a part. + + +What's New in IDLE 1.2? +======================= + +*Release date: 19-SEP-2006* + + +What's New in IDLE 1.2c1? +========================= + +*Release date: 17-AUG-2006* + +- File menu hotkeys: there were three 'p' assignments. Reassign the + 'Save Copy As' and 'Print' hotkeys to 'y' and 't'. Change the + Shell hotkey from 's' to 'l'. + +- IDLE honors new quit() and exit() commands from site.py Quitter() object. + Patch 1540892, Jim Jewett + +- The 'with' statement is now a Code Context block opener. + Patch 1540851, Jim Jewett + +- Retrieval of previous shell command was not always preserving indentation + (since 1.2a1) Patch 1528468 Tal Einat. + +- Changing tokenize (39046) to detect dedent broke tabnanny check (since 1.2a1) + +- ToggleTab dialog was setting indent to 8 even if cancelled (since 1.2a1). + +- When used w/o subprocess, all exceptions were preceded by an error + message claiming they were IDLE internal errors (since 1.2a1). + +What's New in IDLE 1.2b3? +========================= + +*Release date: 03-AUG-2006* + +- Bug #1525817: Don't truncate short lines in IDLE's tool tips. + +- Bug #1517990: IDLE keybindings on MacOS X now work correctly + +- Bug #1517996: IDLE now longer shows the default Tk menu when a + path browser, class browser or debugger is the frontmost window on MacOS X + +- EditorWindow.test() was failing. Bug 1417598 + +- EditorWindow failed when used stand-alone if sys.ps1 not set. + Bug 1010370 Dave Florek + +- Tooltips failed on new-syle class __init__ args. Bug 1027566 Loren Guthrie + +- Avoid occasional failure to detect closing paren properly. + Patch 1407280 Tal Einat + +- Rebinding Tab key was inserting 'tab' instead of 'Tab'. Bug 1179168. + +- Colorizer now handles # correctly, also unicode strings and + 'as' keyword in comment directly following import command. Closes 1325071. + Patch 1479219 Tal Einat + +What's New in IDLE 1.2b2? +========================= + +*Release date: 11-JUL-2006* + +What's New in IDLE 1.2b1? +========================= + +*Release date: 20-JUN-2006* + +What's New in IDLE 1.2a2? +========================= + +*Release date: 27-APR-2006* + +What's New in IDLE 1.2a1? +========================= + +*Release date: 05-APR-2006* + +- Patch #1162825: Support non-ASCII characters in IDLE window titles. + +- Source file f.flush() after writing; trying to avoid lossage if user + kills GUI. + +- Options / Keys / Advanced dialog made functional. Also, allow binding + of 'movement' keys. + +- 'syntax' patch adds improved calltips and a new class attribute listbox. + MultiCall module allows binding multiple actions to an event. + Patch 906702 Noam Raphael + +- Better indentation after first line of string continuation. + IDLEfork Patch 681992, Noam Raphael + +- Fixed CodeContext alignment problem, following suggestion from Tal Einat. + +- Increased performance in CodeContext extension Patch 936169 Noam Raphael + +- Mac line endings were incorrect when pasting code from some browsers + when using X11 and the Fink distribution. Python Bug 1263656. + +- when cursor is on a previous command retrieves that command. Instead + of replacing the input line, the previous command is now appended to the + input line. Indentation is preserved, and undo is enabled. + Patch 1196917 Jeff Shute + +- Clarify "tab/space" Error Dialog and "Tab Width" Dialog associated with + the Untabify command. + +- Corrected "tab/space" Error Dialog to show correct menu for Untabify. + Patch 1196980 Jeff Shute + +- New files are colorized by default, and colorizing is removed when + saving as non-Python files. Patch 1196895 Jeff Shute + Closes Python Bugs 775012 and 800432, partial fix IDLEfork 763524 + +- Improve subprocess link error notification. + +- run.py: use Queue's blocking feature instead of sleeping in the main + loop. Patch # 1190163 Michiel de Hoon + +- Add config-main option to make the 'history' feature non-cyclic. + Default remains cyclic. Python Patch 914546 Noam Raphael. + +- Removed ability to configure tabs indent from Options dialog. This 'feature' + has never worked and no one has complained. It is still possible to set a + default tabs (v. spaces) indent 'manually' via config-main.def (or to turn on + tabs for the current EditorWindow via the Format menu) but IDLE will + encourage indentation via spaces. + +- Enable setting the indentation width using the Options dialog. + Bug # 783877 + +- Add keybindings for del-word-left and del-word-right. + +- Discourage using an indent width other than 8 when using tabs to indent + Python code. + +- Restore use of EditorWindow.set_indentation_params(), was dead code since + Autoindent was merged into EditorWindow. This allows IDLE to conform to the + indentation width of a loaded file. (But it still will not switch to tabs + even if the file uses tabs.) Any change in indent width is local to that + window. + +- Add Tabnanny check before Run/F5, not just when Checking module. + +- If an extension can't be loaded, print warning and skip it instead of + erroring out. + +- Improve error handling when .idlerc can't be created (warn and exit). + +- The GUI was hanging if the shell window was closed while a raw_input() + was pending. Restored the quit() of the readline() mainloop(). + http://mail.python.org/pipermail/idle-dev/2004-December/002307.html + +- The remote procedure call module rpc.py can now access data attributes of + remote registered objects. Changes to these attributes are local, however. + +What's New in IDLE 1.1? +======================= + +*Release date: 30-NOV-2004* + +- On OpenBSD, terminating IDLE with ctrl-c from the command line caused a + stuck subprocess MainThread because only the SocketThread was exiting. + +What's New in IDLE 1.1b3/rc1? +============================= + +*Release date: 18-NOV-2004* + +- Saving a Keyset w/o making changes (by using the "Save as New Custom Key Set" + button) caused IDLE to fail on restart (no new keyset was created in + config-keys.cfg). Also true for Theme/highlights. Python Bug 1064535. + +- A change to the linecache.py API caused IDLE to exit when an exception was + raised while running without the subprocess (-n switch). Python Bug 1063840. + +What's New in IDLE 1.1b2? +========================= + +*Release date: 03-NOV-2004* + +- When paragraph reformat width was made configurable, a bug was + introduced that caused reformatting of comment blocks to ignore how + far the block was indented, effectively adding the indentation width + to the reformat width. This has been repaired, and the reformat + width is again a bound on the total width of reformatted lines. + +What's New in IDLE 1.1b1? +========================= + +*Release date: 15-OCT-2004* + + +What's New in IDLE 1.1a3? +========================= + +*Release date: 02-SEP-2004* + +- Improve keyboard focus binding, especially in Windows menu. Improve + window raising, especially in the Windows menu and in the debugger. + IDLEfork 763524. + +- If user passes a non-existent filename on the commandline, just + open a new file, don't raise a dialog. IDLEfork 854928. + + +What's New in IDLE 1.1a2? +========================= + +*Release date: 05-AUG-2004* + +- EditorWindow.py was not finding the .chm help file on Windows. Typo + at Rev 1.54. Python Bug 990954 + +- checking sys.platform for substring 'win' was breaking IDLE docs on Mac + (darwin). Also, Mac Safari browser requires full file:// URIs. SF 900580. + + +What's New in IDLE 1.1a1? +========================= + +*Release date: 08-JUL-2004* + +- Redirect the warning stream to the shell during the ScriptBinding check of + user code and format the warning similarly to an exception for both that + check and for runtime warnings raised in the subprocess. + +- CodeContext hint pane visibility state is now persistent across sessions. + The pane no longer appears in the shell window. Added capability to limit + extensions to shell window or editor windows. Noam Raphael addition + to Patch 936169. + +- Paragraph reformat width is now a configurable parameter in the + Options GUI. + +- New Extension: CodeContext. Provides block structuring hints for code + which has scrolled above an edit window. Patch 936169 Noam Raphael. + +- If nulls somehow got into the strings in recent-files.lst + EditorWindow.update_recent_files_list() was failing. Python Bug 931336. + +- If the normal background is changed via Configure/Highlighting, it will + update immediately, thanks to the previously mentioned patch by Nigel Rowe. + +- Add a highlight theme for builtin keywords. Python Patch 805830 Nigel Rowe + This also fixed IDLEfork bug [ 693418 ] Normal text background color not + refreshed and Python bug [897872 ] Unknown color name on HP-UX + +- rpc.py:SocketIO - Large modules were generating large pickles when downloaded + to the execution server. The return of the OK response from the subprocess + initialization was interfering and causing the sending socket to be not + ready. Add an IO ready test to fix this. Moved the polling IO ready test + into pollpacket(). + +- Fix typo in rpc.py, s/b "pickle.PicklingError" not "pickle.UnpicklingError". + +- Added a Tk error dialog to run.py inform the user if the subprocess can't + connect to the user GUI process. Added a timeout to the GUI's listening + socket. Added Tk error dialogs to PyShell.py to announce a failure to bind + the port or connect to the subprocess. Clean up error handling during + connection initiation phase. This is an update of Python Patch 778323. + +- Print correct exception even if source file changed since shell was + restarted. IDLEfork Patch 869012 Noam Raphael + +- Keybindings with the Shift modifier now work correctly. So do bindings which + use the Space key. Limit unmodified user keybindings to the function keys. + Python Bug 775353, IDLEfork Bugs 755647, 761557 + +- After an exception, run.py was not setting the exception vector. Noam + Raphael suggested correcting this so pdb's postmortem pm() would work. + IDLEfork Patch 844675 + +- IDLE now does not fail to save the file anymore if the Tk buffer is not a + Unicode string, yet eol_convention is. Python Bugs 774680, 788378 + +- IDLE didn't start correctly when Python was installed in "Program Files" on + W2K and XP. Python Bugs 780451, 784183 + +- config-main.def documentation incorrectly referred to idle- instead of + config- filenames. SF 782759 Also added note about .idlerc location. + + +What's New in IDLE 1.0? +======================= + +*Release date: 29-Jul-2003* + +- Added a banner to the shell discussing warnings possibly raised by personal + firewall software. Added same comment to README.txt. + + +What's New in IDLE 1.0 release candidate 2? +=========================================== + +*Release date: 24-Jul-2003* + +- Calltip error when docstring was None Python Bug 775541 + + +What's New in IDLE 1.0 release candidate 1? +=========================================== + +*Release date: 18-Jul-2003* + +- Updated extend.txt, help.txt, and config-extensions.def to correctly + reflect the current status of the configuration system. Python Bug 768469 + +- Fixed: Call Tip Trimming May Loop Forever. Python Patch 769142 (Daniels) + +- Replaced apply(f, args, kwds) with f(*args, **kwargs) to improve performance + Python Patch 768187 + +- Break or continue statements outside a loop were causing IDLE crash + Python Bug 767794 + +- Convert Unicode strings from readline to IOBinding.encoding. Also set + sys.std{in|out|err}.encoding, for both the local and the subprocess case. + SF IDLEfork patch 682347. + + +What's New in IDLE 1.0b2? +========================= + +*Release date: 29-Jun-2003* + +- Extend AboutDialog.ViewFile() to support file encodings. Make the CREDITS + file Latin-1. + +- Updated the About dialog to reflect re-integration into Python. Provide + buttons to display Python's NEWS, License, and Credits, plus additional + buttons for IDLE's README and NEWS. + +- TextViewer() now has a third parameter which allows inserting text into the + viewer instead of reading from a file. + +- (Created the .../Lib/idlelib directory in the Python CVS, which is a clone of + IDLEfork modified to install in the Python environment. The code in the + interrupt module has been moved to thread.interrupt_main(). ) + +- Printing the Shell window was failing if it was not saved first SF 748975 + +- When using the Search in Files dialog, if the user had a selection + highlighted in his Editor window, insert it into the dialog search field. + +- The Python Shell entry was disappearing from the Windows menu. + +- Update the Windows file list when a file name change occurs + +- Change to File / Open Module: always pop up the dialog, using the current + selection as the default value. This is easier to use habitually. + +- Avoided a problem with starting the subprocess when 'localhost' doesn't + resolve to the user's loopback interface. SF 747772 + +- Fixed an issue with highlighted errors never de-colorizing. SF 747677. Also + improved notification of Tabnanny Token Error. + +- File / New will by default save in the directory of the Edit window from + which it was initiated. SF 748973 Guido van Rossum patch. + + +What's New in IDLEfork 0.9b1? +============================= + +*Release date: 02-Jun-2003* + +- The current working directory of the execution environment (and shell + following completion of execution) is now that of the module being run. + +- Added the delete-exitfunc option to config-main.def. (This option is not + included in the Options dialog.) Setting this to True (the default) will + cause IDLE to not run sys.exitfunc/atexit when the subprocess exits. + +- IDLE now preserves the line ending codes when editing a file produced on + a different platform. SF 661759, SF 538584 + +- Reduced default editor font size to 10 point and increased window height + to provide a better initial impression on Windows. + +- Options / Fonts/Tabs / Set Base Editor Font: List box was not highlighting + the default font when first installed on Windows. SF 661676 + +- Added Autosave feature: when user runs code from edit window, if the file + has been modified IDLE will silently save it if Autosave is enabled. The + option is set in the Options dialog, and the default is to prompt the + user to save the file. SF 661318 Bruce Sherwood patch. + +- Improved the RESTART annotation in the shell window when the user restarts + the shell while it is generating output. Also improved annotation when user + repeatedly hammers the Ctrl-F6 restart. + +- Allow IDLE to run when not installed and cwd is not the IDLE directory + SF Patch 686254 "Run IDLEfork from any directory without set-up" - Raphael + +- When a module is run from an EditorWindow: if its directory is not in + sys.path, prepend it. This allows the module to import other modules in + the same directory. Do the same for a script run from the command line. + +- Correctly restart the subprocess if it is running user code and the user + attempts to run some other module or restarts the shell. Do the same if + the link is broken and it is possible to restart the subprocess and re- + connect to the GUI. SF RFE 661321. + +- Improved exception reporting when running commands or scripts from the + command line. + +- Added a -n command line switch to start IDLE without the subprocess. + Removed the Shell menu when running in that mode. Updated help messages. + +- Added a comment to the shell startup header to indicate when IDLE is not + using the subprocess. + +- Restore the ability to run without the subprocess. This can be important for + some platforms or configurations. (Running without the subprocess allows the + debugger to trace through parts of IDLE itself, which may or may not be + desirable, depending on your point of view. In addition, the traditional + reload/import tricks must be use if user source code is changed.) This is + helpful for developing IDLE using IDLE, because one instance can be used to + edit the code and a separate instance run to test changes. (Multiple + concurrent IDLE instances with subprocesses is a future feature) + +- Improve the error message a user gets when saving a file with non-ASCII + characters and no source encoding is specified. Done by adding a dialog + 'EncodingMessage', which contains the line to add in a fixed-font entry + widget, and which has a button to add that line to the file automatically. + Also, add a configuration option 'EditorWindow/encoding', which has three + possible values: none, utf-8, and locale. None is the default: IDLE will show + this dialog when non-ASCII characters are encountered. utf-8 means that files + with non-ASCII characters are saved as utf-8-with-bom. locale means that + files are saved in the locale's encoding; the dialog is only displayed if the + source contains characters outside the locale's charset. SF 710733 - Loewis + +- Improved I/O response by tweaking the wait parameter in various + calls to signal.signal(). + +- Implemented a threaded subprocess which allows interrupting a pass + loop in user code using the 'interrupt' extension. User code runs + in MainThread, while the RPCServer is handled by SockThread. This is + necessary because Windows doesn't support signals. + +- Implemented the 'interrupt' extension module, which allows a subthread + to raise a KeyboardInterrupt in the main thread. + +- Attempting to save the shell raised an error related to saving + breakpoints, which are not implemented in the shell + +- Provide a correct message when 'exit' or 'quit' are entered at the + IDLE command prompt SF 695861 + +- Eliminate extra blank line in shell output caused by not flushing + stdout when user code ends with an unterminated print. SF 695861 + +- Moved responsibility for exception formatting (i.e. pruning IDLE internal + calls) out of rpc.py into the client and server. + +- Exit IDLE cleanly even when doing subprocess I/O + +- Handle subprocess interrupt with an RPC message. + +- Restart the subprocess if it terminates itself. (VPython programs do that) + +- Support subclassing of exceptions, including in the shell, by moving the + exception formatting to the subprocess. + + + +What's New in IDLEfork 0.9 Alpha 2? +=================================== + +*Release date: 27-Jan-2003* + +- Updated INSTALL.txt to claify use of the python2 rpm. + +- Improved formatting in IDLE Help. + +- Run menu: Replace "Run Script" with "Run Module". + +- Code encountering an unhandled exception under the debugger now shows + the correct traceback, with IDLE internal levels pruned out. + +- If an exception occurs entirely in IDLE, don't prune the IDLE internal + modules from the traceback displayed. + +- Class Browser and Path Browser now use Alt-Key-2 for vertical zoom. + +- IDLE icons will now install correctly even when setup.py is run from the + build directory + +- Class Browser now compatible with Python2.3 version of pyclbr.py + +- Left cursor move in presence of selected text now moves from left end + of the selection. + +- Add Meta keybindings to "IDLE Classic Windows" to handle reversed + Alt/Meta on some Linux distros. + +- Change default: IDLE now starts with Python Shell. + +- Removed the File Path from the Additional Help Sources scrolled list. + +- Add capability to access Additional Help Sources on the web if the + Help File Path begins with //http or www. (Otherwise local path is + validated, as before.) + +- Additional Help Sources were not being posted on the Help menu in the + order entered. Implement sorting the list by [HelpFiles] 'option' + number. + +- Add Browse button to New Help Source dialog. Arrange to start in + Python/Doc if platform is Windows, otherwise start in current directory. + +- Put the Additional Help Sources directly on the Help menu instead of in + an Extra Help cascade menu. Rearrange the Help menu so the Additional + Help Sources come last. Update help.txt appropriately. + +- Fix Tk root pop-ups in configSectionNameDialog.py and configDialog.py + +- Uniform capitalization in General tab of ConfigDialog, update the doc string. + +- Fix bug in ConfigDialog where SaveAllChangedConfig() was unexpectedly + deleting Additional Help Sources from the user's config file. + +- Make configHelpSourceEdit OK button the default and bind + +- Fix Tk root pop-ups in configHelpSourceEdit: error dialogs not attached + to parents. + +- Use os.startfile() to open both Additional Help and Python Help on the + Windows platform. The application associated with the file type will act as + the viewer. Windows help files (.chm) are now supported via the + Settings/General/Additional Help facility. + +- If Python Help files are installed locally on Linux, use them instead of + accessing python.org. + +- Make the methods for finding the Python help docs more robust, and make + them work in the installed configuration, also. + +- On the Save Before Run dialog, make the OK button the default. One + less mouse action! + +- Add a method: EditorWindow.get_geometry() for future use in implementing + window location persistence. + +- Removed the "Help/Advice" menu entry. Thanks, David! We'll remember! + +- Change the "Classic Windows" theme's paste key to be . + +- Rearrange the Shell menu to put Stack Viewer entries adjacent. + +- Add the ability to restart the subprocess interpreter from the shell window; + add an associated menu entry "Shell/Restart" with binding Control-F6. Update + IDLE help. + +- Upon a restart, annotate the shell window with a "restart boundary". Add a + shell window menu "Shell/View Restart" with binding F6 to jump to the most + recent restart boundary. + +- Add Shell menu to Python Shell; change "Settings" to "Options". + +- Remove incorrect comment in setup.py: IDLEfork is now installed as a package. + +- Add INSTALL.txt, HISTORY.txt, NEWS.txt to installed configuration. + +- In installer text, fix reference to Visual Python, should be VPython. + Properly credit David Scherer. + +- Modified idle, idle.py, idle.pyw to improve exception handling. + + +What's New in IDLEfork 0.9 Alpha 1? +=================================== + +*Release date: 31-Dec-2002* + +- First release of major new functionality. For further details refer to + Idle-dev and/or the Sourceforge CVS. + +- Adapted to the Mac platform. + +- Overhauled the IDLE startup options and revised the idle -h help message, + which provides details of command line usage. + +- Multiple bug fixes and usability enhancements. + +- Introduced the new RPC implementation, which includes a debugger. The output + of user code is to the shell, and the shell may be used to inspect the + environment after the run has finished. (In version 0.8.1 the shell + environment was separate from the environment of the user code.) + +- Introduced the configuration GUI and a new About dialog. + +- Removed David Scherer's Remote Procedure Call code and replaced with Guido + van Rossum's. GvR code has support for the IDLE debugger and uses the shell + to inspect the environment of code Run from an Edit window. Files removed: + ExecBinding.py, loader.py, protocol.py, Remote.py, spawn.py + +-------------------------------------------------------------------- +Refer to HISTORY.txt for additional information on earlier releases. +-------------------------------------------------------------------- + + + + + diff --git a/PythonHome/Lib/idlelib/ObjectBrowser.pyc b/PythonHome/Lib/idlelib/ObjectBrowser.pyc new file mode 100644 index 0000000000000000000000000000000000000000..73a8fe6726aa5f905a105fae2df52ad24f395b66 GIT binary patch literal 6647 zcmcIp>v9vx6+SbPWlPw`7cADhz|JZ`6RHgDe&yWYoo8$qK?>nuF&6321#CG@ez0c)4r%$&F|5&K}?eBkTv}N>D z!1ptxe9se!@aIV)vhB*gB%XAA+4iMdknMtWi?Ur5kK+oG%t*H++a>W#NnT>otVBgI zv(lU!7s?XNi1B5|lc*%Ggu}kxu1GX1rlPHLlh$(*mB+1>N$b2s=f1+pCXD@3}^-Q(2pns1v2vrjYWxkEzD4}Y$;KPEI_L>TEHyT;Wo57 zt1T4?8nrUkZ5NR-akovR{6l1io*araQSh~ZYC#J=_ird8BLQ%cBy5?)ngeS~sP&W` zdyb14yE91JHtwZ0ZlcWRCfNyQPzyLZm_=4Ya#?-_rJK(l#jR&?l$ZoxC!YIR??rC1 zoBg4Rx!H`<*fyINF+Arw;+65+rijN$+2QiwWq(RGyLEqMBcKM)w*Ne4d}-_>a=itv zKR`XF{A9ZSM4U@#w%A`Ky6+QAC*()kyTc5CP~otka(P?g$S;T^U6)aOoh~x3a=Czl zlgmqtS|Xeps#{WCS4Be9dr%ywSn~WZ|NNjIrcu~R%-fPjRDisP?Os|ByM|!Pi45`P z-ypmNbT}eGTBkgb9BEYGsLblU^sVWsU?uPs#g<%MMQtoG?ok*emDtZw8D6F`VIEN9 zk=h0ot6KFQr?cXDURseSBeVIwwUAZwZI~$WPS4y!L8!c_711~_XkgBUORB!%RR0Nz zIdvvp0g_!tUi2r%LDrO|^C*xX#V1&rpC4nBLo7*);&;Mhz%71=G!`q-M9h;|rQt6q z9H-&PlU<>35Be1JgXep4RFGj+>_pxLdFjhhQ68rkqzEcI70K$9{Wq5+_2da8X=muN zz!GqM@vu1ZUr-jkCG=I0BaHB6za)n<>ftf>F&Y}`*Xv5|#+^1rz(mE-55rO%xgbVO z8Y_)uriMbk;PygmGhHcI;{-0zF+-46@_?UcE-2F>?AT zd`7crxk$6w?L~tG)nFObfCo{)j(}bxpq_#iW<0VLhQY@uO{vw=DbAaKjB*jxeaV|I zmVNvdkmkz136fmZwrS{G50Q#s;A@u0tDP9+5P|PKllOmdKcY) zMaqxqzJNM)qqcsDA?oTep`0@kZZ=zCZh)GnKYqS(=Qx^1?Ld<{zA2hWe`3<(C>o7*=puNWBPJdc zPr+5TA)VR_D^z}m2}&hF^&Y%c)nD_L{-@BojxE0AHsnvCbpeHYw%3i@|K^rJ+1=+9 zI>FaG3>*u)-|Scz@TsBIRnATx9R8M0<&Px70n5qzq_s`ut)n?6Hdj>~DM)a2QNbBn#7B^X}wqV5z4_$H^gkOiIpoDC{CG^W?y)c=So& z!Sfy3{BU_BG1&GxqBR$o`5Ksgrh(b224?7XlBGs8gd3eG`p{72B@U09QE#>1@8}IVR-v4FW&3ib!c$qox&q z9VJKCN%M1LemvgiY&$YadxE4FZMr3#dAwXah~MyRK@i{P;Q!)~Xhsy|Cdbm8hzyN8 zUMkFni=(&$)ydro!M);uo45xE6}@t&@oJ7>_gMI_fpKT!l`}d>qubMY$aWE_=)LaL zIB>eOmQI7EpI{o;bXY2R>ONrOBG(nxgj5kprScmT=#1QT6UI>x4DFO8yT$^l>$nA_ zC0>nC;5A1_^MsvVOA1_tYuaJoC`h9??}xU%r;)8gi$a+wcGqeWWRDGXfij!JSgODSOhUcwG>)x(omNiOdAQsrvw(kD&6t6@w9 z>-gGwjw^ZqIfk$YPn>wq#3;O9E`pN6(VQI4$^L@u>)Rz7BfOz3>jD-Jmn*6@sHH48 zw>Wf}ydHv7xVMTNR%CxwHz5%hw1oafZ50Bl>kFfU2F+xvlk+CCWpcZ5;x$a;gr^5L zo~vcvxEA3r{wsz85F)KePj*+{)wp|TlBD-S4~`dmxV%}eyBF{7B}mrp#qCaN^4u~U zx419v^xA`5<1?LZ^!-P{v=b+Z7Fs>K=kAfiyry23)~|QQtxlX;lLfzI0}*Cpn;4zN zyQI$QhJF2Fq!OAL9hvu&*eY0eO|NTgHdLDMY_t>a4lsxmDs@fVwga-O^L8@a5Os%s z*zPzltY9X#+xiTv*F|M#(2qjMfSBxtahmjceRtX9;C`5y)COe6F+dZ_dOho;7e`>5 zj+8LP*PrSGX^)!rUOs`GqOQi`v~9QD`cwk(c|h(-dG;T5uOeLbV)!qRGI-D ze89;8?N;U84G-{G5U0B%ksUzwP%i}&e9G)PGlp#ekBor6&gmVV$2}uFOzqa#4L$0m zyIP?xzeswa>!Rmq=r)titwBFA(|N$oq@rgKS0ufYdpH}os=Jk;7W@J=_fVjhPW+!l z^gd|$hBB50zfB8LZ|*SXy;z2oF>r7&MEFHz0^0zemp5dZ)H literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/idlelib/OutputWindow.pyc b/PythonHome/Lib/idlelib/OutputWindow.pyc new file mode 100644 index 0000000000000000000000000000000000000000..011d7bdf91f981f0a69306f1a98e90092c5a57c3 GIT binary patch literal 5007 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 literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/idlelib/ParenMatch.pyc b/PythonHome/Lib/idlelib/ParenMatch.pyc new file mode 100644 index 0000000000000000000000000000000000000000..c3aa4989dbb6970b35ececdfa2e203f7c8d1b5ad GIT binary patch literal 6874 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 literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/idlelib/Percolator.pyc b/PythonHome/Lib/idlelib/Percolator.pyc new file mode 100644 index 0000000000000000000000000000000000000000..b13cbae41baf1959d846a2aa80cce78eb6936796 GIT binary patch literal 4383 zcmd5<>uwuG6h5=IW3TJbP)NB6Xt^3H1yX(>0YX5F0un@MQm9BvEoXP)Y+|p|-6^C} z{HH;*Nc=`T0?)v6@FqL}eBYUM99mEli61zb*}0rKbLKmjIaB*%zWwX(ch?fBel>hQ zKq)g+DgKQNMMg%}jTrVL8AdXy$$Aa_nxwI$b@^W8K;-N7x}*(u)*IsHB%PC;ND8NX znlfz4s3q$yF|H-9AqU`?gJVn9x^3*1{fS@Kpyd}(UCq*g^VX$V;SxVC!c2^r%Wmif zeGGXn`@$8;c*ySIAtDTagi>BcpI$Cy&cImc2TMSo^;kB6p8SfNLU&oYpd*0$JzJaPBmR14gYCqo9 zMH^%9$0OfTia}O-S6I$l<-n6~W-;*hrfi9v2Yv37uF$ruP7{f_H83Ou@v13D1r&Y zgBjhd$yK02c&3Egu*EQ0O$5Lj1pfg0RHM*+SOm`o7gN!Z01ptI>x3& zfqEJP0S!Pzi-i5u;GpFDV^GQ5HZ*}L|m>+9?gpA`9hH*;df-5YNz$ zAyv63K9W0%<~D+b$WBYj*N+SaXNEDs{;D7Vx1PaG^U(m6mGDsC&l4AX?-5LVSkh;+ zasF{pAdb<>4sD3@mdaOUsng9s2nKlkldJ892oaV(55^_;lV}lkwO}-?{Y_85Ve%nZ z#7D4z7dB)9i^D%0v?awgHh>!a5ip^x$PlUgn(VzxQceeV{zX@UOOxJR-kD+y8U#RC zf1t(=H*d&QcIGPn74$RiN8sm0Vb8Ks|D)~MCs`@H>f4Gjp-?py4vw7klPx#1JNp!8 z$zb#NklT6Czk*V7zW{S=I`~_N&H(bZnFs8vT}oI*#k@aqy`GBE>y5_gts%OWVMilD zkeNEtm~83py30%`Z9OaoTbevwL1XV+6vuI^Q}5K{X2LTP8N$Jh${ZuOq<|>y{|OqQ zZK!G7n{bXzjNsA?SN}xS38g||6Wn%nVF0eHcOb05Yd!8aRVh*gMuC{5@HGA#xn7qE ztY}UqO_{WGJuW&Z8mn58Hsy)UNX||b-X;M$lUNXf_rc1@kMLeNDoh4#_^sw9Y)5ie zNl(i?9M{w) z9og^51IqvcSR5`}&}FA|8D+0c=4F3=x=aoCQQ*F+S&#;~D@8v+Zi7MnQ9~c0lrN(C z*Q5p+4YHd$bCw$D)VZgDZjGy-MFqj=nrhleN6^Op(8JMCTnC-r0<_KGLu!vSl37f$ z=h#I#UJ{@t{Vu3WvKQQG36DhqS+1g#FQKA+h^)ZoRv_!jC+q`E4KP22%X>|QSk+MW z&bbibg5#b8gW&2!U?!`creB=+PJ16*DtQqt{~LL$M2!L}gh5_{GLzSyXBXv|*mCuU zD2K9kd7WD-+&;%j^`~3vMi@E?dtMyxpp?9e=S*CSYb7J-6<7Lmvs6!azqWVb8>PGO za*F@#XV4*Hpjr-}iwQdV}UDnz|yZ71W=sGp~LNdoVzzk%ls;S59V!{{-tOV+`E9OIi`HD_Y`X*7e9Jt8_Zf4S zPPEusY_-ukj|_%&mAj1kS>Ee~*EyvuZsn`WCL}n_fvN}L()~~R@HFMMH>J2decFc` zhxpl#Suu)vCUH|retRCVXK9PIUBO(~7LDUYOg+GRA>DeP!9dM&0cqM}Z^cVU*UVqA Ckmf-E literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/idlelib/PyParse.pyc b/PythonHome/Lib/idlelib/PyParse.pyc new file mode 100644 index 0000000000000000000000000000000000000000..d40b320400dc9672129020e382e1a9b91f1f0443 GIT binary patch literal 9749 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 a_1DSo@cWIuJ9h2dHBXuEoZ!9jq5mKJXVXCd literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/idlelib/README.txt b/PythonHome/Lib/idlelib/README.txt new file mode 100644 index 0000000000..101f7eba16 --- /dev/null +++ b/PythonHome/Lib/idlelib/README.txt @@ -0,0 +1,63 @@ +IDLE is Python's Tkinter-based Integrated DeveLopment Environment. + +IDLE emphasizes a lightweight, clean design with a simple user interface. +Although it is suitable for beginners, even advanced users will find that +IDLE has everything they really need to develop pure Python code. + +IDLE features a multi-window text editor with multiple undo, Python colorizing, +and many other capabilities, e.g. smart indent, call tips, and autocompletion. + +The editor has comprehensive search functions, including searching through +multiple files. Class browsers and path browsers provide fast access to +code objects from a top level viewpoint without dealing with code folding. + +There is a Python Shell window which features colorizing and command recall. + +IDLE executes Python code in a separate process, which is restarted for each +Run (F5) initiated from an editor window. The environment can also be +restarted from the Shell window without restarting IDLE. + +This enhancement has often been requested, and is now finally available. The +magic "reload/import *" incantations are no longer required when editing and +testing a module two or three steps down the import chain. + +(Personal firewall software may warn about the connection IDLE makes to its +subprocess using this computer's internal loopback interface. This connection +is not visible on any external interface and no data is sent to or received +from the Internet.) + +It is possible to interrupt tightly looping user code, even on Windows. + +Applications which cannot support subprocesses and/or sockets can still run +IDLE in a single process. + +IDLE has an integrated debugger with stepping, persistent breakpoints, and call +stack visibility. + +There is a GUI configuration manager which makes it easy to select fonts, +colors, keybindings, and startup options. This facility includes a feature +which allows the user to specify additional help sources, either locally or on +the web. + +IDLE is coded in 100% pure Python, using the Tkinter GUI toolkit (Tk/Tcl) +and is cross-platform, working on Unix, Mac, and Windows. + +IDLE accepts command line arguments. Try idle -h to see the options. + + +If you find bugs or have suggestions, let us know about them by using the +Python Bug Tracker: + +http://sourceforge.net/projects/python + +Patches are always appreciated at the Python Patch Tracker, and change +requests should be posted to the RFE Tracker. + +For further details and links, read the Help files and check the IDLE home +page at + +http://www.python.org/idle/ + +There is a mail list for IDLE: idle-dev@python.org. You can join at + +http://mail.python.org/mailman/listinfo/idle-dev diff --git a/PythonHome/Lib/idlelib/RemoteDebugger.pyc b/PythonHome/Lib/idlelib/RemoteDebugger.pyc new file mode 100644 index 0000000000000000000000000000000000000000..d33e1fcc18b5a12fb442c7921fb09f1078fa51f3 GIT binary patch literal 15420 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 YmuPZ=g(mJixb;*UjkOOO7x*0iZ$$hNssI20 literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/idlelib/RstripExtension.pyc b/PythonHome/Lib/idlelib/RstripExtension.pyc new file mode 100644 index 0000000000000000000000000000000000000000..1e73c0fe4fa72a0a3bd0093023d336502beaab3c GIT binary patch literal 1553 zcmbVM+invv5FLAyv`tfiKvbfD6jdt93lZYERESHTXat)FL{((Av0I#OcFWpni-p$RGi1Yrp{u}%|BLzIU? zRm|UMjm{>_4iz@3@m)N9b41hGQPdE8)M*tN;t9Lc27&CP!RFJ2xjt-i3|?8J3El-d zA}&r2x6GvnW2__jKX_8_cL?t*#@G^!k_66uFD8(#uwG#n?i;>)KkyzDYy_qcb;EbK z2IP)YHj-;c<(Ba(zF0B)c{w;TA!bz+zepgi0u`2**-S$QkxgE!vf|LmDNHiwu8?}1 zrB+nyau=Pn!A}9o;|^ygWtig4oxoUNrMw|o1$cv2n*|w+D+v-&ON_qCPGug9<3CnR z%II4dVHJXOOSN=U-%_h;O|{guq@^}=PYUy2TdE^;W(8SfBWFx(B7!la(vEZfJJ|=55sF+2HRL zyDa9tD4luYs{Jzf_`!283SM{S=T|KB7_2e292g^^(=|TGe8%WO_9s>xTQa+y<-z?A VG4Z)MySgo@ZVuAW*KZ?Z>MK)pN|^uv literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/idlelib/ScriptBinding.pyc b/PythonHome/Lib/idlelib/ScriptBinding.pyc new file mode 100644 index 0000000000000000000000000000000000000000..ef44401723f2f669350bffa96736323de8caaa87 GIT binary patch literal 7973 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 E0>P9K{Qv*} literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/idlelib/SearchDialog.pyc b/PythonHome/Lib/idlelib/SearchDialog.pyc new file mode 100644 index 0000000000000000000000000000000000000000..4c64ee1e388eb2d90fb46ffc998eb246f75d1be9 GIT binary patch literal 3811 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 W&Pwm`^Kt@f)ZVOL{u7<7;r$l{C9Dnr literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/idlelib/SearchEngine.pyc b/PythonHome/Lib/idlelib/SearchEngine.pyc new file mode 100644 index 0000000000000000000000000000000000000000..005f454196563db1929cf0309b788d65bdeb73a9 GIT binary patch literal 7992 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 literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/idlelib/StackViewer.pyc b/PythonHome/Lib/idlelib/StackViewer.pyc new file mode 100644 index 0000000000000000000000000000000000000000..b93582d2d1055b236536e832841afac8cf274a60 GIT binary patch literal 6076 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 literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/idlelib/TODO.txt b/PythonHome/Lib/idlelib/TODO.txt new file mode 100644 index 0000000000..e2f1ac0f27 --- /dev/null +++ b/PythonHome/Lib/idlelib/TODO.txt @@ -0,0 +1,210 @@ +Original IDLE todo, much of it now outdated: +============================================ +TO DO: + +- improve debugger: + - manage breakpoints globally, allow bp deletion, tbreak, cbreak etc. + - real object browser + - help on how to use it (a simple help button will do wonders) + - performance? (updates of large sets of locals are slow) + - better integration of "debug module" + - debugger should be global resource (attached to flist, not to shell) + - fix the stupid bug where you need to step twice + - display class name in stack viewer entries for methods + - suppress tracing through IDLE internals (e.g. print) DONE + - add a button to suppress through a specific module or class or method + - more object inspection to stack viewer, e.g. to view all array items +- insert the initial current directory into sys.path DONE +- default directory attribute for each window instead of only for windows + that have an associated filename +- command expansion from keywords, module contents, other buffers, etc. +- "Recent documents" menu item DONE +- Filter region command +- Optional horizontal scroll bar +- more Emacsisms: + - ^K should cut to buffer + - M-[, M-] to move by paragraphs + - incremental search? +- search should indicate wrap-around in some way +- restructure state sensitive code to avoid testing flags all the time +- persistent user state (e.g. window and cursor positions, bindings) +- make backups when saving +- check file mtimes at various points +- Pluggable interface with RCS/CVS/Perforce/Clearcase +- better help? +- don't open second class browser on same module (nor second path browser) +- unify class and path browsers +- Need to define a standard way whereby one can determine one is running + inside IDLE (needed for Tk mainloop, also handy for $PYTHONSTARTUP) +- Add more utility methods for use by extensions (a la get_selection) +- Way to run command in totally separate interpreter (fork+os.system?) DONE +- Way to find definition of fully-qualified name: + In other words, select "UserDict.UserDict", hit some magic key and + it loads up UserDict.py and finds the first def or class for UserDict. +- need a way to force colorization on/off +- need a way to force auto-indent on/off + +Details: + +- ^O (on Unix -- open-line) should honor autoindent +- after paste, show end of pasted text +- on Windows, should turn short filename to long filename (not only in argv!) + (shouldn't this be done -- or undone -- by ntpath.normpath?) +- new autoindent after colon even indents when the colon is in a comment! +- sometimes forward slashes in pathname remain +- sometimes star in window name remains in Windows menu +- With unix bindings, ESC by itself is ignored +- Sometimes for no apparent reason a selection from the cursor to the + end of the command buffer appears, which is hard to get rid of + because it stays when you are typing! +- The Line/Col in the status bar can be wrong initially in PyShell DONE + +Structural problems: + +- too much knowledge in FileList about EditorWindow (for example) +- should add some primitives for accessing the selection etc. + to repeat cumbersome code over and over + +====================================================================== + +Jeff Bauer suggests: + +- Open Module doesn't appear to handle hierarchical packages. +- Class browser should also allow hierarchical packages. +- Open and Open Module could benefit from a history, DONE + either command line style, or Microsoft recent-file + style. +- Add a Smalltalk-style inspector (i.e. Tkinspect) + +The last suggestion is already a reality, but not yet +integrated into IDLE. I use a module called inspector.py, +that used to be available from python.org(?) It no longer +appears to be in the contributed section, and the source +has no author attribution. + +In any case, the code is useful for visually navigating +an object's attributes, including its container hierarchy. + + >>> from inspector import Tkinspect + >>> Tkinspect(None, myObject) + +Tkinspect could probably be extended and refined to +integrate better into IDLE. + +====================================================================== + +Comparison to PTUI +------------------ + ++ PTUI's help is better (HTML!) + ++ PTUI can attach a shell to any module + ++ PTUI has some more I/O commands: + open multiple + append + examine (what's that?) + +====================================================================== + +Notes after trying to run Grail +------------------------------- + +- Grail does stuff to sys.path based on sys.argv[0]; you must set +sys.argv[0] to something decent first (it is normally set to the path of +the idle script). + +- Grail must be exec'ed in __main__ because that's imported by some +other parts of Grail. + +- Grail uses a module called History and so does idle :-( + +====================================================================== + +Robin Friedrich's items: + +Things I'd like to see: + - I'd like support for shift-click extending the selection. There's a + bug now that it doesn't work the first time you try it. + - Printing is needed. How hard can that be on Windows? FIRST CUT DONE + - The python-mode trick of autoindenting a line with is neat and + very handy. + - (someday) a spellchecker for docstrings and comments. + - a pagedown/up command key which moves to next class/def statement (top + level) + - split window capability + - DnD text relocation/copying + +Things I don't want to see. + - line numbers... will probably slow things down way too much. + - Please use another icon for the tree browser leaf. The small snake + isn't cutting it. + +---------------------------------------------------------------------- + +- Customizable views (multi-window or multi-pane). (Markus Gritsch) + +- Being able to double click (maybe double right click) on a callable +object in the editor which shows the source of the object, if +possible. (Gerrit Holl) + +- Hooks into the guts, like in Emacs. (Mike Romberg) + +- Sharing the editor with a remote tutor. (Martijn Faassen) + +- Multiple views on the same file. (Tony J Ibbs) + +- Store breakpoints in a global (per-project) database (GvR); Dirk +Heise adds: save some space-trimmed context and search around when +reopening a file that might have been edited by someone else. + +- Capture menu events in extensions without changing the IDLE source. +(Matthias Barmeier) + +- Use overlapping panels (a "notebook" in MFC terms I think) for info +that doesn't need to be accessible simultaneously (e.g. HTML source +and output). Use multi-pane windows for info that does need to be +shown together (e.g. class browser and source). (Albert Brandl) + +- A project should invisibly track all symbols, for instant search, +replace and cross-ref. Projects should be allowed to span multiple +directories, hosts, etc. Project management files are placed in a +directory you specify. A global mapping between project names and +project directories should exist [not so sure --GvR]. (Tim Peters) + +- Merge attr-tips and auto-expand. (Mark Hammond, Tim Peters) + +- Python Shell should behave more like a "shell window" as users know +it -- i.e. you can only edit the current command, and the cursor can't +escape from the command area. (Albert Brandl) + +- Set X11 class to "idle/Idle", set icon and title to something +beginning with "idle" -- for window manangers. (Randall Hopper) + +- Config files editable through a preferences dialog. (me) DONE + +- Config files still editable outside the preferences dialog. +(Randall Hopper) DONE + +- When you're editing a command in PyShell, and there are only blank +lines below the cursor, hitting Return should ignore or delete those +blank lines rather than deciding you're not on the last line. (me) + +- Run command (F5 c.s.) should be more like Pythonwin's Run -- a +dialog with options to give command line arguments, run the debugger, +etc. (me) + +- Shouldn't be able to delete part of the prompt (or any text before +it) in the PyShell. (Martijn Faassen) DONE + +- Emacs style auto-fill (also smart about comments and strings). +(Jeremy Hylton) + +- Output of Run Script should go to a separate output window, not to +the shell window. Output of separate runs should all go to the same +window but clearly delimited. (David Scherer) REJECT FIRST, LATTER DONE + +- GUI form designer to kick VB's butt. (Robert Geiger) THAT'S NOT IDLE + +- Printing! Possibly via generation of PDF files which the user must +then send to the printer separately. (Dinu Gherman) FIRST CUT diff --git a/PythonHome/Lib/idlelib/ToolTip.pyc b/PythonHome/Lib/idlelib/ToolTip.pyc new file mode 100644 index 0000000000000000000000000000000000000000..88c95e8842eaef8959e24521b81e8faad174ca16 GIT binary patch literal 4414 zcmd5<-EJF26rQymJ9d*2TAEb+x}p_s1A(RzLZS+&O^c8sx7t`j4Xsv=cN}lJ_L`k> zlZaFxxe`19&%gt5$s=&b1Hkv4*^Qm3ihRKZNoI0(e!ug7rug?_?e{-^+3u+9r-=Vw zqnV%3h4}MStW+y3sBl4rMfFOlu~JWVJQbFd_EZ%8;~iv7O1LZs=76ki7o?}Hnrt1@0tz>d#6q!7GQJ&eA zt<)_6gA!hpdI^S$SzsaC{6J6>F&r0Ex1g3~7?;iSC}(~|)r{UkA5lJr;b8Sfh`$Ey z+81$&b<&s+5xPl`CW$?iU_ALgvJ|5G?&)Z+XT@b($uQP0bZqG$2mK&`oW$~`r4-M6k1OwK~x!7(+~i3OrOwvT9-s5doZgxUBQ;?Xohx0wUp*Adv$Nw zTl7{ui6c*vQChe9(AIlECUK;QrR3;7n)wo)%@sk{fXzV%a1+FLxW=5aAS7#yy*a1{ z@^<=iLZ&@5CGPPO@sRzIu~GNP(&u;Eo#%ULG8%*uus`hLM}H=fIYk`QU6Imml0t3= zh{Qcnm3W}|-Bx>7$D%2@W9z}gmW*#d+WK}=hK9JIL6*c1{SU|wEj#AUS>^a1HmswG zji|y^?}{_-Q;s=_Cube=2F2!#T(bPcB?Xx1nUshp)W)XC(Uc?7v1Ua|WBYuFR0qBoBt%B;XwDw2LV-;n`v<6JF0}lk)otEeqUBugNznn4Ta5L_|G+ z3(r^s*>|!QO!CPfFe?%YK*UELl;@(zEs*{yJ5e;(OwJSPeD*%Zh7B}fuk2NemXNk0 zV|SCo|APX>rz5NT=ByUiPVss^n-tE&oK59rTBNDaN5#Ir0WlpA5e>(l$Gmmo;)mBH zLlxELvt`AQC@BmGVTaWC4>#3!qIDkJ^sk|xj(!bBd-04+zAh7egi)W&NOX(_1_cLV zuTl@1n-iX8U+nZE@sBc@sQP^NX%^q2Wx?YL%BH3N$bdc}P##S|(ttWNY{nXLE0X;S z1SC5~K6lbYs&Qou(hWETJCNb2=L1%YNRi#2mMCge0xv;8)R4I=0q|>QFl)nBg%7+o%-$Rk99*!YxN>i$6t1v%l+LX-+p^dOfg#}FQ@*9uwq@0 zqk$H<(|Zk5#bp0_gIr0O(t0jVX(JoE2NBIuEVkbs%KvC!Wo4>mr5VPNtDW+i$iGg$ zY58LGjw_$R$frR`M(ekuL7XH*DcWS&u$`iQ66Oy+ho_3Gnt5 zy*{JoxYU}7ReMi$VrWK8fu;2vf4<#aS?x;y9bB}iJ& zAts%=Ty?^_zlnLDVcjyXWY5Mm{tqmyX|2cJXE2-aAk?`bKw#Z5Q;Nh|;qvFp MmE~G>X#oM@U)vJ;NdN!< literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/idlelib/TreeWidget.pyc b/PythonHome/Lib/idlelib/TreeWidget.pyc new file mode 100644 index 0000000000000000000000000000000000000000..993dfce69922be29c697ade936e46e867ba1d329 GIT binary patch literal 16916 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 O%)<2JIH|;D=l=mBj^R)M literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/idlelib/UndoDelegator.pyc b/PythonHome/Lib/idlelib/UndoDelegator.pyc new file mode 100644 index 0000000000000000000000000000000000000000..d392d2606d257cf15c75eee80d38af806d324c02 GIT binary patch literal 12790 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 BN*DkD literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/idlelib/WidgetRedirector.pyc b/PythonHome/Lib/idlelib/WidgetRedirector.pyc new file mode 100644 index 0000000000000000000000000000000000000000..4fb60b164d61ed1cc92083885bf8115f22261216 GIT binary patch literal 5341 zcmbVQ-EP~+6&^~mY$^8UuT8ow3QVx|T25R6MbVog4R+Vrrok?pf->ON^@63zkwl9k zRdQsJ zRehTH{|r|-L=)rZsZ^=MxS`^%iks?NrQRv^`(sbVEfwEU@!H}MrnGr;+*Af*>uS``D~UK zRuA(+7uC*5Hqv2nn%E*NF7<_QrOWwgluxH&7MJ~QSK~9tr$!%6bUrghXp=lEb)08A zR%dxJ4b${e&%(0Qc3kB1(HJw6%$lOF^{=s)c^gh=soB%XP=`V;8iz#~VTMjhon)mc ztclUFxeoQAd24GXZWhrdxiMiavgxCzjd1|qX5Iaq>nB!P%$EI4jQ|cW@cxTBp zcf+>Hd5G;mDT`$VGLvc*S9jMxIKDRo8u-xo4j3$oZT2=?t=PBm_ zf>5vU_53Sy`9eqeJdO3K(bF(C`aFTC4yQeRF%BWKfm#I2i!igo3uKCOvW?C-&nGp% z-zA$ZO**Xfbu=~^Sg7>rK(-*7RFdn%C`LCq|e)4~rz9mqM>%YiUe-+Vn^L8tWbn^ndJN zx37=DL1FYLuT)Jm97L;oQ>D<~c>;h#Jq)8HP3)!a?G$E|lrXrRUB?%?k(pUx&9NiI z7A#dbzRvXPmtTLmC-a8$491gZP$8M9NkY_WOIjCAr#3~K&vahf{BN;io`&#s4f9Vj z!1lS@|1`HYpK>M*P6owN#n@_Ed6A5gEKG$>SnN#oi$X8PaEpGA@@yn-BediMw-VQXsN4)IzxEDFb0%5YpHil8<1PuMz1h5mfi-s_Ku7!B8ZGTF)X>Z6Zs1+Ecq7-?9k)v7CU02m6cgi zjFS@P7>#?JC#&cJJ~{BYxy0Lx9(qce@(FtVldqH0lO#?Joc`qKMjYYrH zzFof96*+``+rhLTh*Ct=AgDMZl0o1zo=ZCMnO#0my28wgAovsnN`j}nyPn8I*!VzX z`ZGFjf1<2d4`f1Sd-=^nb?w9yqhYf9(>--WSz$kTrqmy6W1%_Wwzi{d*J-QkHFece zXY1-}jWj*pYzTT-fJd;gmjW0?OMW3Qmeh-cE9(nh@j%vG0EGVK-ycSsh6gO}z zXEX55=P+L02+9~BC|2;qAY5)BCUD?PM(~h4Z)|97;cVzGNWQ7U#=Z;A;-ezE|9y;# zVbx*ny+tM1HT=Ioza*~8+wvZI5{7CS_c?Zi#zi0a$E2-_H%nPRc6NgS%=p!+;1IO< zN;$b56pS{gu7JpZHo~hyLfn3V#5gRMNDvy>0UwAF9pst00fqlD=DaTi{zEMKC9Wz& z+=cL6?*Ra4H3R~(L%v>d&IuZ)U-%NW=rQ14{*0lt*p`6WP=AF$PVew1cHlG~BM2mZ zj1_~U?15?_%1*kfI8vVHA?gf%hZyYwaM^;_>?3AMg)%IVSeWZC#z{2R#ThRb1B)hR2{*>iAvN}vl$A)x_BTdM6o=Q z+C$gYR_C>_7?n~y3N_RW;I^;dV0Ceklqedj!qQbDB(~TJTexzQt0q!VQLH*sirn>f zD{>v=mL&-aF4m)~($tfsA_9ag5`|)&vpA6Dt~4VnU<(5C}S2mt0^7DZmTXu`DO!UNZlBT1yw_x27Z{Fk_#cWgfJnqJ%M zHlDysB%u2|30cPRAeiRyJVko5^wl7U^9ZSqiPyi+<`EkvV{tj3l$Y#C?{>-Euama$ z)P97ZyxD1W?sV2VU7xu*!X+P0`~p|`2^v!$#J>GMXEB_!i0>k^{gOXN!XiBSZ7TZ$q{^9MjZv=v8+cAF0-!MDEB{e;j%W|cp zDMIj9knz=T00{n(o>yv9Il{Qt3}P7aY6mYY&Uw@gY?KDWD3cNYgA9XOnO@>3!Z##y zveZID_wsk~-(!U*ho-}cgaMn_)cACBXbDThnf&9$ip)Y1qDhs=D^`qdWbj_c7MD^K z@x6<5W_Y(DmGLl-AV!ItA)Y4T_bG{Q2=OFK^L*w?bK1@f2XyR27KPChUrVAzMVZ=${Ju3B(|V_riL`eU~K jXBb1nB_dEACaSHt}l<=-A literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/idlelib/WindowList.pyc b/PythonHome/Lib/idlelib/WindowList.pyc new file mode 100644 index 0000000000000000000000000000000000000000..7570f208dde14a3b2670a0f5d5418a3019b0ac36 GIT binary patch literal 3411 zcmbVO>uwuG6h5tttK z$5QgEybABYd+`A9eP``BElA*|o$=YZoa=Yanefln${(Fyw!1R@3-S8}hWiOqivLD( zk)1Satsx6m&y+M$-D(O|WUmc6%B8 zv%m1yHlRGG5B&<}PFAGD@x#pdGo`qB55sL@vJeV}LWYnI1xbVg6-m^lT2|7z(wIu$ zRmoggmT0@Z1YTWo<_IwEW4J4rGLaLJSY*E&};I zWTY1xSQ%?X7O;nGk~F1rrlzdUO`(Bm%4Z-ZYpS{epi=#Ar?@CJA4q>i%4=ebDU3X# zeIfB?Ua(B{j_5%3;sZPRsw{_P#OTh=h^Wc}2GHu%!cn#b$`O`gLbGOCL9MccCpgrS z-$4K?r-2;*Jhg|R5!rbBt(+n#&>jH`<&D#tOjhNj#%N*xv@V@u4d#Yw?sqiz=!&St z$f}y0)Oomv!-z9>Iwx4Jt0RtY2tGC*UzNRpjKG?}0NMcuq+Xz6mT)#ON5|4p$A!>z z%QFOd^2FwzZt4yPgQQ3`BP$p%@_jpT3h#aEW1o3AgI?b0=IUTiToxP8yNY4u(&ymV_UYd}KAAb88}2 zs|Bo}^GC%$?6`_$N5o7M$7rpkVFZA>djrJr-Kobn9)B#SMkW{3@wnAFT46c>&70^B z$d^q(TFFp0zsBYxjB}`V?}ObqDT}Pwzr8+l=Xx*6a+|Ja#rnMFYPY$ql~LoV2z0791*f`dh#PML5j&giP zjC;i56Y*~JCa1SKy~9aM9Eb&i6|p4{2#y_~5j1P~x7=(s!)8O90^6=lcZP?#eQNVA z4(T7S-NSI7VzTI<3pQZ1TiT-SjN%D_2N>=KCXec<9Sj+ViuNoNgYu7Zk5tt5rb!v2 zvCo?txmEROs;c@*S1Kfy6Lp*#)f;w4&ZhA=OHs_)RAAoR1_{#-0#Sp;{~z`$?+z|G zRyIL7X;lb+?ltiVw$99>EzcRootn5?ngLZ&FZ9thYu#EjsZ$mIYvjhLrxs0mIGGpg zqfzFy-K$*-SiyqwCB`&UTc#DBdv(y3``jg3Dm$LR)^l;7+alFa(Wsvc?xGEs&>kJ8 ziMNOn-+ycj@hp_zV0Ts%sncwzZp@FWXhXM|=XgTVFdkIR>!rN23N8;ZD%pWnFmfjP zRQ4W-$;Mnfid8?5^180*3&2n{?ezw+Mjv2P3!COd?5vO2g4uGVI#WAi7tzXw&*4&UWv$Hj#Z`p>!}>E$lu1$HyH|8 z9px)**0w4>%h*wSclud@wAOl8;q!&!$y`!q3o4+#zf)D{&xr*s>np+KTg{+}7ke}O E8v!<0-~a#s literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/idlelib/ZoomHeight.pyc b/PythonHome/Lib/idlelib/ZoomHeight.pyc new file mode 100644 index 0000000000000000000000000000000000000000..75b3692f572c184d9667a698dda82dd7fda8b5e5 GIT binary patch literal 1571 zcmb7E&2G~`5T3Q2q-j(2Pbw7%2@XX@r9HIQs{CDgKs`7}KorS@?51_hnAjNEbn-Bc6NTg{nq}k#rf}V-Z#56dwhJKVc0_mjaN}h)VkCa zwUpRBNvRiy-W&}E z#n8EVSXxDq9h&6$#9b@r1(xg+2m_Zgd4-M@^*oj>kC2{op$Mq}*`sDy#RkWD&yrjh zXVx~L$DHCpnZqu@u)qHqmhBVCdT`M7VEa2>LbqJ$M9~C$1%swEFl&Ru8=W|$2zi$a zc#BDU5yKc_l)~PFw$px+H7UMVz3vRgZVu~loaBj%<7McUqmhzwI22E%oV!p^ zOCPVIsYlMEiANU-XF$N2!95Cjhg9HLbH%_d;LDB1Wuv7B7wakz=99@?#DM)r$t%}G z#u8)=M$2(YHIzVdE7(J>Vg^Fq$xIvzAL2MG^eE*i1C*J3q)pF8>>br1uF4hdCYU3J zha*`QRo_=jLEZ1NmFdS}1>~PlN{}yzriz@RK3E18D7x?%c3^II#m8sD3-~yEpox`! zm2Gfr2Q>9*3R$6PRorX5G_7&7{W@unPCXiaVFpjdz1PVbr{bhdml1v z>#fJ*uTa2RBnZJYXhQ*X%|^34+po@Mc|DKg`R zV-Odu83~tlT=zuo&IgmGLfWh|kZ+PZ$HY7y7Ndc6t5A`=SH!kEG$t?UES`33g(ZWu z<9fv~i{M&vDzVQ$jykVTLq24ox#Z$XaI)altS9YGB-bn`FP)3S*fBV{Ih(C8!7&@l z?*$4+5(0|2k%j!%xPxIILGVRcRaG^w0`(C367)r{5mePmQ1#|vse9|HjLtwr{CkLa myJVmJPNZ3(cf`@Jin&!qg4=$1*A9H_m;2FB4R6_7Tlxd;jw+r2 literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/idlelib/__init__.pyc b/PythonHome/Lib/idlelib/__init__.pyc new file mode 100644 index 0000000000000000000000000000000000000000..e56d5ddf451eff22316099eee1af91af8e13a155 GIT binary patch literal 112 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 Ur1ayNf;FAtL*U}eX=~2>= (See [CodeContext], below.) +# +# Currently it is necessary to manually modify this file to change extension +# key bindings and default values. To customize, create +# ~/.idlerc/config-extensions.cfg and append the appropriate customized +# section(s). Those sections will override the defaults in this file. +# +# Note: If a keybinding is already in use when the extension is +# loaded, the extension's virtual event's keybinding will be set to ''. +# +# See config-keys.def for notes on specifying keys and extend.txt for +# information on creating IDLE extensions. + +[FormatParagraph] +enable=1 +[FormatParagraph_cfgBindings] +format-paragraph= + +[AutoExpand] +enable=1 +[AutoExpand_cfgBindings] +expand-word= + +[ZoomHeight] +enable=1 +[ZoomHeight_cfgBindings] +zoom-height= + +[ScriptBinding] +enable=1 +enable_shell=0 +enable_editor=1 +[ScriptBinding_cfgBindings] +run-module= +check-module= + +[CallTips] +enable=1 +[CallTips_cfgBindings] +force-open-calltip= +[CallTips_bindings] +try-open-calltip= +refresh-calltip= + +[ParenMatch] +enable=1 +style= expression +flash-delay= 500 +bell= 1 +[ParenMatch_cfgBindings] +flash-paren= +[ParenMatch_bindings] +paren-closed= + +[AutoComplete] +enable=1 +popupwait=2000 +[AutoComplete_cfgBindings] +force-open-completions= +[AutoComplete_bindings] +autocomplete= +try-open-completions= + +[CodeContext] +enable=1 +enable_shell=0 +numlines=3 +visible=0 +bgcolor=LightGray +fgcolor=Black +[CodeContext_bindings] +toggle-code-context= + +[RstripExtension] +enable=1 +enable_shell=0 +enable_editor=1 + diff --git a/PythonHome/Lib/idlelib/config-highlight.def b/PythonHome/Lib/idlelib/config-highlight.def new file mode 100644 index 0000000000..7d20f78240 --- /dev/null +++ b/PythonHome/Lib/idlelib/config-highlight.def @@ -0,0 +1,64 @@ +# IDLE reads several config files to determine user preferences. This +# file is the default config file for idle highlight theme settings. + +[IDLE Classic] +normal-foreground= #000000 +normal-background= #ffffff +keyword-foreground= #ff7700 +keyword-background= #ffffff +builtin-foreground= #900090 +builtin-background= #ffffff +comment-foreground= #dd0000 +comment-background= #ffffff +string-foreground= #00aa00 +string-background= #ffffff +definition-foreground= #0000ff +definition-background= #ffffff +hilite-foreground= #000000 +hilite-background= gray +break-foreground= black +break-background= #ffff55 +hit-foreground= #ffffff +hit-background= #000000 +error-foreground= #000000 +error-background= #ff7777 +#cursor (only foreground can be set, restart IDLE) +cursor-foreground= black +#shell window +stdout-foreground= blue +stdout-background= #ffffff +stderr-foreground= red +stderr-background= #ffffff +console-foreground= #770000 +console-background= #ffffff + +[IDLE New] +normal-foreground= #000000 +normal-background= #ffffff +keyword-foreground= #ff7700 +keyword-background= #ffffff +builtin-foreground= #900090 +builtin-background= #ffffff +comment-foreground= #dd0000 +comment-background= #ffffff +string-foreground= #00aa00 +string-background= #ffffff +definition-foreground= #0000ff +definition-background= #ffffff +hilite-foreground= #000000 +hilite-background= gray +break-foreground= black +break-background= #ffff55 +hit-foreground= #ffffff +hit-background= #000000 +error-foreground= #000000 +error-background= #ff7777 +#cursor (only foreground can be set, restart IDLE) +cursor-foreground= black +#shell window +stdout-foreground= blue +stdout-background= #ffffff +stderr-foreground= red +stderr-background= #ffffff +console-foreground= #770000 +console-background= #ffffff diff --git a/PythonHome/Lib/idlelib/config-keys.def b/PythonHome/Lib/idlelib/config-keys.def new file mode 100644 index 0000000000..3bfcb69015 --- /dev/null +++ b/PythonHome/Lib/idlelib/config-keys.def @@ -0,0 +1,214 @@ +# IDLE reads several config files to determine user preferences. This +# file is the default config file for idle key binding settings. +# Where multiple keys are specified for an action: if they are separated +# by a space (eg. action= ) then the keys are alternatives, if +# there is no space (eg. action=) then the keys comprise a +# single 'emacs style' multi-keystoke binding. The tk event specifier 'Key' +# is used in all cases, for consistency in auto key conflict checking in the +# configuration gui. + +[IDLE Classic Windows] +copy= +cut= +paste= +beginning-of-line= +center-insert= +close-all-windows= +close-window= +do-nothing= +end-of-file= +python-docs= +python-context-help= +history-next= +history-previous= +interrupt-execution= +view-restart= +restart-shell= +open-class-browser= +open-module= +open-new-window= +open-window-from-file= +plain-newline-and-indent= +print-window= +redo= +remove-selection= +save-copy-of-window-as-file= +save-window-as-file= +save-window= +select-all= +toggle-auto-coloring= +undo= +find= +find-again= +find-in-files= +find-selection= +replace= +goto-line= +smart-backspace= +newline-and-indent= +smart-indent= +indent-region= +dedent-region= +comment-region= +uncomment-region= +tabify-region= +untabify-region= +toggle-tabs= +change-indentwidth= +del-word-left= +del-word-right= + +[IDLE Classic Unix] +copy= +cut= +paste= +beginning-of-line= +center-insert= +close-all-windows= +close-window= +do-nothing= +end-of-file= +history-next= +history-previous= +interrupt-execution= +view-restart= +restart-shell= +open-class-browser= +open-module= +open-new-window= +open-window-from-file= +plain-newline-and-indent= +print-window= +python-docs= +python-context-help= +redo= +remove-selection= +save-copy-of-window-as-file= +save-window-as-file= +save-window= +select-all= +toggle-auto-coloring= +undo= +find= +find-again= +find-in-files= +find-selection= +replace= +goto-line= +smart-backspace= +newline-and-indent= +smart-indent= +indent-region= +dedent-region= +comment-region= +uncomment-region= +tabify-region= +untabify-region= +toggle-tabs= +change-indentwidth= +del-word-left= +del-word-right= + +[IDLE Classic Mac] +copy= +cut= +paste= +beginning-of-line= +center-insert= +close-all-windows= +close-window= +do-nothing= +end-of-file= +python-docs= +python-context-help= +history-next= +history-previous= +interrupt-execution= +view-restart= +restart-shell= +open-class-browser= +open-module= +open-new-window= +open-window-from-file= +plain-newline-and-indent= +print-window= +redo= +remove-selection= +save-window-as-file= +save-window= +save-copy-of-window-as-file= +select-all= +toggle-auto-coloring= +undo= +find= +find-again= +find-in-files= +find-selection= +replace= +goto-line= +smart-backspace= +newline-and-indent= +smart-indent= +indent-region= +dedent-region= +comment-region= +uncomment-region= +tabify-region= +untabify-region= +toggle-tabs= +change-indentwidth= +del-word-left= +del-word-right= + +[IDLE Classic OSX] +toggle-tabs = +interrupt-execution = +untabify-region = +remove-selection = +print-window = +replace = +goto-line = +plain-newline-and-indent = +history-previous = +beginning-of-line = +end-of-line = +comment-region = +redo = +close-window = +restart-shell = +save-window-as-file = +close-all-windows = +view-restart = +tabify-region = +find-again = +find = +toggle-auto-coloring = +select-all = +smart-backspace = +change-indentwidth = +do-nothing = +smart-indent = +center-insert = +history-next = +del-word-right = +undo = +save-window = +uncomment-region = +cut = +find-in-files = +dedent-region = +copy = +paste = +indent-region = +del-word-left = +newline-and-indent = +end-of-file = +open-class-browser = +open-new-window = +open-module = +find-selection = +python-context-help = +save-copy-of-window-as-file = +open-window-from-file = +python-docs = + diff --git a/PythonHome/Lib/idlelib/config-main.def b/PythonHome/Lib/idlelib/config-main.def new file mode 100644 index 0000000000..132797ce32 --- /dev/null +++ b/PythonHome/Lib/idlelib/config-main.def @@ -0,0 +1,79 @@ +# IDLE reads several config files to determine user preferences. This +# file is the default config file for general idle settings. +# +# When IDLE starts, it will look in +# the following two sets of files, in order: +# +# default configuration +# --------------------- +# config-main.def the default general config file +# config-extensions.def the default extension config file +# config-highlight.def the default highlighting config file +# config-keys.def the default keybinding config file +# +# user configuration +# ------------------- +# ~/.idlerc/config-main.cfg the user general config file +# ~/.idlerc/config-extensions.cfg the user extension config file +# ~/.idlerc/config-highlight.cfg the user highlighting config file +# ~/.idlerc/config-keys.cfg the user keybinding config file +# +# On Windows2000 and Windows XP the .idlerc directory is at +# Documents and Settings\\.idlerc +# +# On Windows98 it is at c:\.idlerc +# +# Any options the user saves through the config dialog will be saved to +# the relevant user config file. Reverting any general setting to the +# default causes that entry to be wiped from the user file and re-read +# from the default file. User highlighting themes or keybinding sets are +# retained unless specifically deleted within the config dialog. Choosing +# one of the default themes or keysets just applies the relevant settings +# from the default file. +# +# Additional help sources are listed in the [HelpFiles] section and must be +# viewable by a web browser (or the Windows Help viewer in the case of .chm +# files). These sources will be listed on the Help menu. The pattern is +# +# You can't use a semi-colon in a menu item or path. The path will be platform +# specific because of path separators, drive specs etc. +# +# It is best to use the Configuration GUI to set up additional help sources! +# Example: +#1 = My Extra Help Source;/usr/share/doc/foo/index.html +#2 = Another Help Source;/path/to/another.pdf + +[General] +editor-on-startup= 0 +autosave= 0 +print-command-posix=lpr %s +print-command-win=start /min notepad /p %s +delete-exitfunc= 1 + +[EditorWindow] +width= 80 +height= 40 +font= courier +font-size= 10 +font-bold= 0 +encoding= none + +[FormatParagraph] +paragraph=72 + +[Indent] +use-spaces= 1 +num-spaces= 4 + +[Theme] +default= 1 +name= IDLE Classic + +[Keys] +default= 1 +name= IDLE Classic Windows + +[History] +cyclic=1 + +[HelpFiles] diff --git a/PythonHome/Lib/idlelib/configDialog.pyc b/PythonHome/Lib/idlelib/configDialog.pyc new file mode 100644 index 0000000000000000000000000000000000000000..4d8a8c1ad02b50663b7c9f1e2e4b171525419e14 GIT binary patch literal 43516 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�s>O6;%xa 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 literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/idlelib/configHandler.pyc b/PythonHome/Lib/idlelib/configHandler.pyc new file mode 100644 index 0000000000000000000000000000000000000000..ca3dead51a7091d83c49cc41a2897b7e8821ec93 GIT binary patch literal 26737 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

    40n0 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 literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/idlelib/extend.txt b/PythonHome/Lib/idlelib/extend.txt new file mode 100644 index 0000000000..c9cb2e8297 --- /dev/null +++ b/PythonHome/Lib/idlelib/extend.txt @@ -0,0 +1,83 @@ +Writing an IDLE extension +========================= + +An IDLE extension can define new key bindings and menu entries for IDLE +edit windows. There is a simple mechanism to load extensions when IDLE +starts up and to attach them to each edit window. (It is also possible +to make other changes to IDLE, but this must be done by editing the IDLE +source code.) + +The list of extensions loaded at startup time is configured by editing +the file config-extensions.def. See below for details. + +An IDLE extension is defined by a class. Methods of the class define +actions that are invoked by event bindings or menu entries. Class (or +instance) variables define the bindings and menu additions; these are +automatically applied by IDLE when the extension is linked to an edit +window. + +An IDLE extension class is instantiated with a single argument, +`editwin', an EditorWindow instance. The extension cannot assume much +about this argument, but it is guaranteed to have the following instance +variables: + + text a Text instance (a widget) + io an IOBinding instance (more about this later) + flist the FileList instance (shared by all edit windows) + +(There are a few more, but they are rarely useful.) + +The extension class must not directly bind Window Manager (e.g. X) events. +Rather, it must define one or more virtual events, e.g. <>, and +corresponding methods, e.g. zoom_height_event(). The virtual events will be +bound to the corresponding methods, and Window Manager events can then be bound +to the virtual events. (This indirection is done so that the key bindings can +easily be changed, and so that other sources of virtual events can exist, such +as menu entries.) + +An extension can define menu entries. This is done with a class or instance +variable named menudefs; it should be a list of pairs, where each pair is a +menu name (lowercase) and a list of menu entries. Each menu entry is either +None (to insert a separator entry) or a pair of strings (menu_label, +virtual_event). Here, menu_label is the label of the menu entry, and +virtual_event is the virtual event to be generated when the entry is selected. +An underscore in the menu label is removed; the character following the +underscore is displayed underlined, to indicate the shortcut character (for +Windows). + +At the moment, extensions cannot define whole new menus; they must define +entries in existing menus. Some menus are not present on some windows; such +entry definitions are then ignored, but key bindings are still applied. (This +should probably be refined in the future.) + +Extensions are not required to define menu entries for all the events they +implement. (They are also not required to create keybindings, but in that +case there must be empty bindings in cofig-extensions.def) + +Here is a complete example: + +class ZoomHeight: + + menudefs = [ + ('edit', [ + None, # Separator + ('_Zoom Height', '<>'), + ]) + ] + + def __init__(self, editwin): + self.editwin = editwin + + def zoom_height_event(self, event): + "...Do what you want here..." + +The final piece of the puzzle is the file "config-extensions.def", which is +used to configure the loading of extensions and to establish key (or, more +generally, event) bindings to the virtual events defined in the extensions. + +See the comments at the top of config-extensions.def for information. It's +currently necessary to manually modify that file to change IDLE's extension +loading or extension key bindings. + +For further information on binding refer to the Tkinter Resources web page at +python.org and to the Tk Command "bind" man page. diff --git a/PythonHome/Lib/idlelib/help.txt b/PythonHome/Lib/idlelib/help.txt new file mode 100644 index 0000000000..bd6822c423 --- /dev/null +++ b/PythonHome/Lib/idlelib/help.txt @@ -0,0 +1,302 @@ +[See the end of this file for ** TIPS ** on using IDLE !!] + +Click on the dotted line at the top of a menu to "tear it off": a +separate window containing the menu is created. + +File Menu: + + New File -- Create a new editing window + Open... -- Open an existing file + Recent Files... -- Open a list of recent files + Open Module... -- Open an existing module (searches sys.path) + Class Browser -- Show classes and methods in current file + Path Browser -- Show sys.path directories, modules, classes + and methods + --- + Save -- Save current window to the associated file (unsaved + windows have a * before and after the window title) + + Save As... -- Save current window to new file, which becomes + the associated file + Save Copy As... -- Save current window to different file + without changing the associated file + --- + Print Window -- Print the current window + --- + Close -- Close current window (asks to save if unsaved) + Exit -- Close all windows, quit (asks to save if unsaved) + +Edit Menu: + + Undo -- Undo last change to current window + (A maximum of 1000 changes may be undone) + Redo -- Redo last undone change to current window + --- + Cut -- Copy a selection into system-wide clipboard, + then delete the selection + Copy -- Copy selection into system-wide clipboard + Paste -- Insert system-wide clipboard into window + Select All -- Select the entire contents of the edit buffer + --- + Find... -- Open a search dialog box with many options + Find Again -- Repeat last search + Find Selection -- Search for the string in the selection + Find in Files... -- Open a search dialog box for searching files + Replace... -- Open a search-and-replace dialog box + Go to Line -- Ask for a line number and show that line + Show Calltip -- Open a small window with function param hints + Show Completions -- Open a scroll window allowing selection keywords + and attributes. (see '*TIPS*', below) + Show Parens -- Highlight the surrounding parenthesis + Expand Word -- Expand the word you have typed to match another + word in the same buffer; repeat to get a + different expansion + +Format Menu (only in Edit window): + + Indent Region -- Shift selected lines right 4 spaces + Dedent Region -- Shift selected lines left 4 spaces + Comment Out Region -- Insert ## in front of selected lines + Uncomment Region -- Remove leading # or ## from selected lines + Tabify Region -- Turns *leading* stretches of spaces into tabs + (Note: We recommend using 4 space blocks to indent Python code.) + Untabify Region -- Turn *all* tabs into the right number of spaces + New Indent Width... -- Open dialog to change indent width + Format Paragraph -- Reformat the current blank-line-separated + paragraph + +Run Menu (only in Edit window): + + Python Shell -- Open or wake up the Python shell window + --- + Check Module -- Run a syntax check on the module + Run Module -- Execute the current file in the __main__ namespace + +Shell Menu (only in Shell window): + + View Last Restart -- Scroll the shell window to the last restart + Restart Shell -- Restart the interpreter with a fresh environment + +Debug Menu (only in Shell window): + + Go to File/Line -- look around the insert point for a filename + and line number, open the file, and show the line + Debugger (toggle) -- Run commands in the shell under the debugger + Stack Viewer -- Show the stack traceback of the last exception + Auto-open Stack Viewer (toggle) -- Open stack viewer on traceback + +Options Menu: + + Configure IDLE -- Open a configuration dialog. Fonts, indentation, + keybindings, and color themes may be altered. + Startup Preferences may be set, and Additional Help + Sources can be specified. + + On OS X this menu is not present, use + menu 'IDLE -> Preferences...' instead. + --- + Code Context -- Open a pane at the top of the edit window which + shows the block context of the section of code + which is scrolling off the top or the window. + (Not present in Shell window.) + +Windows Menu: + + Zoom Height -- toggles the window between configured size + and maximum height. + --- + The rest of this menu lists the names of all open windows; + select one to bring it to the foreground (deiconifying it if + necessary). + +Help Menu: + + About IDLE -- Version, copyright, license, credits + IDLE Readme -- Background discussion and change details + --- + IDLE Help -- Display this file + Python Docs -- Access local Python documentation, if + installed. Otherwise, access www.python.org. + --- + (Additional Help Sources may be added here) + +Edit context menu (Right-click / Control-click on OS X in Edit window): + + Cut -- Copy a selection into system-wide clipboard, + then delete the selection + Copy -- Copy selection into system-wide clipboard + Paste -- Insert system-wide clipboard into window + Set Breakpoint -- Sets a breakpoint (when debugger open) + Clear Breakpoint -- Clears the breakpoint on that line + +Shell context menu (Right-click / Control-click on OS X in Shell window): + + Cut -- Copy a selection into system-wide clipboard, + then delete the selection + Copy -- Copy selection into system-wide clipboard + Paste -- Insert system-wide clipboard into window + --- + Go to file/line -- Same as in Debug menu + + +** TIPS ** +========== + +Additional Help Sources: + + Windows users can Google on zopeshelf.chm to access Zope help files in + the Windows help format. The Additional Help Sources feature of the + configuration GUI supports .chm, along with any other filetypes + supported by your browser. Supply a Menu Item title, and enter the + location in the Help File Path slot of the New Help Source dialog. Use + http:// and/or www. to identify external URLs, or download the file and + browse for its path on your machine using the Browse button. + + All users can access the extensive sources of help, including + tutorials, available at www.python.org/doc. Selected URLs can be added + or removed from the Help menu at any time using Configure IDLE. + +Basic editing and navigation: + + Backspace deletes char to the left; DEL deletes char to the right. + Control-backspace deletes word left, Control-DEL deletes word right. + Arrow keys and Page Up/Down move around. + Control-left/right Arrow moves by words in a strange but useful way. + Home/End go to begin/end of line. + Control-Home/End go to begin/end of file. + Some useful Emacs bindings are inherited from Tcl/Tk: + Control-a beginning of line + Control-e end of line + Control-k kill line (but doesn't put it in clipboard) + Control-l center window around the insertion point + Standard Windows bindings may work on that platform. + Keybindings are selected in the Settings Dialog, look there. + +Automatic indentation: + + After a block-opening statement, the next line is indented by 4 spaces + (in the Python Shell window by one tab). After certain keywords + (break, return etc.) the next line is dedented. In leading + indentation, Backspace deletes up to 4 spaces if they are there. Tab + inserts spaces (in the Python Shell window one tab), number depends on + Indent Width. (N.B. Currently tabs are restricted to four spaces due + to Tcl/Tk issues.) + + See also the indent/dedent region commands in the edit menu. + +Completions: + + Completions are supplied for functions, classes, and attributes of + classes, both built-in and user-defined. Completions are also provided + for filenames. + + The AutoCompleteWindow (ACW) will open after a predefined delay + (default is two seconds) after a '.' or (in a string) an os.sep is + typed. If after one of those characters (plus zero or more other + characters) you type a Tab the ACW will open immediately if a possible + continuation is found. + + If there is only one possible completion for the characters entered, a + Tab will supply that completion without opening the ACW. + + 'Show Completions' will force open a completions window. In an empty + string, this will contain the files in the current directory. On a + blank line, it will contain the built-in and user-defined functions and + classes in the current name spaces, plus any modules imported. If some + characters have been entered, the ACW will attempt to be more specific. + + If string of characters is typed, the ACW selection will jump to the + entry most closely matching those characters. Entering a Tab will cause + the longest non-ambiguous match to be entered in the Edit window or + Shell. Two Tabs in a row will supply the current ACW selection, as + will Return or a double click. Cursor keys, Page Up/Down, mouse + selection, and the scrollwheel all operate on the ACW. + + 'Hidden' attributes can be accessed by typing the beginning of hidden + name after a '.'. e.g. '_'. This allows access to modules with + '__all__' set, or to class-private attributes. + + Completions and the 'Expand Word' facility can save a lot of typing! + + Completions are currently limited to those in the namespaces. Names in + an Edit window which are not via __main__ or sys.modules will not be + found. Run the module once with your imports to correct this + situation. Note that IDLE itself places quite a few modules in + sys.modules, so much can be found by default, e.g. the re module. + + If you don't like the ACW popping up unbidden, simply make the delay + longer or disable the extension. OTOH, you could make the delay zero. + + You could also switch off the CallTips extension. (We will be adding + a delay to the call tip window.) + +Python Shell window: + + Control-c interrupts executing command. + Control-d sends end-of-file; closes window if typed at >>> prompt. + + Command history: + + Alt-p retrieves previous command matching what you have typed. + Alt-n retrieves next. + (These are Control-p, Control-n on OS X) + Return while cursor is on a previous command retrieves that command. + Expand word is also useful to reduce typing. + + Syntax colors: + + The coloring is applied in a background "thread", so you may + occasionally see uncolorized text. To change the color + scheme, use the Configure IDLE / Highlighting dialog. + + Python default syntax colors: + + Keywords orange + Builtins royal purple + Strings green + Comments red + Definitions blue + + Shell default colors: + + Console output brown + stdout blue + stderr red + stdin black + +Other preferences: + + The font preferences, keybinding, and startup preferences can + be changed using the Settings dialog. + +Command line usage: + + Enter idle -h at the command prompt to get a usage message. + +Running without a subprocess: + + If IDLE is started with the -n command line switch it will run in a + single process and will not create the subprocess which runs the RPC + Python execution server. This can be useful if Python cannot create + the subprocess or the RPC socket interface on your platform. However, + in this mode user code is not isolated from IDLE itself. Also, the + environment is not restarted when Run/Run Module (F5) is selected. If + your code has been modified, you must reload() the affected modules and + re-import any specific items (e.g. from foo import baz) if the changes + are to take effect. For these reasons, it is preferable to run IDLE + with the default subprocess if at all possible. + +Extensions: + + IDLE contains an extension facility. See the beginning of + config-extensions.def in the idlelib directory for further information. + The default extensions are currently: + + FormatParagraph + AutoExpand + ZoomHeight + ScriptBinding + CallTips + ParenMatch + AutoComplete + CodeContext diff --git a/PythonHome/Lib/idlelib/idle.bat b/PythonHome/Lib/idlelib/idle.bat new file mode 100644 index 0000000000..e77b96e9b5 --- /dev/null +++ b/PythonHome/Lib/idlelib/idle.bat @@ -0,0 +1,4 @@ +@echo off +rem Start IDLE using the appropriate Python interpreter +set CURRDIR=%~dp0 +start "IDLE" "%CURRDIR%..\..\pythonw.exe" "%CURRDIR%idle.pyw" %1 %2 %3 %4 %5 %6 %7 %8 %9 diff --git a/PythonHome/Lib/idlelib/idle.pyc b/PythonHome/Lib/idlelib/idle.pyc new file mode 100644 index 0000000000000000000000000000000000000000..da68244da04a996f802cd0afef7666c37499b03d GIT binary patch literal 391 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 Tnu=i%#2V$VaQcU%2nYNR-!mO& literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/idlelib/macosxSupport.pyc b/PythonHome/Lib/idlelib/macosxSupport.pyc new file mode 100644 index 0000000000000000000000000000000000000000..1c06608747bad34dc459e6fbc2734fce91ae3e68 GIT binary patch literal 8284 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 will probably be listening there. + +# NOTE WELL: You should also follow all the steps listed in PEP 306, +# "How to Change Python's Grammar" + +# Commands for Kees Blom's railroad program +#diagram:token NAME +#diagram:token NUMBER +#diagram:token STRING +#diagram:token NEWLINE +#diagram:token ENDMARKER +#diagram:token INDENT +#diagram:output\input python.bla +#diagram:token DEDENT +#diagram:output\textwidth 20.04cm\oddsidemargin 0.0cm\evensidemargin 0.0cm +#diagram:rules + +# Start symbols for the grammar: +# file_input is a module or sequence of commands read from an input file; +# single_input is a single interactive statement; +# eval_input is the input for the eval() and input() functions. +# NB: compound_stmt in single_input is followed by extra NEWLINE! +file_input: (NEWLINE | stmt)* ENDMARKER +single_input: NEWLINE | simple_stmt | compound_stmt NEWLINE +eval_input: testlist NEWLINE* ENDMARKER + +decorator: '@' dotted_name [ '(' [arglist] ')' ] NEWLINE +decorators: decorator+ +decorated: decorators (classdef | funcdef) +funcdef: 'def' NAME parameters ['->' test] ':' suite +parameters: '(' [typedargslist] ')' +typedargslist: ((tfpdef ['=' test] ',')* + ('*' [tname] (',' tname ['=' test])* [',' '**' tname] | '**' tname) + | tfpdef ['=' test] (',' tfpdef ['=' test])* [',']) +tname: NAME [':' test] +tfpdef: tname | '(' tfplist ')' +tfplist: tfpdef (',' tfpdef)* [','] +varargslist: ((vfpdef ['=' test] ',')* + ('*' [vname] (',' vname ['=' test])* [',' '**' vname] | '**' vname) + | vfpdef ['=' test] (',' vfpdef ['=' test])* [',']) +vname: NAME +vfpdef: vname | '(' vfplist ')' +vfplist: vfpdef (',' vfpdef)* [','] + +stmt: simple_stmt | compound_stmt +simple_stmt: small_stmt (';' small_stmt)* [';'] NEWLINE +small_stmt: (expr_stmt | print_stmt | del_stmt | pass_stmt | flow_stmt | + import_stmt | global_stmt | exec_stmt | assert_stmt) +expr_stmt: testlist_star_expr (augassign (yield_expr|testlist) | + ('=' (yield_expr|testlist_star_expr))*) +testlist_star_expr: (test|star_expr) (',' (test|star_expr))* [','] +augassign: ('+=' | '-=' | '*=' | '@=' | '/=' | '%=' | '&=' | '|=' | '^=' | + '<<=' | '>>=' | '**=' | '//=') +# For normal assignments, additional restrictions enforced by the interpreter +print_stmt: 'print' ( [ test (',' test)* [','] ] | + '>>' test [ (',' test)+ [','] ] ) +del_stmt: 'del' exprlist +pass_stmt: 'pass' +flow_stmt: break_stmt | continue_stmt | return_stmt | raise_stmt | yield_stmt +break_stmt: 'break' +continue_stmt: 'continue' +return_stmt: 'return' [testlist] +yield_stmt: yield_expr +raise_stmt: 'raise' [test ['from' test | ',' test [',' test]]] +import_stmt: import_name | import_from +import_name: 'import' dotted_as_names +import_from: ('from' ('.'* dotted_name | '.'+) + 'import' ('*' | '(' import_as_names ')' | import_as_names)) +import_as_name: NAME ['as' NAME] +dotted_as_name: dotted_name ['as' NAME] +import_as_names: import_as_name (',' import_as_name)* [','] +dotted_as_names: dotted_as_name (',' dotted_as_name)* +dotted_name: NAME ('.' NAME)* +global_stmt: ('global' | 'nonlocal') NAME (',' NAME)* +exec_stmt: 'exec' expr ['in' test [',' test]] +assert_stmt: 'assert' test [',' test] + +compound_stmt: if_stmt | while_stmt | for_stmt | try_stmt | with_stmt | funcdef | classdef | decorated +if_stmt: 'if' test ':' suite ('elif' test ':' suite)* ['else' ':' suite] +while_stmt: 'while' test ':' suite ['else' ':' suite] +for_stmt: 'for' exprlist 'in' testlist ':' suite ['else' ':' suite] +try_stmt: ('try' ':' suite + ((except_clause ':' suite)+ + ['else' ':' suite] + ['finally' ':' suite] | + 'finally' ':' suite)) +with_stmt: 'with' with_item (',' with_item)* ':' suite +with_item: test ['as' expr] +with_var: 'as' expr +# NB compile.c makes sure that the default except clause is last +except_clause: 'except' [test [(',' | 'as') test]] +suite: simple_stmt | NEWLINE INDENT stmt+ DEDENT + +# Backward compatibility cruft to support: +# [ x for x in lambda: True, lambda: False if x() ] +# even while also allowing: +# lambda x: 5 if x else 2 +# (But not a mix of the two) +testlist_safe: old_test [(',' old_test)+ [',']] +old_test: or_test | old_lambdef +old_lambdef: 'lambda' [varargslist] ':' old_test + +test: or_test ['if' or_test 'else' test] | lambdef +or_test: and_test ('or' and_test)* +and_test: not_test ('and' not_test)* +not_test: 'not' not_test | comparison +comparison: expr (comp_op expr)* +comp_op: '<'|'>'|'=='|'>='|'<='|'<>'|'!='|'in'|'not' 'in'|'is'|'is' 'not' +star_expr: '*' expr +expr: xor_expr ('|' xor_expr)* +xor_expr: and_expr ('^' and_expr)* +and_expr: shift_expr ('&' shift_expr)* +shift_expr: arith_expr (('<<'|'>>') arith_expr)* +arith_expr: term (('+'|'-') term)* +term: factor (('*'|'@'|'/'|'%'|'//') factor)* +factor: ('+'|'-'|'~') factor | power +power: atom trailer* ['**' factor] +atom: ('(' [yield_expr|testlist_gexp] ')' | + '[' [listmaker] ']' | + '{' [dictsetmaker] '}' | + '`' testlist1 '`' | + NAME | NUMBER | STRING+ | '.' '.' '.') +listmaker: (test|star_expr) ( comp_for | (',' (test|star_expr))* [','] ) +testlist_gexp: (test|star_expr) ( comp_for | (',' (test|star_expr))* [','] ) +lambdef: 'lambda' [varargslist] ':' test +trailer: '(' [arglist] ')' | '[' subscriptlist ']' | '.' NAME +subscriptlist: subscript (',' subscript)* [','] +subscript: test | [test] ':' [test] [sliceop] +sliceop: ':' [test] +exprlist: (expr|star_expr) (',' (expr|star_expr))* [','] +testlist: test (',' test)* [','] +dictsetmaker: ( (test ':' test (comp_for | (',' test ':' test)* [','])) | + (test (comp_for | (',' test)* [','])) ) + +classdef: 'class' NAME ['(' [arglist] ')'] ':' suite + +arglist: (argument ',')* (argument [','] + |'*' test (',' argument)* [',' '**' test] + |'**' test) +argument: test [comp_for] | test '=' test # Really [keyword '='] test + +comp_iter: comp_for | comp_if +comp_for: 'for' exprlist 'in' testlist_safe [comp_iter] +comp_if: 'if' old_test [comp_iter] + +testlist1: test (',' test)* + +# not used in grammar, but may appear in "node" passed from Parser to Compiler +encoding_decl: NAME + +yield_expr: 'yield' [yield_arg] +yield_arg: 'from' test | testlist diff --git a/PythonHome/Lib/lib2to3/PatternGrammar.txt b/PythonHome/Lib/lib2to3/PatternGrammar.txt new file mode 100644 index 0000000000..36bf814827 --- /dev/null +++ b/PythonHome/Lib/lib2to3/PatternGrammar.txt @@ -0,0 +1,28 @@ +# Copyright 2006 Google, Inc. All Rights Reserved. +# Licensed to PSF under a Contributor Agreement. + +# A grammar to describe tree matching patterns. +# Not shown here: +# - 'TOKEN' stands for any token (leaf node) +# - 'any' stands for any node (leaf or interior) +# With 'any' we can still specify the sub-structure. + +# The start symbol is 'Matcher'. + +Matcher: Alternatives ENDMARKER + +Alternatives: Alternative ('|' Alternative)* + +Alternative: (Unit | NegatedUnit)+ + +Unit: [NAME '='] ( STRING [Repeater] + | NAME [Details] [Repeater] + | '(' Alternatives ')' [Repeater] + | '[' Alternatives ']' + ) + +NegatedUnit: 'not' (STRING | NAME [Details] | '(' Alternatives ')') + +Repeater: '*' | '+' | '{' NUMBER [',' NUMBER] '}' + +Details: '<' Alternatives '>' diff --git a/PythonHome/Lib/lib2to3/__init__.pyc b/PythonHome/Lib/lib2to3/__init__.pyc new file mode 100644 index 0000000000000000000000000000000000000000..01a6ebe4674124277756cd79a7ae0c6eb56deb9a GIT binary patch literal 112 zcmZSn%*(YSJRvxl0SXv_v;z~%a97Z@Yvy5&bX!*C*afRaT7CI*ktB9sVd0j?2P1e3rMC6RXvHQ|5m!?AbB zQVBxBXwU9ODGTrFRp|1palIuahCx6B9k~3KZSR7T?hjgWn^ikkSL20BYdNZQb|1o& Sr|Y&e4{tZ(N#Z%jMf3%sbt;zt literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/lib2to3/btm_matcher.pyc b/PythonHome/Lib/lib2to3/btm_matcher.pyc new file mode 100644 index 0000000000000000000000000000000000000000..9e2b89b487a137fdbbba1c9d5583ec51dc745fe4 GIT binary patch literal 5665 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 J=YQ7q{tM>`2$BE* literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/lib2to3/btm_utils.pyc b/PythonHome/Lib/lib2to3/btm_utils.pyc new file mode 100644 index 0000000000000000000000000000000000000000..91347a105170a67e52918c9119300f486ffce226 GIT binary patch literal 7368 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 literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/lib2to3/fixer_base.pyc b/PythonHome/Lib/lib2to3/fixer_base.pyc new file mode 100644 index 0000000000000000000000000000000000000000..e427cfca66ae5f311203fd76bee3c1515e3acd78 GIT binary patch literal 7017 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 literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/lib2to3/fixer_util.pyc b/PythonHome/Lib/lib2to3/fixer_util.pyc new file mode 100644 index 0000000000000000000000000000000000000000..78ff67d157b9f7e3730fde9ac3a7da589ae9a5d3 GIT binary patch literal 14173 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 BW~u-H literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/lib2to3/fixes/fix_basestring.pyc b/PythonHome/Lib/lib2to3/fixes/fix_basestring.pyc new file mode 100644 index 0000000000000000000000000000000000000000..d76cb745b55a48b61469eaa2aa4aef111e466d69 GIT binary patch literal 762 zcmbV~!AiqG5Qb-yG-|O>@T$;@n2SB=Rf@LgNrR*XF%;Ie*-A>%lhw1SHr)JeA44BO6u1RL#jfqa;~u~jHz*nge3ssaoNPf( zX52UrK5KxX4D%-Ux&`HFGVw%)&KtQ{A%0X@E%n#ya7w(|uxvYDCy literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/lib2to3/fixes/fix_buffer.pyc b/PythonHome/Lib/lib2to3/fixes/fix_buffer.pyc new file mode 100644 index 0000000000000000000000000000000000000000..7f99caf2255c4eb62f35698bb96cd2e45a2db493 GIT binary patch literal 919 zcmbVKO>fjN5FIDk0E;U1z=fL;hon8^036GTZUrY;q3lYCu*l@Yp{|?{#SZOC<+S`L z{uh6M8KtW}M8-n>Y4<9L&GJ`?N0M=JE0U0?nKuQ~((wgUSQVpz$E{fKlv& z_Mr(N3os5qdT=p=8b8e78^9jmeHKC$!aBY~#hxL&Qde@|_B^+|JkQ(D((q!eYdOS8 zk{of>+KxA}>4x1GB`@7!qC8BD8G@Z7)Ko$gxslUZfM=_`k@g-sSbyp2{hEdHmT2ZN zg2Y)E5zTyuftzkd(;;JIo33N(W>SPX|KsVqOF5kI7F#`!CejhNL#{L(M{&eI*fX|gC@`RoZdOZ3 zG)9u+RxKN1*bfo~im8z$)d$(@yp$=)kW!+n;Yt{(>#0^($(x_esI5sUJ4TzpJVGzo zzE;IntKy06o^ELehEPmGB>m3Gk8-r8?uO<8rWk4mY|h;J?OhCnAl^c_MGDb$)u<_? zKR3fD?EyN=H=^vCKDVmS(xu6(UaL}BNAm6IX7e&#rL^u_lFs`#rYUXsKAIs)Aq%}Q z2))(Bk~9;d>PlpVF3?5z{oajMX(y)Rvcy}6SI$-ZFD`DplSzjKsbFY{p?}B@{hxq2 By6gY| literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/lib2to3/fixes/fix_callable.pyc b/PythonHome/Lib/lib2to3/fixes/fix_callable.pyc new file mode 100644 index 0000000000000000000000000000000000000000..9b4f696fec903b006369c0bc302df7337dcfd7b9 GIT binary patch literal 1462 zcmbVMO>fgc5FOizQvyhQT;PIMaEODd9N?N(v=y8nLQW-wsbm~`Q#SHPw7Z5@N>7FV z#Q)+4z?)6e76}eu$&>NS?wi>+Zxj5u-T(gX<20v>C&2FuyygQ;L6pFHRQObSRQZ(n zIO_KgKPe;frv5Cog|kUDv&B%T+BQNNRU4btxr`9p#@e!! zxm8VVMh6$mhub163RNGAtbZ*pRJClh6>2VODGOPQ)K5H-hjwfqX3jmOv&_h-%drj& zV>)M&RnmrtOsxjAi|tvf?JZu~wE3rWjc;!vfa7htxg?qE?Bg|0U?fQPn5iUigm;*5 zFbd8=8Ay$%5l_XkS!!tlZ0`#^%jS#JV=>r}GjLJP;ITSWC8x_}rgsL>Z^`u%*htik zjWT^)Dr3b;z-ud6+i_N(iowo6;CFW@=53wtz`b7J5<_6$dchiI90BuhNDg;es~P5_MC^)<h1@SIRZAoW~4@QxHKxZD~!+ZMfbra}(i%oN<~Q9lchwqf*VD+2;8X-v+}r z-6(CeJhcu`XSKoAtsY^!;i}~I{rmm{@3H4@xaBHoTI0&3sk>TfS~W#m@+UWas9R}o z!`Xk6=1sNCtinHlJ87c}+w%ZLKQTJUhmD7V81HX)(Y){yAQ$6Ib*<8+Oc%*Iex~ Nrr{HW!5uI1e*rSSK>z>% literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/lib2to3/fixes/fix_dict.pyc b/PythonHome/Lib/lib2to3/fixes/fix_dict.pyc new file mode 100644 index 0000000000000000000000000000000000000000..ed946b194217684647d4962ead233b159470e1be GIT binary patch literal 3709 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 R64%rn&HB8czYV9|{0H7fZqxt( literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/lib2to3/fixes/fix_exec.pyc b/PythonHome/Lib/lib2to3/fixes/fix_exec.pyc new file mode 100644 index 0000000000000000000000000000000000000000..60dd9f7fa72ac33bf6c61c5d54fb5cdba71c8a5a GIT binary patch literal 1387 zcmbVLUuzRV5TCtEE=_2)2!chW`*s&-3)a^fY)gI8AlHDHR?f?1lU}?(<#r<}q%XE# z!O!8V-@%XL7w|WGEk#5SFYGTfvoo_Zznyh|u64e@`*@tt&FA9(C6wy@VE<(LsVv3u%O2yoS#6nA16M*(oX>j zObb#V*tM)Tn02rPKEvaH3(*TeN8;lyB5iWBCw-QE8NY~&3+bnYFGp59@wa@Lu=qjt zY|!#Ap+Qj^8JjZS^8;U=*a*Mt_qsPp>*$0#3L>!xXR8vnjz0u$oFF%<7%n{C}crzLfScfosLekbhK;A=chcn znla*rb}-p(j;-QC;|=DIq3A~d604#uI^w?ltwG!54w0)rk!hTDpwyd2Ln zR=JNsHCJX0!oiy;Df9E#q@%3v;O+ika1{2#huFQV^qobZ6ouSWh()1&#CMN&Zqlsgo2j;>TVfCJnDI<)`u`})GO|~5(BsoIQ{=hpVqH9O Fe*wEc8rc8< literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/lib2to3/fixes/fix_execfile.pyc b/PythonHome/Lib/lib2to3/fixes/fix_execfile.pyc new file mode 100644 index 0000000000000000000000000000000000000000..9475b53c252bcca3d3cf1b97ab3d8df31612c645 GIT binary patch literal 2028 zcmbVNTW{k;6h7lPHz#Q-cwm>S5z@wspbzj`Dz;1asZ=Ys62f$4oOqHt_!4=>&`Qn= z<%u7{3x9zB#Seh*jN`T|UI0fvIWyl3og_?UQ=RD;5TGkTcpOMiGCK$Bgx0x4s&aR z$y-5NyIppOmtCp_t)Xhu%+dg*|-B^PeFaTkx?$gSm zTZ^`XRyt%*z!dBBS*KChorQE{q+_Oy2y{E7dO&bj59zI~b05KWMDc*?5rq@ddlV0O z$^OPvJEW&<1=1Zerj?EJP~A8F5eQ69D2C4tZTG0&V<+1w)c^z04?`+LQBP_8Mr*=u zQ%72YL=N-aR`u7{RlEOC-MK|>aEl?Gm^x1ousHYj(62L8g$Jeqk%9RRKL+LvbdtaD zn02|~NvU{@ip`EGWfWJ8bGPDQGKig3JTQwQ+rV-KmdqIjv$3-&C5F^{69N2x%4??pB?yj<88*p=MgeF>}JL1fP9YD=hHqT z)gLn9czt%W8}VG4xa75#dF-)XGutv<8YXWqfl{g})yf~Ufe90i-z3qFYG{h2*$)>f z#H_0O6<=w_B-ibJTV8KU%|_c^@G(;WHXAD4NOvV|Y_fX0ac7pjc@U5x>LYLmm#4}6 zGEL^6>EiQCz8w|QunqWNb7KNQ)pCVPJ9~sf>SHz{#=;R(F}2^e-VyKP_o0|{#$t%Q zcf})X2>A!*^|;g~-Z13*C=AV29EMpDS1B*K4Hso4HCOHU>yRUlbTUty+x6wMi;ENg z%zpyuef<9^37>D_DPG0F^hB@Mv(B1kGFrkgE*1y`Ecr|xd@L%Rqzxz-Lk1ZSaARO( m05@Q%L6CtS?;YbigR9>-|DS=Ix*ax^I${@10@l8GVgC(XM6Ch< literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/lib2to3/fixes/fix_exitfunc.pyc b/PythonHome/Lib/lib2to3/fixes/fix_exitfunc.pyc new file mode 100644 index 0000000000000000000000000000000000000000..8c4fbe1939d7ec0d1f3578068c4bef21911c314a GIT binary patch literal 2682 zcmbVO-)|d55T3j9?<6D?+B7^=hY^HOD%-Z{FtM|wEKOT;0_3`-sSNt_o z775Xar9+8JnM1itBbRcIMjkoPdXzONZ_=nqd5cCZ%G)$*Q{JIbhw?6sx|H{5)MM)g zDUW6wG~sPc`kCmQ=!elJB`rD(+BonF7QKVA_(^H&&yDiSiEkEWpiWaenHOWvOOM7(o?0Qqu8hbE4IO680Sg`53JQPIEb^% zHhJlw%=6d+&QP6XX;IsmMQ-c{D<7w)k5*_d66Ub}A%D&1EEFfqA;o#}L^dRaO{9=R z<^*vfF=!)q7<4E+3;@df%8q*eE1%%f9E+ThD9x)<+k5rDsNit+`}L%M#SZKW`n>OT zi_6z+N=j>062(T2F#CQG7Yo0Cr+@onU;MG#JAI#(thoOgC%3QAU$(spfI6*oWNdEt zuW*2ns`5nX{S^?a<1~}$pzrtBjOqLLuf)~A*Z0Awdx+;Un9G32xL{BVmGL!h>OB^g z{~TH}ja{0#v~=hfVwMw=8TP{f)+>j($cA_UEE@z($(Ib)o>{vJU85sQE0UAn*y$Q(r^ zL|tP?C4^lFfsF%)m|g+u6E+T&Y0Cpz;`iA#?n z54dMdbdXsacV)YjH0a!sK@$Vc7yq3#h(ljCuxrXkJ2dm?+@rImj5la0#?C8H{uE@J zu;7ljO8jAMGTWl0O?zi8TJqU%34(1pc1brKXm-fH4Xlh{Jr`(6M-Z{L_-z&V>>8c5 zY1t(7NjwnFHc+T8G(t$?`fadk7ZcbAass1}!^)y=!*` z8&m0px<|Xqjf*G)kYX5avlMEe^yWOFIj*s8<#SL)t7&Si(&ihU9K=Q6`jfOs(DVGd zzkTUH$rLwpKTZ;EJnMI$UgVjN$HA5r-i}2%*Sw$KhZH3_hw$ad+B`+Q1UFd-wD2t+ zNyUycup8Jat+?7k9@WT)Wuij74q_)ADD-$5!c_>C%G;q;mBnKv#{{1vubEp%xs|3bmPM)`Zt^+{@P?aL4N>618ju__!==%-yV*)~8`lRhrbMynt+? zeMc)R#(;iNsFT(6Wsx|Z{{Ozfg~EU-AU|z*GJ<94dK6&u;>7#HcZ8?NVc!$M{C}s4Yn>)ave2jEGr{%P^TW;6uHiiLw z%f&@eQjQrch`D+ygt8$RZ*iR~?Envmj^;MaYQ_q85u5J5-Y-Ur)weI^@zaGXkf0}rIk7Xo4LNo^S zC}~jU(X2t^26>D(DQnWKMdMbDw_;}u9Ok!;avmr|&< z={KTlqMyc(DCy8)u*~k>dqn%{LYBf#BP-%*q$kpdRAp9{!TyGL-4jaNTx81F;4Zn> z?{;5F5xvb-0%a*|8EKQ|gM_Rbb!8vby!wMrJW+3 zoBi)ll}QCnWkp`uepfY6!2ks$yTl+rle$K`KvS-2coG>Iw3y3a7|o>H?4lT!8{hzC z-OXo(T?e9cXbKstC=0nb^1|8`kkKFet{-9`?qQ$LvCLNh=-9DG5>484o!jEh9WQb7 zqT|q+qr;%d!hb@oEAZ6G4YO!=l0<_dKbPgUV=&XNx&DHHzEas;2`3fY3NRj(6YkJk zGfd>iIg#nM@N0MX)oPhJ4ANpSeD-2bT#2`7kvOHm7dKSD=kJJ~@V9(%Q4At|xrp$_ z%FY9dzwywYvJaH+E5gyjP|c~~m81UGbO|4^-=qaMK+AzY1oQ=h5=Oq^D8!C{H}TRikWU~^Ch;A0L+v}P-xCnF=DQh zpGfQGN1VaXhz*V0IAH;97|Zo3N{N9oV*9t_#K@7;pe?sD+`%pbJCGxeUWuo>Up5e4?YWk}kW?Utq}13Vf_ivO4&e&yJ4v zMniWHPEnZa5x4K{DL&vRBhK0rEVB&I_S#R|jdo)gtO9c$!Z68W1jV^7CQ@&Xup!G} z#Pih!&p9f?3Lmk$Fr0r^xw=Fj0o~2<(c&*|l@v4q=W2%y*MT=5dyl;@ G8-D{Brt^^i literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/lib2to3/fixes/fix_funcattrs.pyc b/PythonHome/Lib/lib2to3/fixes/fix_funcattrs.pyc new file mode 100644 index 0000000000000000000000000000000000000000..c6d704bb5e98f6f5d1035fba6df7ccbbe65797bf GIT binary patch literal 1083 zcmbVL&5G1O5Ux%#Q3qER55fv!ACzPj=ir`%b|k|EvESr|{_ zL-{s7gfC!KXLY;?YC~75x~nQ*)mQC*KNx>~`+iZt#2ZR>KHt>buGUstnPlBS;o8{mOhpG3L0|?I+ot@~pXd$ZeM?O;$9C9Pp=c z1f{I9UR$$2DcVy0OTJPSHag~0 zs^bBlIwS=#Or0CyCX&q)6kCs)afCb{efDAN!#Vcc@k}~i25|Qll1r8kJH~bli3j92 z#OS%DgpO1ELQiKx+&4lf`imud-AUvxCPzy%(aE*W3Yj=|$?IdLdzsMv;6$2{x^lT2 zto$;}P)`!7BE~%ka}Tx2>Xph@TIG*zd$OWoF(d_X<;G&NzOdKO5eaQf)pqqwGz@_Q zc7xq!t`>V0O(BR1A>7yrQMYBU$s|n6u9x-zmDy`iwDmf(D%S(JH_w;Lm&rV#Vcmms z+Fv6~Xb=gd0~WF{486H~MXr7!aL5n|IzU3=x0lgdrH6h}gJ<|o@KLyY{|m-7<8&y0 NN=yx)fqHo-Z=hwnEiPFak+*47vuN}!<{4403{-WIs(n0ji8Kx(K-el zLz_UE;5q>r!PNvB+?c?3fNuaF$`tApmiav@_70(tt@$Fk5Y6BRD}~^y?Tz&=%NlFi zzc+Ye3|Ed@+3RX6YksZ#Cth`2w!PnRtvWf&RD`8-hTt=VM%_p&HkFg(zXSX?*H!oV z60<$6F4WCMAn;o<9iC&jrw9@yGtyJWL4HE=%LzGv!cbJP%wtM^fiMaXME`_OX_)fX z)Pt6yt6KT;_)hFGpN`p6RIuZxir8+cQi4Gu&N19$1Ro6i8pADvD+aeQh=9u=X^~TM z5frC5>#ao5IaTolPUeZ4hE_g9ubsc98xMljd*4*0g=) z)kcrx-kz;iuZu;v#15S>wwAV_f_FUsfowtMJiu^NB4ufm#%Z(|X_6U2)Mkq;aS8>& lAJ1m+N{_};<{TdpK9*4NzqkZjPDUe6Lu<&lG&y2N(Jzjh!V>@h literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/lib2to3/fixes/fix_getcwdu.pyc b/PythonHome/Lib/lib2to3/fixes/fix_getcwdu.pyc new file mode 100644 index 0000000000000000000000000000000000000000..a5d6d6a82ae7506c0f9f60f57b6e66aaca2f1cf4 GIT binary patch literal 895 zcmbVK!EV$r5FI<&0Ff${BL^glOVS=90oQf~iwYN5RoRsg(Ml$pc-vIYI*J{&mC9-P zDE^BdV8&UszzJc=FEg=c=FRg2KM&#`pT90D*slP;Z*bdp2sJ=~$e`w+8MGV<4vhQ& zbO3D#MTmX~io?|eHh3_B?*Kc1FGU1(1dH?$C3}ewzi)0-FWhD6M0HtiFO(I=W*5p; z*Y%Jd31=Ss^eBrPj!`K?a52J$!sWWOYWx@Czj@gze~7t1jEU|$p}-k#`y4@GCyZzo zf$u7$u8?UlfqaotA)6z_;*ZstYt^5K#Mnf*zHBskwQ;9OmWVCZK27%Y6EPL#_V!pz z|4LDjphR_on>4k@2zQ+7Kl>KIT>w|upqCg`C6~jFu^mHU0rm53IzlQqL}-jP9hqIP zP?wa7I8wS-oh~btQ}a0m`FJ00mEMebOs)2p?Vz2_DLTbHf_;Hjw))ttSGrlha_04l zq_>1}-)`33x+i!IMcLYo>D#C1SgHpsW+^dqj}fFK(o*_2lCm}Rpvk41%YIPq0FBuv zS(&ygU9;9BvGcdf@Z~Y^?oSu}X#uAr^MPbC}einV_Qr4zI9(V@y?!Qmi h;2Q1q^EYQWZ#Y~&-~UnZLY$1PPf6;LQh3M?`7iGjwZs4b literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/lib2to3/fixes/fix_has_key.pyc b/PythonHome/Lib/lib2to3/fixes/fix_has_key.pyc new file mode 100644 index 0000000000000000000000000000000000000000..e8f7f94b29c03434a79852611e0d0b351d687a5e GIT binary patch literal 3153 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 literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/lib2to3/fixes/fix_import.pyc b/PythonHome/Lib/lib2to3/fixes/fix_import.pyc new file mode 100644 index 0000000000000000000000000000000000000000..6bde2782f45d68dcd4499c7f8a7963c6f2d748e3 GIT binary patch literal 3163 zcmbVOTW=dh6h33GuSuIUks1OOUCPAz<18tO-p&8SlYAWnKNh3r~|1eEK#f|DN(0HDlAjzP+X?Op^igIg*p{Vs?@1cQlm}{8rV^xxK2rf zIt@yi)M-*OL!B9{Rp|lD&Qe$-U80>+)Q5JRCy$9f>zt;rK^yHR`|uEAEjrM-+s|@0 zN`_f(U1I~Q6P;SK(!AMs%`iyZ$hch{rGtr%4&8p9C9d7pZk+Xk*bSpx_iUCQUc@A{ z3tR6rUHn9~FjJhM2Lsc*rh8eU&0{JnPw6yQ)9`6~Q$OL@zgc+{2d_sZgxFRPmLu+S zuzoi%I{FL0w!;fG2>71{iMBkklSQemVxSKqV~ypK89i+CTdb@h_L~xl=$pgD*a|OZ zyE^UhVQhwHdU(w55M!c&q9a8IztC7w{wvEJDalcZ#;B7b3t6V!66Np8j6Rd%#x^$AT74@)R9F zQIxuY8)nw(&<~7XtfpD0SHysYC5l+AM}MMT<_w0TbT`fRQ&zCb1#TT+G8K>48-JIKGb8F*g8aSJBq^`=x3u(dM20%hC`i(cJ8TF zGl7idW!}7MjLvP8r8n|C%L}M6CL~A!9a}vxLVj*#_3o`~{F1 zsPbdQ3u*jIK)I$08>NIAJg_-7z&$X!f`(r_Tpd#{nFxxap43 zA?PoROFU-g;1VYcdf0k>>lHeZ#IwPwSo@Ki5!!p-$)Li6 z&2feD-)QVm{!l^z5y_RuB}~zm2#Wbf+yJj)`UqYixYIPQkuP$CwSG-4sVBnyRiB}b{=e^x{akAQtrgKvoB zGR`m;Aqb@7sAg%QvY^g@aOTx~sj8}KQO&7Fsfkgwyr`Vg0;s9S?Z zsZm{EZjt+WgQo<`1y}{6fHQCnh&rr@%M_^u;GxQ>z~3s*unqtY5J61_rY|NB-sWoz zxx;r8zL@Z#gwLZv6;OSiFIDVjV`W-mFYfalv9WibHrX5bhFUL>6fvFzS%$9`-;dJB z`aam%l<}Y693bAkV!~vTcRXDP+sw!(MV*nSAGEnKaWD! zl^|2j_T^;Xm#};vU>n8S_r*;CX-T533r3+vL*(lEXsW<5Am=Y#MRZIqc6&XJ^Bz70+?ERpanockji s#nO~Q2=c*EbT4<}H6$9>tGMvLoR|DvDKd7IK~)4%o>v#txpHIiZ$rDKjsO4v literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/lib2to3/fixes/fix_imports.pyc b/PythonHome/Lib/lib2to3/fixes/fix_imports.pyc new file mode 100644 index 0000000000000000000000000000000000000000..1f50f80f354c50d828d7e789c108519ed89dccdf GIT binary patch literal 5230 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 GQSc43#e^9E literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/lib2to3/fixes/fix_input.pyc b/PythonHome/Lib/lib2to3/fixes/fix_input.pyc new file mode 100644 index 0000000000000000000000000000000000000000..affdba7317bdb0b44dbacdfe037cf7e2317f60de GIT binary patch literal 1103 zcmbVL!EVz)5S_Ihw+WP1LLhNK@`<>Y9Drk6K`M}t+6Xz75T`minZAacUZ6!FB zkK(`h0p4sVrJN9!_IY-8Jp1O&*#EIL`2OzGG^byWkM|2Kvj7xCDNs=1krq^WlzJq1 z@00ea3MdVz>QUNTdjl60QW}y_AuTtk=+Tv+bd!pZlt;@x&GGdHeIvRedY=xc*raLP z=Nq2`UY8fDjqD<`QNGCPGi9Q(UUfDejYhjLZ4;@_nT~IqyQ9*>hp__7Xq<)LWcaO2mV}OEaf{RUkCt$z=qF#uUOdTb2gs?$$>$$$(6^1L@GqZn-#0RkW zcunK4k8|!C*V)55#4^VKOSBa9MbHw$d)$Zi5i^>y%V+(+f*~S&k^$Ks*^nEJIC#!n zlQ}Y=D^E;gPCw}Y)UnAjAs)K53W~=pr)9{S+NukSbVL>OU96+BR@G}~uA5pVe4Mau ziR&JxbPX~}&z(^>g>ng7Wjbw*S%Sn|kZ zww&oTzqc<>PF^LGSQa9;FfzM3wIlB04ZmvN@dkN7&t{ zjpRHXPyLJdzxoH1Z)S7XBEbV#@_2S;cfQ$gW*oe`5&ik&uctHGJpsO7;WZh=oM-~+ z(cGufqspg=PadxWSqC%;+`2<$hpH}3x>SWU390JQqz7M@R6xr);gJFd zfe_PSVsKw@gKOc+>8XQb%#~K=J-$(lXVtt``Y0Z_{0CxVJ07d^qGV^e%JuOe`J2;i zflT7Mu}Q8k%EH*VjiIe8RokPy-o%6BL5%Nc7&p`9F|?24Ux$csO#Cj$QG$s77Du9f zF&M?ee+;E1)!`r>eeBK`C>+CoE>`E8F&E4&zhC1u`{1-CS`uvoYJKML?$YC~*mkJx z(9)+C4HM8SpY&6)IB%Eg2VBZ!cejBzi|Yc?r!DLV=hNM7NNq^^EnNUAq~|~1rfrYf z-fsIZKK{F?jQ^^J5dw}~iRgyaUC zvND^>$l+Pp)UMC%W~Fc?#B&u-q3%YZnJd{WeVH;+$^#|4cMa+0N-K;~%Hty_W5iCl zk`7aq3sGv0$4Kb;b!kny4?Sgr#G!a-YpMREjNZI!Gc7XhtLkszbmHaWifqh znE!TVb?Ck8DbeuBahrIto z@+p`16TF7=36Wl5TCuX&(5_ep&*q=AT2`34upU}eM_Szp-4z1ASbB83OX)#YiFJF-F0`b zbtL<#d2}rWODSHFD52kOQ5P zMOBXFCwo!@&8M;{bynqy1=bmvRV7rduF9P_R%2X$i?%=8mVH=ldly?<-pNfYx2I6q z+KT1!)0W&U*EXMAn+d>A7I%JKoklo zxJtv&7q!Jj9k#iyC>KgKIO&J1{0oSOR#!;!?lnr;y9L?15jvCV0$Q@y?{NhSZQZU+ z%PZO2hQL)*e{`eI5kt*Ba>_bZPR43hdy9|d-i=yst0(vH^Z#DDJkt@tWeoEURtxJ8 z%YKhYo$t9tNb`Ur+g!A0-lB=1MVrP%i-=r6^ESPNq(igcY2KkPfBcos0$Oxwu}1SX znuO$F)27RS%x_*2(LAKf$g^E?os|n@?VU>^^NRU-m$Ud_b7kK3<~ZrlWQ_+wJbOsb zUJ>X#qDjntfkOQILL7%QxwE>KHQ4SUJ%yDK0u(d%`X$%WMTiHJ z-!#g(E|}~>7dd9kt$|S`=Gml9d3$$NtATH4_IA8~^u)3A=V{R>@1uYjOAfz1I@QoTqx5uVX_n9$+IRbQO(KwGBC?Og5DS3Yx?s?v@sGkp(c_9J#9);r8d`ZGFC5eAOl4M%tO~EYZ|I{Gs{Bj%|C0RACQ>XDp z`lNife|q|4aO{DYrc5f6D>GmuxAFYPpa%SwakJPiNF<_e6hy)C5-Qg%N%ATKG;C?W pD5KmomQ81R$8H5 zB~6ea;Jiy;ArIC6`U0I<$#=#rq*Q1}v-9!OeC_&w?TkPD^xN?g`p3ubceuo+=}p&qmcbcA99> ztPFp6@aVxll7q>(gDEOqTf_5O7aL5T)`I64X2xYnOtQvIr1O|o?>c}N`4u;5c&A3k z)NrE-(tg|LG^NZVQ>DdMT&z}RGT{WFGrmlfGW@MnikI5* zm9Sla)6Ubw>PA>xuwx_?dYvp%BRbgtWwR8KZXko@e{os&b-T&`2$y+)L}0ra^>XgJ z)(@!lVo2@0L+wPxh+2;wo^L^X91*_x8c7sVAHz26n?f9B)PEAC%at&8qj#+dC+1J| zb%{`GyQk7`Mg16S^CVmsKfGo`mbOl%Ld$QnyGhF5mBpJZD53NTv-@{Vx zon!f(;B^4Cg?0dEc)qsb^~i0}Fn~R>_hHXFAHsP6Z2)JUgF(ipzOi<=<`4kiAt7Bb zU?o87L-oNScV13y5vTjt2<~NDWOTt8d0>dg5zX1mQs=1-62D++ill95%C4TuPJnZ8 zIRKV2$JR(Uu~dty7C5vK0es%w-6ihVGhGTx<$IH=M#O}KVFT2n&~JoeD?H1kwN&R? zR4QGHnEtxKFhb=Htkjw4?M$Prad0t(8q+Ug$~D5(5py58>FE!0ajN9vq16YcbnFb# z&2@qIgxy9%oQ%@ol~>%wjk$vaSio+w8*G<-;cc_AKW4YRT^2dxEmS8-i6=Hm+<{J# zLT8PlEk$usH^S~9bM!J<>Y_@mTqt45?Q+6h?n>jeVO&l>K0P`4KAyQ?>ZVL|oryZ$ zMUPENj{DDf#nh~uxD1U#fawII9Y649U1_P{Ns{R$#*8e)M6TRUjg`uE!i9H)cNJbt Z4)gy8`VQ3Tr{}#LD{S5-yo!I~Y literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/lib2to3/fixes/fix_itertools_imports.pyc b/PythonHome/Lib/lib2to3/fixes/fix_itertools_imports.pyc new file mode 100644 index 0000000000000000000000000000000000000000..f64c67ae65a22831f810e0fa6e55f1ded0d09332 GIT binary patch literal 1985 zcmbtV&2Jk;6o0ep@7RfxqKcr1`hdtHP=ty&rLAz9RI1cCXl*INO0}%Lv+3IV)tPaL zk$s_X=D&b{fg4xO+!22RLY(2fw~iY)fK(jM^P8FX_501diT!)4@x%G&{V}XQHvWEs zL!Y4t0EQ?91Qx^s5(|bF2%6gv+mMuCSc0Ss!!jfl7*=qv1k!>@6+$#B!`A>W0X`en zAgDm!sZ!uBiq50xN~%tnsZNySnKHVQg`LPqWwI>R2Tqju`63FV7?&2&m(h9>`mvVp zb)rA<;|L688Yn^v=Z$!04UexgJ}#dI)8rnpOED@;N2pX9{goxYiJLI7UC>ou=eF}VDsIufAdscA3?^1Y6Ax$c!)#)f!G%oRj|9XVPV4rp$V8+FttFx%PTfC)m_pq z1uRRD)>o^jU;P4$5`m$w1>e}Pd;Ih#Se9W?=1?V=lqr;&^GXGl6;hT}NDpt=RN3ZR z3e#VCu8a5{ObxygY>mWW3iMu7VS>SGu)sU91=9+sU&$MtJWgLn{9niIhzRwTE`PGNyuf7vRUki4LcI2w?;u(LYmllQzw#HBi3^g1HUL2ACZRvPAM4gx%XF*(a8rZ9M*-p;lV8PDEEP!U3}q zuljkRVB5^tuIQs#lXeT8+o)JTD=*H{OQ}sn4K*VX&giz?w59n?Q))nNs26@bE86bg z({qRXcMT4;Cbz7a=h7u?W)sD#k9_T=ej@Q^0gRtTaiC=C+Se|7C*%428oaG8tj9v_n8WcBFX4 zMuDDAvMAgeXG!8?=VN^i3Sgl>K<(h-Ni@2MqtRWHeRM%jq$cUDA0KaZfe!LH=QGMr zHNMFS@vV<3nrMhU(X{H~EwLl&__t$~tT#mqwI+@h%7(Zt+V(9`!5QvYo7NrihP@}Y z*uF0K)#vl_xOmUwC)@LqESSa8^V~KjGA$HGrvxYWO*D#&(}}Y&KKM-gr`^He#O=9v z(C`(~*MsZQ6{z9RbOkD+Vz;cG!>2(F<9R_g#yUw~@#msSUAbO3AVQTlGf~WE&NsEV hiR5;K|BD{sb)ZE5w^}CeUP0FbI_aWnyDj$YzW^b%vjzYF literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/lib2to3/fixes/fix_long.pyc b/PythonHome/Lib/lib2to3/fixes/fix_long.pyc new file mode 100644 index 0000000000000000000000000000000000000000..70e572f80f0f07a833e9c1a5b211a3f73d8e7ec6 GIT binary patch literal 810 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 B?aKfF literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/lib2to3/fixes/fix_ne.pyc b/PythonHome/Lib/lib2to3/fixes/fix_ne.pyc new file mode 100644 index 0000000000000000000000000000000000000000..5844647f913d6236990990457a94ce9751dc72a6 GIT binary patch literal 941 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 A7ytkO literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/lib2to3/fixes/fix_numliterals.pyc b/PythonHome/Lib/lib2to3/fixes/fix_numliterals.pyc new file mode 100644 index 0000000000000000000000000000000000000000..b39e8a0a67c7c298d570ec3477a5839bee6fe687 GIT binary patch literal 1205 zcmbVLO>fgc5S_Ihx2Y(!2ZVaU0;$RYsj=gD}uI

    1}e3u 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 C6A%^v literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/lib2to3/fixes/fix_raise.pyc b/PythonHome/Lib/lib2to3/fixes/fix_raise.pyc new file mode 100644 index 0000000000000000000000000000000000000000..25f690ae9dd487a13f15705703ebdf25c49d60e1 GIT binary patch literal 2467 zcmbVNUys{F5TA9Ne~zzr91>N9fW4C-E?iHdeM6<{wFHFJMwJs?McQH9ONDLSmz-V8CxCV&{BeUF_`o0dMdbzJd+<>GBqb4LR7_}g2!>A331tSZR z4vad;*8ow6xeXIk*o0pJ&H;WHZ9&+Afzu`fN-y#s!Hz=vJS zD)+ql?mXc7pgQiobIf~hFHoND-tzOFbA0>K9qPV%cX%49nWu6;5Mw_$afX+;`&lZk z3S7foDR&$PZSQq&6R9Xo$5-Jh?)^!Y?U$}rp1hsV@KZleCHKc!p}16eluo%g3&cW2 zSt>2ddVF-;I~oqYvc9~{_cvkN=ciE|^ReJj8f1Ac0u?VgdX~!AS0d!m1g(isbGp%I zA#RjP<)?u--Rb`=kW zLK7~u-+Huf|;LA z(Gy=HOdKB&SeOx*U#KiWFG-D>Me@*!FulNGNK^yKVySW=%6**Ku>mlFA+=E#6YIOIo2 z1lAk_fu&Z{^=DH3VQpY#xdVp`mc*+At%K}Im8knwadhd~zNR3(=pJ5b&)zqpDn+urgt8fU3dVgcAeu9yNt^T?-&( zu&Tp3bq9a}Mibf38RWmg+2<78YP;5In$$mT&2cg>0lXf<^AI(e;I$ydwu4dzoHQZ- z15_L47OW7w1Ingufy$9{Y7picIT_4buxgMj(g9iDxKQ5ICTO92n@!QnCJ;PExCMLP zyxN5|inXA0_D2I={|)Olq`MHdiIu~=mJHBBg@ ztd4L%K`XBHU_KU9J34WrfAA}aLs43*aY2Pd4YeTTt4+5o&|F{WgIN@Zxkz0bPh1?O>OM9XMODA4 zF_$8tLHb8edm5Mg5iXhHk{K?QlIkFlQG(^JOVgnmE6o-0L@!cOP8Q@s7O|2pvAFcd z(@{#~RL`k6b;$%p{sdam&!^HQ0DV>}DFZcj@DwzW99M@gpG4!AaWuZGvU@M7cS)k2 z_U8~=ora^%kH6OBGn9}IkpOEOJ8YLV*bXyWHruX!%xuFp_L$8~ys_DV(MBE{@7qSh z+(X_^*}lHD*@w*0A)ub;c_}tW&(l%#yd(Qvmc u`$9#re)xA@xlAB3_!0gPsHGF`|1nr+;r%i^4?aL8lF%FG4n}x~ImW+U@)+;{ literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/lib2to3/fixes/fix_raw_input.pyc b/PythonHome/Lib/lib2to3/fixes/fix_raw_input.pyc new file mode 100644 index 0000000000000000000000000000000000000000..b7c5443e2ecc1597c0b9f06971c0d1f1007dfb62 GIT binary patch literal 905 zcma)4O>fjN5FI<&0E;Sm<$&Y^QqmrBDA%%rMIa%;3S}1|!Xo2Myfl^bq1aKWR8Gr} z;(zf6m~qM$IMtG0X5#sH^X%Z)!Sv^cFUtb1SAgGVxa|vs5+FxpP;xK~Y7RLEMt%S$ zfI5UcL_Y-0;d}yHJea@_fE~ccJc2TUWpam#oglobzUf}LGv!2arkbzXie6pFs_6!o zq-lC2s>ZblfBdxKn3gaEH$~V|0l86DkN-maw@|fq_tC)WnYwsQ$@^I-bB^0SLeMx1 zBcgfW=L%^qAkR*yd@xryC2`tIE(xoW$ajYA!#E_$U@L zf#$K8{a2+RRf+BdHwkNx5w18^cG0*dHIb%exZpfX-3 z7opYl8l_37ha$EW*jtIc*S)0X-=*bc_ojItBlBiP4irRz7x#|b) z4$zptl|@^3%2gXPQhWD&wR)K?GHP){&0DwTm(j%%2TN=s9t9C!_&4dNm$GaNWP)dq q5&ZSg23Hxcp^u#7v!gfWpCm=zFuFAvFUILO{)}#CBo!XAL;f31u(_oG literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/lib2to3/fixes/fix_reduce.pyc b/PythonHome/Lib/lib2to3/fixes/fix_reduce.pyc new file mode 100644 index 0000000000000000000000000000000000000000..de60d08574b34bf91fa532fc202f7a9f4b8db806 GIT binary patch literal 1231 zcmcgr&2G~`5FXo!0gFO~cz^{Cb|jPoTtie+(G!i3Qwd>3GLF5b3${1xk7%Xd%0uy9 zJOIqBO`=|q=z*1Hc6N4tzMYv3ejY?W-hW(`FsuOgBP4x{tOCf8drnw)wU~*l#OPstZc)Xs0Rlg=pMOvRBeYp*}T2n;A=Xwxp(&bkZbv zZ(H7(S z$H>f|3BK~+I>2!SoJz7~in)too_9sd^W4pC zp7#@vM@oODEH?)zEKc)Mw%fvpO~cI?HBwbvIcV=*pPju)mnp&AuwuG6h5=QBz78_Ms2D9g5^@|L?QwzDui4^(^7=mxM7_VVWlkV-Ep(luGife z(*!xcinu%nFTs290(|GJoj{czDNgq6oVlFaeBas9-^=yC_J8b#H2anD{t}OwKtx16 zNJWuDiK5h@oBM=NBkipkFXpq-aqF zHHvDa9U9hYfD?6|d_nYmZ;7HM>NYR2`!68w$472F3bS+^*tnl)H`k*e)uvv@iZ-9u zU3b$p$7U-Hj^dGZKWxu66aTF1u>%`T1!3zD1DwhIeqeNy7c6JmfjLA8 z$u=d9VFnkhrNLMxay`zA&?Ow5_H}NW*gzu8yBKX9JdFDXN!E|bhgv8El83^2iPpYTfKD-kWvI_Sp#5jdv>y>}nltX0KOu3IFaP3noaNRZ zS!758{O98(Xl-=$ePoW+$8Hx+nm_H@Z>I|7})3)%w#0Vk5RUb$9x8%!G6Vz@0GZv49lb|3^5P{O#+bNCgIGRL}}I} zyn;6#mqWNQ&UMIk88uuNew)V-z$^$=kZ$PEA4IV7V<}YWq93xjkCcL+K&SmiqgzynQr4@MZ@$^-Q0xTHN1&b@OqQQ*JAj{J> z9~4%q%j$CZl6q4$Sru=-`0{<>sqfDc_T{Gc@`<)g^6ee}>?7-OAv~tKB)fZOZ|^Iw zBY9?d1WYlUybXx6xL*avg2_!Bmzb+S#i~;+)s{Q*-4~y}A7vq8#wPMuNc8-H%l(Os zlcLIuWRKA$7vXUtXJK#SGtX^_3Gn~ol=8KTg0&f`g5+vtMXfnkovKqS*RK5o%1zVw literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/lib2to3/fixes/fix_repr.pyc b/PythonHome/Lib/lib2to3/fixes/fix_repr.pyc new file mode 100644 index 0000000000000000000000000000000000000000..32262db56619e0dd5593827999fb6f00ca639fe1 GIT binary patch literal 985 zcmbVKOOMkq5FXoYb}1~ZkT@WL$Zf-=h=;^wSwUBDf`ZaYh^UgAHZGguJY+jkQN1JnQuOi_;xh-`hGrH!jDhj|2dj{i;w{%hzv3gnnA%K;lOAu zKno~(ko2JFL(+#LfF!`Z9w-j$16bjqK70Y#1AIshAq!v<9Z=#22(R*uGNHRjUFb|& z+Erx=8_qZFcH7RwymVD)RBa+3xIfG}-ia838z8Lcwp^rEMMT&25YAJry)#Y=<*s3* zPK_$vg|hipIjW3BV@&$1RmwL)vv&~`w#tZmB7ECDY8&ZeYw;wa`t~WpApGM?T~&mq z;mQ0YRGZp7OUu?T&i*>LB%VaGk9Lk`CkQ)EMQ*RXNS_7l1gshC0M;m>fKMFE6Y37* zdj@!*#Af^80(uXOVEm(hiyb4$_nb{4Dl+y$5TS;aq$J)!MT|n}qC<2s4Zu=YrSfN8 zTX&9a3+t}X0cD-et$P>~^_aAZNrjja`6~XRReI%}vdTJ@jk1k)Hl_j*S_k$Xdc)c4 zd@R=ap3%rj#wA7C4r(&;ucc5_(%jW71#!wo^iJUz*v z6kt2ObgkCiai4XXGhMqLID1)Hw+iNYd2yiKUgz*SY=x6uR{IDGlumi4L8+w3=tj-$JL-r;BgI*!5)v(wfw?(|e& zOz*}WMjLnDv~fFRvG^CdoO^Q_i|hFm%RWZ_XJ|L+(JMuBpJqO_-;h%@@yPi!>9J(e z=Qcc5bmh^!lLR#D5lj?*=6$M%>W00+f@&OB=0 zR-L3+0>&kp0o{F$N--yPP+$13fp36$<7Dm2V04vtJQGs9b8h(GbEZ5?yezNBATy%l zdo)*qNCxzEJU%o2Fij8@t&245=fkV-ONzKW6dKUU_n4%9GDs^TiR5 ztYw;FWYWcCZ%!{Qqun~yHM*(YiLkNkGa$h_m%%T&^d*bq2Ouag%Bo$$x5}9BH-%1E z>e$=$R3-fKI3}&0nk?6%yr;8q!pYReOY>5{W)s}Y{#v!cu$!j#b#v}WO|)m8JWmI`(6lQv^vYDBO=YR`?c ziM(SR_ZaU(!gtH@B5_g%ai4I+ua$Yp)%E+!Enq(cA+@Fg?|rqZmc60>j(S(U=RHsl z)r$WRvY}e{g2I!)zKPSdI>&JAxF_hEak<>}r1HqD!AnmOc3iy2C7%Di+E z(RWV{51%Fb$p^4`703T=qlB;I)LSlJ-~}oe2Ht*`Y3_hDEt(wAm|yf{0+zZay8lYL s$(`D!=dLu;C0$>!*)INXo|hML)$1db3~Y6&+TotHT->0yuGV}102w8VaR2}S literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/lib2to3/fixes/fix_standarderror.pyc b/PythonHome/Lib/lib2to3/fixes/fix_standarderror.pyc new file mode 100644 index 0000000000000000000000000000000000000000..b432fa2facc23acefd6ba675cd641550dd4d7e4d GIT binary patch literal 822 zcmbtSO>5gg5S^7|wRH%%^jz?zM3?x`UPDM7+*4|bWC#_8tt_oUK_6y!1u68F{;2-1 z{DHn1$7!2e$-+F%?9R@L@7TUOG;3h}*wxl2Grlmiu20X2%+fbxJ8$00Q# zwGrhJ;)qN@HzV5OU_?KO?ufqTF;y{T$qO#_4)CeIHFmn~?KJa6R~5EeSc~ZNe7d+T z&Cb_-H>(3=CJNxkfGywAo5Gp>UWC16(HcL2gMx=jhATbxz}M$6_ZDE#gJObtDE&m- z4>;x{O0$HYbEkmu^q+Nds4N^$o}8Af5*zcmgt<2We~{{jq8mkbN@WQrEr(aY#~yu* zXlD(2ljl>Wn{uLLd#>qBvlXZ7E8|&0YuwOym%t?facAqRdb4io&3oT}ShHG=QM(6) zMVHy`yJrU87M+9s?P~;%J13Pe8UGTXbq8U!7TvXO`)X)7WI8K57=H|B{#loOyDNOX zY4*Ind|a&-=`v-Gf5`nm!<6|P!5lM+RUF2_Qiey`*ShLUu)!In41bNs;Oj<2l*~DX Z1(PB5o$bZ&7=4)z2IRH&PI`4>9L3qgiaUgl;=n zduDATgXeLc%U}{0+IrZUw8cy}_7KBqJ2Od>)pn~Z)@Fj0zWu71(YnLh*xLuMt*d74)C>F{*u$G{?+wN^hJJv5K}u|Iyp+%lBw zge4=(MaK!70mPc<>Xf%OsopO0p80^6 zFTc!Ymw7gOVyjOsnK;8TLf{c{KCM@V(?7e`rC!#}_+2(+e;y?q7MErhAER&nfLJ>m z%m5uR*tldR-i4xtLu;27E+dY2(;*OR!G^4W8Q%48(3A{*}E$_AV`sL>b-@0lYhEI$~-kQcQaqGAz-ab8Zl+%ev8k zqUAIJhvh#Q%$SwYJ&1s@w!2ahGln87Q@uoLL{cyTqZP1mz@-yNm#|UtLzbtFF6FGa zu63CPY!z@%1PrV=ky5(tBct=V^hC+c!CH+rZElSO!nAQ(!F@L8_>x__@$!ErUvNVG zmIjwj@c{k|XHM##I&n_ad+J2JqXbepK8i{-bri`h5Jg3mwmGK3F-#B32Qu6uw*~P_+U=o}_?KWT;{mYUK7+#Lk@W6A9mFK?iOh$aL91%rn zl^{&aDPZy1wbj}z7m{8hj)8oW8;1TIR~)V+Iq(04DzKexff_UMhK1L?uReAD2J#zM AR{#J2 literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/lib2to3/fixes/fix_throw.pyc b/PythonHome/Lib/lib2to3/fixes/fix_throw.pyc new file mode 100644 index 0000000000000000000000000000000000000000..fca3c72266b20aeacf47bb4046c078a73eb5fae9 GIT binary patch literal 1965 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 literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/lib2to3/fixes/fix_types.pyc b/PythonHome/Lib/lib2to3/fixes/fix_types.pyc new file mode 100644 index 0000000000000000000000000000000000000000..918adbb229a76dc71003788fce7b082b970bd5f4 GIT binary patch literal 2154 zcmbVM>uwuG6h3PwPU1Fg=?w}k43yS(FGgxbC8`q9q%Dfnn#eYSnv`Yj87JfJ?wFl% zE>if_J`_*DBk&@;0N**ACPDl`#MwFbneSX?s(&rlfB)f^-iQwW=0Lx}=a(WPO*Ft7 zk*-i0QC6Wrg(8-#lvXL5qrqG$&rv#0S&arYitHuQ^Q3F^KrfJ91X&_o2RTLhG{`dP zGbK3-a*p(SAm>S60J%u|63AuJ@0ZdCAXi9#2=Wo>t031%e+=>oX$A5r>CZr}ll~m! z2I-q1IImGEn;*FR~1h&yEFXi}#!(z{D< ziQW*s8~}5hdd)AmB!8eJ&+MKl)YuiOFqzx2`Iee_pF+r-o~5Q;ulKi& zH)_`vuO-Cg>AtwV&fRXV@+5<^&Ho*#6e2k!^C}s-9aA4AIXp+{OdlT7R=|+E&{oQt zJ8C^B3t#VNnbERg34*mYo4O)EZ7eVr@OoIUEBuv)60|7Bh06|eIJC9fZFT)!;4MDW zPtC}V?dUL!b9}dv4@oeY$perShS6~;;B0hR3@H7!o26O}jY?o=IAbYk*iM4lPI8^1 zCSX&O_#lalU7EUGuJp*|I0D<3__^54pI)`p-4&HuA2Hm6LS4k;{N_Pc~dD`J)hRM+m#9?bKV}3a6oZCrKEmI8I#>1i&-qL|=v8<{>bU^}N(ER<5NS{2YvUGK%Le-x8q) z!3`${=s551gk_6oF))~p%S}tRU`}iok8NR{ljb=wx)sjD&~Ybqated?sU4M7>oIqv zAMOW(cEh6=3JiuAI2$xqN_njIWrKMVB>O&d;?FrTBLX+{``nJ4K0c*L@~yJ9KX#dA zN8f_u)a{z$k!l21G*l=On~I{{kURZ#;|A0#YDFr57egYCo>-o}Reb&?7K0}?B7>K; z%Fpd&j?6s0iTEMKJNp*a1?u*i920n64@R6PcZt6>eEuseLClj19aK2(%B0Gh;QzNO z9aO3Kk}$kr@Q@!wG~pwn9?t7EdAp8GHa|y!n>#HGu0WH=LS|!D7A7o15%*tiJdIyG z-q=|0d>c3zHIf?dBE4I-80~+D+~v+c zz~{N#HQ+p3=`{J?%Jy-r-3Y+=(CL=R?{&d&i&0v6vv~5k5Jfx-HZ5y@n_a}(m4V>y ut>OuLX7}W{|ASM?_NXk>3SVH)plj805q_0wv~coQ`G<7U64k5MDt`k-O$zb= literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/lib2to3/fixes/fix_unicode.pyc b/PythonHome/Lib/lib2to3/fixes/fix_unicode.pyc new file mode 100644 index 0000000000000000000000000000000000000000..d3a8edb4d8d942efe92daf6184fe98f9f07ecbfb GIT binary patch literal 1672 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 literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/lib2to3/fixes/fix_xreadlines.pyc b/PythonHome/Lib/lib2to3/fixes/fix_xreadlines.pyc new file mode 100644 index 0000000000000000000000000000000000000000..b66d6938395151e88f61c19e6b600608f0c259e7 GIT binary patch literal 1121 zcmbVL&5qMB5FRIKfT9&EIB`H&l~7X6Ta{Kez>@yvW<|K~yT$Jl#rXqnt3+u!YIobby{o*DORfGTz%st$7PhY9YsaBIm zwmdqefiQ$($47T@Zm*#w@>Lj|)%+F;hAIGd!wcD6FQN);T~mSMBZQkSA@VX?Y7!~A zQMIfGtN&W0WxhzPn&>*qH_t|+lXwu**zNNB$0TE#x9hkJr4zES5qbmn)LbWo$jTH` pK^?>ddoN&Vm3EzVmVJB=IQ%Z&e`n*`aa=c`N8PWp3J%$!{|mP=^&tQN literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/lib2to3/fixes/fix_zip.pyc b/PythonHome/Lib/lib2to3/fixes/fix_zip.pyc new file mode 100644 index 0000000000000000000000000000000000000000..846ab3cdde339d9d603016e560b51d43f0695c30 GIT binary patch literal 1315 zcmb7DU2oM!5FPtE7ckHw@{)(DT8W42NapKO z%6~KGx>tN!v8qoiccO#(%XCH1e}2ECU~liJ`Fy^ujAO5?30!>YIvtzz&Gtgo-f?A|ZcrdMtovejZ+mC# zBzin_R*#1Puyix}X!^_>H*S2dP)|J)kh^<#=DA5hU;+M!bC|V|Sgxv|3z3a8m;=C% z&ORXVO`I54hECU}vZbKX=gd`WT>SZ zX-3}rSm7DW-$ZAy3B5|F-xOSjoV?xNihEq1O=RN!0dCw)sLY5r2n_=|zQf505~LC! z!P%P_oR1wH45&nd6pvFU6U$d&!l@r@Q-o8ajEcu*%S>Q#{gm2-^kAF9-V{2AFu>bK`v<_lR5H#;D_zFVa zjpPm*CB#dRgwO0FgGr{l}GDodH|vW&A+maT6FD_cQ$)DN1k!?|}KQ_^;r z@s%A>KK$kA=-0(TL@e!>-Yq2ZJ>1X5ypT#?VFiIRO{W=FdQikxgpjgqd<{f!X(8r= tF(262$mqyz)If6Wd)FBGBP)xMjwQYvS>$JTWMogk1<`UkxsiO6z6Kw{EL8vi literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/lib2to3/main.pyc b/PythonHome/Lib/lib2to3/main.pyc new file mode 100644 index 0000000000000000000000000000000000000000..70ebd87996ea15a6c47fd30c51ff92e862f3f7ed GIT binary patch literal 9681 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 literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/lib2to3/pgen2/__init__.pyc b/PythonHome/Lib/lib2to3/pgen2/__init__.pyc new file mode 100644 index 0000000000000000000000000000000000000000..e2df8002a552c58b5ff8fa07e2c14013fc5a605d GIT binary patch literal 159 zcmZSn%*(YSJRvxl0SXv_v;zVK0YNsIX+$k$Yeke#qvO|UW`v>QcO-}l2J*%aSYgmnE3e2yv&mL ac)fzk5)Pmmo80`A(wtN~79hJAh#3G3mLNp{ literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/lib2to3/pgen2/conv.pyc b/PythonHome/Lib/lib2to3/pgen2/conv.pyc new file mode 100644 index 0000000000000000000000000000000000000000..d3ed568363963aac7162281e4f2437b4d9b62f52 GIT binary patch literal 8099 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 JUGZ-&{}<8IsAd2F literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/lib2to3/pgen2/pgen.pyc b/PythonHome/Lib/lib2to3/pgen2/pgen.pyc new file mode 100644 index 0000000000000000000000000000000000000000..c008e69806b282f1a2797aa782f185ffb2c58f6d GIT binary patch literal 11693 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 JzqQkR{{(TSfE54$ literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/lib2to3/pgen2/tokenize.pyc b/PythonHome/Lib/lib2to3/pgen2/tokenize.pyc new file mode 100644 index 0000000000000000000000000000000000000000..ef5a3f1e9e5fe7e1114e328e8226ff50778dcf73 GIT binary patch literal 16570 zcmdU0TWl0rdOp={H@L9@W571UKw*Y)+t?m1Gcdy)gJBrJuw^`+ZMUbl-BmV)`$knY zwrA{ImdV}}DUl*YtCb=pk@B{R6m6v4O`>F?C{mP%yhQsHX_e=^B++W6D9Y{o{=cf* z%rFy3@)Ar{o$G)8^Pm6xw{trEv!3ja=Ds#lHu1kh_+G&ic6S=%8k5J{GI`6mDU(kb zH*MSwQ%RdV5}NKX`3^~Uno6gsW=uX~s@qI{o3Yp;V=CLt19zKox0_0rsb)<+Ypi8s zydB2Nnx~ezzHrdwyN%av+%7ZdX3a|41k22Sm@6>SLlGxb%BS?ju(H`TfS-Yx4cZ-DmOx#@%o7gU0PQ`2)rsF!@)E*K521;|&_` zfbm{2PeF)-#vL^IS6Stv846Q|5MNb@hm3oWng0A?>3zs}huI`=OAqw3je7`)py-IS zz#DZ3%~Mc($he11{-|+nlYh;)M@;^hafeL)b?J=q*96wEWKs3HWOI@oHg3+iBgP#y z?s4Oe8F$>c6UKeRJnb@hl%Fv9QE7S7xTmD!ab~>{ zym8EFLi(SU_nV|CrqS=dCHXT+o>O~6iiFVKus}W`3xVN~Q21yA_?-ZI(s-wg*I^z3 zGKN6*nDJgWOC5w?0MXwx`L|5|jLDxhK4_sWkCNiRxhc)v(A-VUy{oxfntM-kw>5W1b9Xg2 zt+{)eyRW&gXwK2xjOHGgGuV*stbX3t&zycf(9c)(lQ(Db?-(DO;+$CnKYtS&58LIu z@$ml~-xnVLeR_@!E=YrKZEbKt8(1B4?yAXOH13-5E}13Jbe-GksWD&8UpDSXN$JO} z(ksT@kezqccvp?PX+D8GnKbS%NZ~c({-SZeZQNgKb+{g{q5I2Rv;35Czb;L08270p zZW{L!NxW;^Uy;Nu>Lmp8j>kZ-McZOgC$c5vu}+@%|^uw?NvW| zNEji9tS)*%crKf@@sDr?Q9D|1cy=!I;`~HoedIGOaxz`Nw%o1=qf!u|#Lflv)iJwV zuQaPQkgVqVWef{E+XJBcDaA+ekHR(_4;}vZQ0jrd?AJ;aB~lJ+Bgkg40HCewh5mBQ zb4k)_DFVTX+iE>n;m|RvF=Gfx{ExiA_SQ<}sIoqW1eY)?%kM{I9k$02tFG5O+l&uwzC0TM(qn~`iOz}jNUVX5jR^TASu5m=q`kNJkwP~P1- zm~I2|=VGb6l3i-n%Ce6+y^1TeE(iW1h+SH&Kk;l1-6(}23qmw21k(wyn@fQmffALgQKV4`5yHkY(8SMIqlUfey&Bh5NLOiC0A}J&& z?nELIUc;p@+;W6$LAltw-Ay|B+<{rhr@-!!f5XDxk6zg z&Wwx>hgvtZwN5f4qeJ1bXZmT^jp5woBg4ZZBW)PN!*R<5O5Ab?Er*8KGJ!ZW6mpx) zHy39oG4sG#xIB#BpDi0gyVs@NY|;wkuRSw?ILj$K+jNLc6HH{Tah5aUHZP18MlW6# z>Rh@MCoWt-f*gI}l6;O_l=?T`h>OQB$%@S%FN}}AaqRUg8y{Z0aB1P>*rq?)=2q*RCvt!#W}GMm+H^o{~Tv{#=hQnVIw$5-uP?$qghTIUrzx zB$AS5QqoLH7L$@imXNEO(oIuI*tTvT@z4K)}$F|9&?pEW~${FhHKWuIQ(MX@mKSpyyO?- z_L#5aC*wS5qV;iq%w6l9A)ibris%8=&{PoAgEETbAC=K09${b)9)@L{85Q8%45HwQ z#Tu-LVo_iei&Ypy6=by)p-AdQ^o>IW|C@M(vKbRmx6DNKhG6D@1a1GKm^rVYt8);q z{|O$iqThG%#CVj+RuuBv@myp1RlGLf#iq<=r`gPyjkKhak?c{g5#)%9n?^6POtR2zYw~*-Q24`G-S|seWwHhz zl1<1pg2Z}nObU`A#TZbp=>Sz21A2`yAc_81Fhozby zR>ekd4-VgujuJ6i@`DhTe=_b^%b6Rqt4-7_(uSppTw1KaNn3p6m7~}?))Bqfv$x+?h_$(e-tP>c?VOOpX4w z8u=78W9o}8!7JM01;BF*uy_p&PCH*GBQuO0*u;i*?Zx%PQEB<=BT9_ef~UEZET1?} z4tI8YYb7)mj&4uy<+g)EHverrx(RyHRytW0Upu##_F@89mvhLe30kJ z{xLN0MD_!_Pmn-3*^&gp#3@N2l9iT3C-nmbRhg6ELqQ<(r^B%P`bXvSBA1R%=xL&e2q39cI?I%S_FG^#{P=awNm2h5V>E&n=Ycap(N5$fg0Y|Jr zV|C$AWEmHjn8`HmA%Qic=*Ryw7Y`GFd$wYk@CZG>uVY0~j>41~*z7PHh+W;5eA+w$ zrBK~r_JRW}hNxPKKuiof$HAO8@DlBJ6^=5(Ds|P%4*f7^f|X>9QlkM$uRZ7=IY(GS zOi3PoDedWU;9IOOErnk6lBA&qF1c z`#sX>`oeFKQ1lQ}RDYN~gMFuk9>V&uKDZBJph*GxG;KgNRjixPp+ZQgR8ou?p(02q z`3zSArA4S*yhRm9+i00ArOZmk1OlMrQ72jTYzoc5soL`KHiQ3jE&|V8GD?~tXM~>9 zKKZuIiNGK1NKy)2E6^>REW$gDQslgYq%4c`7E@e3St=j`ex91Ub8C7kBEac84!2v5 z#B#V~!h0ZXKs_NG5J?gEz1Y(3vaZe$`y6F&JTGBX5r@CT6ArK+7Hp5T+v<>|+l}-d zYZvlmatrMW?p;~JW7tucH5LP#mRt3xlM4_5gs>bRt+ z?j*a$)gKxV1wc`?_9++q`ofQBHNjHC0@+whm{ZRI`@PSD-7cK;W9}xPg;B{6k3Cb% z%cxya{S&Fic@+gL>Mnf_qkl>;I?8Pu^jX}mc!QxttTD=LDJ3``6t_lFaZQp;|-?*JcipQPWrNP6_`^&)%J!a-553>|A0G!g>%iJ*mAleI4OMNnW3l zBv+|{7$8?l_(!Zi=Q6vpOiVzr`nc+dy)yPF5*`c{7FA#fK;&!9YLa|Xst8}B^d-6L z0>=4Uj!e;HAPh2M1?~|(>%x0?3h7k02#Rhii~2o~tKHU4ymQ<`ZByN0d_^}C(RT>D zjgF*V#6ES#(eH9zBO;oJagKDWF=07aNmK_{SlqY;fejK7G zVq;wW=4fgBZBbuMrp6`QQ^AQxZTzGNZ9lA!zy0=G?;uMKWj3kaj(nURZ&hmBaS3E? zX*@2P`X!)i`|gW{kLE_fS9nHVFTyy{ zZuBaChVK82vXHA|(g&?qAUL}rFgq+^5~9SB_=G>j3u5Bi;1ftN(R5IJ--O2}%<>J9 zrQbA?O&ew*RKY<=K&Et(Yk)S{qC`0WI4A^L9Y!_S39wZBgpVmUmjNgR-T@3@HRZzK z*U4ZgS;nxeR`}40V7~9O-)*s(QMjDa-qO6C&vCxtZp^mj2f6UN$`MH} zyJ@R~hPZu`QGQtP+Dg2Vq$M&qJX6<1puuBmHwQG&E+xljVZ9m9dw|a)o<-n2Zu;;M z#Ft6V54N~q0*~7zajsTN>xo+h3CBY~517V|L_LVT9{4P)KKv(fq7v5tSX4`EeznPy zJv&-O6kVOi*q!1StvPW5GI(x_Pcl@R)T=T}b$3A{!nbAb+l#1!zXi88X)i#_IK=Ql+|UjiUfIVf zjZ4we@EYSMPMtXo0>jO$^@xX8;2!_k$tDLy zV}jOjECK!HVICprasdzZ;W5cty+s%{Xi)=4T@O8F9@kqcH7l}e3U0VPEAgfYkIr{n z_?EFn}xzTn?L0I?Bd2lU}pad3b-GLJG;ny6!S+N|%U;YA6BY=@bv9RWz# zbRf*Pg)m(P3KsRe-vghD@gWc~_~Y23qsE23_WQJaRNb->q$a%549rilF_D=Ou{AB^ zD}`m>7pq>vZq3?Ct-jjcAm_F$q#S%CJBMK+80gh=y0^r69>*E7nt8NhT!c%oM;XkU zt@%t}mlD|vYV;xUB1W1rei0l=D$Dt^GmDg*lQ~>gvDog&X`}Y1uHLe@1RkTV>iZo{ zy3q2&!ZMQM&}I==BAJ7XM#ReMEYn_uj3~WlLbQCWgzS=4FtlZEJ-7)1X1z(So+ zj~VeV((o&KQhQSwYgcL)YWy@>$zfS*YfkF~CQ;!O_;UEdW1K0xWaTvS!F?qrK)ffN z57=mlrKF<7Bo^U^2*!WMO@5N$-4GGH+ysg_l{61Pf2uigOQ8Gw% z>M3XjoUlVULWjoJ5n^4)b&N%s1pYiQCv5$em}6{=(l&7|w?ricvK>N)f-^KUDtAI4 zP%B;uI*Jk17#_~fONxpOZvmG@M3*T92<#^GG4zFqztO~kArm^q6-4QgxN4&xYUG7me}n%8HeJw9j{CL^)5#o=vAX3 zzOA`>y^2+jPh*EKEp%|UCFWU2HJb&)g zLJ~(to5bp9MJ$&l5>sPjq179=AGpE*(Y_s!i%#k_4^klMgBD!kT-;$IY*hS+Vj#?& z92uG5J)suR=+tvidJaYj>@E24zD5Afz@#qP(J28bR=4z9(vq-@Q>%ji$fPR65$9_^*jJG0E8Z~lXmEfF25pZo&Ph?;Z zZ+4lrKgq23$gaaC%tGbh8Y+|)RnC%VF@&A6qG;%{;SwW8!hjIB8*<|{wYkG=cGGMQ zKDJO4{w}2tw9Q5j4d$<_iN2GXPCIPwG8?;0&}rfQNWvo6?;V5!<%gh$wAkhC1zI)l|K&w%Y zG}@lhVPFc}M_+-p!#w^SYc3uYfQC~767_-BV0A#lqAbVI( z3hiOGf3wd-SZI`DQFh3pNTS_>M9dl?VuZB={62G-t^4BE&yYKA2|}VVAZzb7N`s1^ z07!=W0sx#{ui1dn(`yD-5UaYCM&{8@mI8GP7mXB{O(qsUusw+w55QRawXI;VTt7%F z*cC9>H`4Hhanl-?fweEEDi?QS8%svFv85s`sn~p5skDVQkME@CYOfKa@F!_*mc4|i zXrY;I8Ln#Dti6&3keGS?B?DVZ_Yn#iWIT7*{6Pnn86{jRlz%~QWk#zL^^b6AeLt74 zJN$=^sGs&O`R{oh2TU{|!+xtX0`>!Da1(2v2%VT%Dt8`sZk0Q2GVCx%FntOj9iYYI z$?QJOvLDGZvy z#?Ru(U|k2dZWd-L`EmdNtmlU(g1! zeh(c-OJFBCWlb(YZwZ&c`1tbpi!Ikc#YlM3!*H>to_i23U=ow$1rEc%_#j*$ zz06^_ZC|axxT+x>%WJ<05(1};pvAL?{H^nLbgAO*vDms|SwG{(w~fmL9;`Cl0j}k$ z>x^)z(MB8Zs6Dk-s^ZeNM0FBO+Gq$K4`AfC0$FrZ^(yk0UH2ARs}0X1rt{1TEG<+2 z@jMLw+U zQM>(_VR$D6w~^yv1k{%dg`gC#n15~<9EpB*5CO$V76;bL5A4UA_AF8KRuK}@i^g)p zLz=}GmEo!+G^*5>eFO*v%6Xu`J0?wu&%{AJ`aOQFTxq&VaLC8ziX-(rKs<5s)af_h zI&=2zcbs#`YBYjpbGWuo;#BD-;Wq)er=d&X{|63~;F5`*r=w^la({4kY;k1 zyt}31Xirv71dd9Vo~&GH4o{<1v!*9Pwp&N=v{uJW7rFe-h@@PN#_&8bil^f}@hWm? za6t$JpXXA@YgNy~6I+D-rwlwH$Yk{}jHpV!AjswBKbG&v!luT#lm=)NI}kz=$sWR6 zJ$eafKtkgvn(><=PD-)ILX8-_k7DOMU%WjgVGlVfm98@noLkd3<+uRHZ1@$s?{T=Jc)@GpNn|Kr1jwZs`sy7t0>d^GiVz*7HOw`{t_+vy-j%7wKao&H zBbBvEk)RoAQqpSYBkZgMMlBN_n(6&Fj>rofJ`OUOhCfV%1)MUqMubrHLUAC6NPa+f z^k3O!_fBgs4t_FLS1OG-R}cQO`0GP#i|3h)c=h2#a{z6+tk+R<044ZKu~jD3XJt$W z@;GTXI1x4b@N^++y3^`59jV=jll9@rSg)b=(bOT!Mjyn^tYMV%MqL_^v(|7rgKq}0 zv^{9M53L3eY#Olo1v8G!)P8wqr46HQuc8f4U3qZDk#^%dfRTGymSPV)sRNiDL@w8|MDE}+@%dZDpT7zG z>^)=ldd}V8)?HrQmc{rC|2^++aILmFvBeJ3&wk9I{^&$VtcsleACXo;Y>wT$z2y)a8q0&~)@Y2;IK z?|N%na`(#7mK@^!TXMH*NgV~?)Ee$HQa@5%+~+U5mMZm<3Rl!=hD5u;;us9u-l~?C z<18i8v;<)V*%{FglDuAT^7atro|c}Lv=*P1CJ#j2Xh&72MC)Gs(=%y486egS%_?Ac zGzd}3y>+8mtF0^I6^MZc3`|Rfrr7)%^ur7k2hW%8i!z*Aivq-wIVCO7#$1~A>C91o)#TKFs@8e@~ZehMxpZ&Usw1-EZsOEUIK7Rexip{GqnnM z?b9LaI-HR+!WVCeI17Bq;maeYI2jTBaw$cWTeu#Ic_9i1hs{qUL4#fOE&+xSu9E1^ zK<>rwW{GsYpf~0((R`6h1ep~71|Z3^&;oBjhNq!*wp%^vERGoPCtBwaG=b08FS!fYJWJ~KH;0{|yp$-1Kzh1yfBe>N5%c9S7 j%7FQP{B>oz`?@;%-rkk!+R=5hYhTxQc{hBYdDZ$a$#a5T literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/lib2to3/pygram.pyc b/PythonHome/Lib/lib2to3/pygram.pyc new file mode 100644 index 0000000000000000000000000000000000000000..6ae0adbf11b4e61c8c46a416895dd2fcfdc325a0 GIT binary patch literal 1369 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 literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/lib2to3/refactor.pyc b/PythonHome/Lib/lib2to3/refactor.pyc new file mode 100644 index 0000000000000000000000000000000000000000..3132fe3ae0ffa0c57d5df36e3de6b6e4e83581f3 GIT binary patch literal 23342 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� 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 W_#Ci|OG_^UTnRzT-)?t;PWOKsY?aFZ literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/locale.pyc b/PythonHome/Lib/locale.pyc new file mode 100644 index 0000000000000000000000000000000000000000..b4536a1a020df588a95c0b0829e85c5acebdf9ba GIT binary patch literal 50811 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 BihuwB literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/logging/__init__.pyc b/PythonHome/Lib/logging/__init__.pyc new file mode 100644 index 0000000000000000000000000000000000000000..8b2538ec4a54cce1b1febc75af8ada9d1b55469d GIT binary patch literal 56945 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 literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/logging/handlers.pyc b/PythonHome/Lib/logging/handlers.pyc new file mode 100644 index 0000000000000000000000000000000000000000..fb92502ccc925d87cefe1c439d6ea8c8f8b5d5e8 GIT binary patch literal 38918 zcmd6wdu&`+e&6qq6h%@`OR{A7c`aKuWlOXrKjZb3 znmaT_$8I*Zvq_Lgiy&>&rdaGF-2f??CMfzxi*1`0MVl1eHc8PINgJeX8lXiBG{v?+ z(k4hh-{0@t$B@#-ruUChnltC#^FHTye(!T;@Y_4azWMimZl)H6zb$;f!Y4g65JmMU zxH|@$5?vwU@qy^dKo%d2t_)`Jq3Fs`7T*$G*^k;qE-)a8$pilyGmJ z@JLj@uat0qp73Z?f1s2Q=LzFc{lTa)Ze2Q*zda(Lm>EATSoyyMV<+qNX0O?4S6lI7 zwOwyDx@kP$>BhaqM%?NwEHv8-@p83xy}Hn__m|dsi=FmFJWG15({1F5&2;Q)HEq=6 zPCLFdbtyja{E3(f$+Wc8X!lap*lqMWakH&=%M-0?dtqYPs~a1e>@2T!n+uD*czp6m zeB#L`j~_env&rM(KjriLO zv*#{MHD7!vikhEQ@REX;6%4T3nsE9t3i}_RSajjKNeUY-EF}KxT+*Px-YVmxt z)ktIBRpVNt+p99?%bjMsH(|9*cY5(squTDpEXUObE0XqjYErr$*PGo&t=C$ch~sm- zZ&d3?HN9~*s54X@24UN@AIAMqK7D&+hVVX7Wp1w7ZuaKpti%$9?QNq?J-~u3q$Q<|*1RQUJxWHYEg2)|X@=^JR&{NhNMu3! z5V6S@-u8`m;<>k5&8u&Re!QIl0Q)Erw7$S6RZY>*_R47GUOqKVjz0O!FYvJTlqT|; z&G3hnsQZ9DR)i}n8`t2&fv9r1eJmQHgUrqRfT8G%LeU>YQG1^vs&1vXkywOabSxYAo*0U}v6PZMzJNz-&Rt^u4~AtNEDZl~4iywm8$ z)ika*(ptB9wNcM&0@&-FBxD&s;!vn2rpGl$y`2QUi;6dq(N2^7=+!_4P^esMYU zv>(eEofFE|Ml-q_JH9JVQ)%a&T4NK-95 z>KdfK+iTWVTGejerFW{W6=s;JU#i|bwbm0Af(f_^2eGm|*;#R#Q)Sz&7Hu*6#g6Xf zbyef#ZUZ#h=q@$e;A)@nJUQFEai_*grM7MjAq63gZ0$tug+StF8n+wOF8o2>v1U83 z3(~OATbzi`&G&VcLN9$bKJL?!+CGn0n=m2iO0CvN)8;$OOI!msdX2oUc4O7yj;y^! z>rE=Uvs~>h8UYGxB5uht9*wVp_$)K<*J!7(V`*O9p^4*%j>d;3P8^CGz1l=vU1rtm zOb4^p>`laHz=w^SRahUeq*YSw8v{%6OkSDRLdl`!*!n|`L)1FKT+z}Ri@Yl27%#Ag ziiEt5?3MQ`6r_7c^t?Jj{^J#g?7b>r%+tBvx8LX6c9iUb~Vj92O=yr}4+n{Zb?2ug$ zFheoPK@h>Tp@Rf$;Mm;oe^#H-q0*K!q-k_0*{%Y{Z``feJqkoEk{tvEHTc+sV1#0C z@o}c(ZZRDP#dHWG3So)d7#cjq8|OH>he8DG_aW>CSYPN4KEiY4xbmUO&7X{5nN*CI z1JPZQV+W%T2cy%UUya`9!4tup6)`3IL9FFh6ggn82StG4POgoJofNa zn^ECv<6w+vUmFYjr#PS+uSNX7tnMHpZ;1}TuNL)sE&uzLwRp=`PE9>jQ8B8vH)>F| zKP1LWueL?$OU6!Z*ZlCt=Z1L-7c2SZp}>DC#)tEUafW z*=9;D+HEYsy@jZDt3jVtIM)HYIcyu>WS#5{QeQgXw(t6UdlPWFiyGEc%fkfG&?pSl zcG##GCh9Nk1ge^1vx>i6pZ;Xpg{CX_1s62jK4) z(CQ6fYJ9N()T~l z;4)B%oyB$PSi(D}s%f(Z0bWC3Za^33okFcFFSjHn1>V~!K&>h^B4fgZq#HMDjS|9D zlE`x0YKpC2ZJWUJ#ZV z*DV4E(z5l3RGZB1_-vobsQ#sNVH02>QQ#-}1kQRF0I&;?*jqVN*$QVZMlQKi!F~k? z6lk+J11*?JR726Q#XdIjl;&WTPdY*{JTzRnD;_=Av$waAsB2`jKlSVspY#GjVM$V5 znJp9#ncAVJkyuTrAJEuTTWJ7B2w;guiJHF@KPg@vb|430-qzvNkH+mzyd-rKnvQn4 zoK>y9z&((By|LVbYY<#^T8M^70qu~4T+Kc~+(^`Z!}dQ5 zHf))HN~;nwL#`-AX2=o|G9Sq@k6Gq_7}f92GH=T=Z_hISks?AzJCr&7o$L`!EWP^U zsD7{Iq*uEwLPK|0gob`OWWF{U)%O^I{P_x+M(-E`rq>KLtM7}h4@TX|3S0+DP=CLl zgbykuiar<}tnZJm16j>%1bTJAgre`avUhDL3tkqu%c5+8xogJpn;?#|HFfZ+PtOiw?feWbBFPO7G6-+MPnt zRK`p7Y=87#UN;(Pbco|IFf?r}nt|AifmkZ-!Qr=#9bP(ixITCI?6Jcajvby!h4sGh zcK!RFe*YNZi4e|};{N_&tLlO&8B-yg{;JXk{?vNBhO?E4R`PZ|@G_^3v%GNb z^z^w`&(4~%)6i8`ODd)3#wxt<<)-kI;r;Y1F$s`MD{M*^SYfE+I@(>SbXFUU>&R01 z#y1)LNs*jqV8t_@;oqP(QGk}$lnUX@NCEtSX{ z%+OO&UU{3lnQsri_-88R*cV?IjmCwmOH8ku(vGUKp~K&|v@HkDaBM(NU( z`T6EedynXMp^AROlsD*OyFKYE7L%jYWbfXPXl;5WtB-nmLRbv>;{0W1&$uo$?3!{Z z*ujZOOgwo|!65>ts37b_l-S8C=(#6CrV=YXRM#bqST;8&d*f=UBtd+S9zUa?UxG-a zfV6e#jT7612J`1BWv~*#hV4R>7~Nr^v1>e)zVBBm&wB{(tn9Bm!e_tU4D5x8+s*s^ zFm|T@)TYsrOse)95=9Ilz{?#7EE$Ll4Gmaw!gh8=_#N(zz20347^{0ua|Y+;%$&5< zyX*}J#n?OENYewddLJ}TY={`yiESYUwgIz4kcYuOh!6HX938mpeO}X_t)K_gwq*kv)6ne|NEp(x-P$B0(#hEhMz;4c;6XXIEAk#S?TDVE!W&;ODP~MMt{c}X zH>bnX(-H+WDI7m!&h1%4JXn-CeIKw2Nh_6 zo7#egD4U|>PT;jmP10%p{{Q@wKUue>9kdOW4XR%vvw?9kMa*{T!jc-c-PY>BJLgYx z8D30Il6PECW}CzW@SuX4RZ;Z?Jpd}UM0l{AezvpH?MdDW`7bov?8EY#8C2!%y6vj2 zZGE=9VFbR@+0NxEDil?K;wjs{CwtapJ?%|*RxOd}$zGOhiPd@?Mbaj==^5Jk9X_VW zjfQrNJUB3l47IB=rhja?k;>TaJ;ZnMPx91GHsu&h^>!52qXWZi&0W4NwQNE~wk?kk zf#G7Dt{4!R1z25Tf{{WHI&2aU+j7Q4fb^Frl7rLfPa*{cF$c2J#u$c_gOv->d9`6& zWQY)j2&t7DUyW{D(ErQI1xi9)q((6Yl8w%76HD3sR^&ay&48qJ z8SaYJXXIzMMg2KOoG(QIGFl~ADoN27B#Q)2qvk@1s*r}ci3-|5 zAu~J}I0?q$g;wY4go3g<#&-6^xT)r1x@QF2v>_=nc`p%rXH>m~Iui4&u>{Fy^;Qds zs0`O24CAU{qwCjX?G-{yF@+nEE=ai5MLp9%rLi8;-PnVuykO~DNE=AR$ zWo}!UEL-v-Z$CMJ!evJhs-rWK+-5tcO*R`Bz}`P>5v8MHit=xd`rL3;;A>1pENvdd$c91LR2cl~@^!V8BAMlCa-o1Yy%+{y| zZ8OX`m|-MfW|)jHZ6gCdv6^9scG4Ks%Z11IFW$@)M7?=wyC-V6%;~I`%7j~aaC@)Iy0>1mam|MaXF`8 z-JBaU*-9)~@+J$?YVs-_@=y)~l z%}VaOtUSVthTYR-R?lw`d~#fwh;@EhxKV9JBc{BD&DslQ%owkXwc3wL+m+b+!JvC9 z`;>#&uF4$)kN2@))28UVm3Gsp${7@O4cBwpWbCBn#AZpoDF$J&kFD{XpzPQ9q#}01 zTZb$6JTv;@=#J3?y*<3REO2YoMH7PBvBq2b6RJPOCp|$xHwxD&aDr`m5Wq(`HGU_z zfe!}5jz0;!o3C5hA};W+27|0S46Isz+=4E8XJAgQpf`sXT!d$=QP%>Sl`^t3x5Z7$ z-f8HgO%`o>_OvV0JM&h{N-Bpsw%BsFv(T+Br7|fmiUoy>$I>iSsw|d#n~Jre>dAm^ zLE3SvBUiV&64t%)Xf=!t8z~xBGZhPuNRz+9Q#XFS-Mr}-VEq6!1-Bkt+HBX{5`gnr zFP2M;@8%2wkD3)5I|A=v*@OFu!h$f{1!Bo zX6bb^uCQOe9x@m)`#J8C`Q3{JcFk5ITW@L-wq#AZo#n1P-V6ka$+?Wn1D+3X`@Uel zS~hPXDOQWtzUV_+)q${O(L!RyH!0YkkM;SMsZ0S#2pVz?z?jlnkrM$~Yu8is)>`t^ z+@2h5qxF`oVV%$-I*?>5jPW1Y5w}Wd#*fB0Fygf+Y_C40D55~sbjnuUst6W^fa?s;n-!E&4ua4J3*h;F|mA3bK?MHK6@ptm)M3+Z7u(j z5V-~%;hu+jibs=y)pMHz1sWC1?8_z%+kknLaF%hdObl$%L4BcG60-zvqj0M@Nt+5) zTsE}DJR54C*9eWV*CuLr5)z_B*^`!nC4!Rcnow_wG+W^OkB#o>O7x?}ctuh=wWIDknVjk?(*JU7#99O<^`+75>;6F29aC*P@8 znrnaDWjSvAiYC4=Cy)bH7+#y&gXsB925LJ%yWn*Gp?n8{IDGM*u!GeQ|1f*7-Ib19Taj3B-)GbASX3E+)q09ae(CrnFVfQBfe{ zTXCOaHwbLo(%dEhQ&s+X0p`6#qV0nN;+D`O4{RMcR@pVM1F3Tqh1Tvr)dp-`wGOJH zP4oo)MbuSKMu-gW9j@%zGP(uP3uFdOX!OoHqf+CA{UPZ(BlH%LMn5C;5s&C`-G!2a zAGhL#V3w2(Q{M*LFIGk+jpat*{WNA!QSeLddmh*$e78_?!G_o=0avL3d$2&u&DwRC zA+ah|c~H5ctQr7Okeu4++%L@IB3x#^H2|&Fx*fdSv&!YMfZi}ZVe5Qn zAu*5TN0Fs^Jsgfv(&8(RUl(U5x@*?6ahz;GumEQcZ5VML*A%F<^m;XTp( z!x)M`6w8~B%^m$IWi>5TuQ&3fcz&gAWA$mP4FY}o2plK*q;C_HDL1luMbz6#wbN|i z5#@-HDzKs=B|A7^t2fvtoV1%JL~lUQTR@@0DCsCW#X4tzfM048v){W+s)m~Jc)p^6dL=}nSEgO1sEIStG@ue^eS}XnG0;-9dQuV!dE1kQVLn~unJ`foR|KIQAWGrKzb8Z~NiiCc=o|jw%{5vv zt$I!1sOI#U-lAPY>*+FHz9oP2F=W;U5RdBM_P5CrbY4`^<- z5(E^P6w8w@nWcw@5&_&NUpecpkjad7?>DrDW7HIFxeKDZ8#Ax*z-m$;Xv_AmiTJX8 zh|R%p1qxkIg#7Lv4on}`SI00UVI6W~QTNxQHFIlmZdnKfwBxv?5?#LW>vo8RCDmcX zZ)FEp^18od3y%4MayWiGZI5ns9d(}(fAA1K67A{VwM=GART<;_1U494RZS(L(KmTb zFM{3bpEJB1Zf3h{0txpbkE;QT2p0=aL)IEMmvLg!`K*>{@jCPKCO_siR3Udap)zdF zSZgJ!T5TgxQf<xTH;)k9;{>=9rKYk?W z8>Ha4+Cbh-TRL|q4-JkAXj^BVRECLIQ)CTOlT8s#-dCX2Onz9w_bK>*z}P**kIA3a zqe@u6FLAi1Q%}CgbMpNJ1=27suZ{ zlQp}E?;6-^dNac)8b}VBzs`eJm-R$60URCLKn(~DT6{|bwAOBlLk(FS$zTby)DoV# zD6jx@nHdQTNHc@c%@@pP0B8rgekLme7Gfg|L=PyFnc)zM&3%DZhRj%T<7#yI@{Ml+ z;^uKI5dYN-#Az4}y5wZ1uTexs1It0cQdA)Q%LF+v%!ota2!?TTCPD}tfhYlxBd0zZ z3USML1T+hr@9-mvc18q9gQ=?PjE3lE4WJHcu}n#xH_Ji0Rrv)_-PM(Jt%UWo{;Gw_ zjq(Krroonh+K-bV`9TFgq2MTi(=!Sg^d&!{_mVS8lD+CO;wH8)?aV{YG#RbNeCC1L z-i$Ac?2Lby!`N2f3NkeaOzp)0F4yDzX4TpaycvvXbZU2!Px_Y#SZrV{AhpK~2w46M zM8rr{g5^a}MrJf54j9BuBLYxB++I{xLxC?Mm0bh1@qi`)s3QT&XTow(*@)l-BNS-c zjl0ST?C~F;mB5Gn7#+-)?2>_q^I#A&v72zLS3xk~BNqW&--Thp&e`Z(4+cdOUh`T& z1Ez*TAIN!{x_gE7a4=7onw+$eg2_dKGW-eo=r1`&hiu)d-343>HHo6oFP(R+WDE-G zHjZe{cakHd6zq;zc1zE=cOzIBLN35BqNQ~b>4P-py3uH61((*$9#A)0>d?uYYyzK&f{LhmzxL5eDmRyC%V=d7{3V>`c2hxHP`jur zgM19eP7w*X>hS8VL56a0lCDD=GGT%O^(stI;R3ZxDx6lIB)`;)Jv)$*9uZ-nyE z$R04l_5s5QS}V0?>orScEe=bj6)?q@R?w&dkKu?ev}7`S6dh+H`LT^979Q6y^38^=Rd(9`B*bbRxG^HlCLn^iEwx#*WE-ihcCC* zq@;%u_1MIkOJnrB)_fxw2&R=6X;nYw&iSW*`^4r~Li zyVDktM~6?>CMHRBpUWp{XpG5`>2vqMwu-Zw>rQ59|2V&CoPe#~SM<)*mYQ;>{X{mi zW~&tYMaE+S=Gh1#T0g~gv( z4Q5r{MimAYVdwsTs0Oo6=Xx-$)TCA`CXnQ6q!UyNhsAltjFhtAxe$1XoK}fY&$&;h z%gV5q&=G>zAYmeSbpyVrSRqiA#C+cSPWads9qqBI_M`?J4eh;!{pwy4Gy~Z@D9$9n zMKT*gJlYKD3PC=4f!{ji33}HV(-(xTB!NH|$e1Huw<+J%LTb({s>ZLMzLe?V#!c~Y z`qkv*h0-MuJ`o?#d;)HC*ZLx3iJWf|wf``cF6J|Yj>AYfFA9YIG7pZ>LBzKeAyHrm zewe+?$|?O*AK&$DD$2)xTY;^b?Q_=<3s%e~o{MW(nOhxv7`RX4;|gwhtC;|YqOwnL zLs_b&$Ti*zD^+;;9w!d*u9PyI!yoP9xa=q1Lp| zhR1N1-a0zs)}XZ%W&C=&qFs23PkJAP*3lIwDo#;!`i~p5aFpR@4V3Pj2jtKnH)tX1 zaf24RcFaX6+PQvcyQD*I=TiQimVcM!=SnZ~-(mT292||V?A7^zEBkcgmhR@_>M!o* z;=(W7`gYpgT)XUUuHDfU?&jixFYe~r6J5DicWCK4F7EcaKWc8bBZ_xM&o=1de*Zea z7hSrGF9_p7zUcVf{&f#uboySt7{Psfk>!5A7}W#*6-Uorc_3NBE-nV|+34$N6Gnj`GE*kMYGIC-}l)@d>`T zg6v7Y80T@m80ZPU80k}dG1RB|;;OM{=vb^H3Jk6OZ1gOns6WS79Mzxai(=oy7d5{? z#s{PNXQBpIiVZ|+dNQiNXbw&fNA=H|o$hc{e<`~1NK}8>9v_YBuULeOzfM}@NK`*% zk;i1wJ1sCd@SS-HZ68zHV6~IyNM?6%sowO7)!4n03<1~`T-^z~mdYGLW~xhZf-x6W z5r(qh$K*Dx7p%l$uebcd6HlzJu1>V2P+a2B<^-PhPo!chTTl3XV8=KN^#o#n?Fp}f z>y51RWTzcWZ(J#|7Ed>89o&&{XzINik5}h8Um7$_To_`mI8IcgxN^Uv)H@+ZB-3ij zOc-c`kxuu`XD@9yQljner`fbMo1+ROgEytZY>K&TN>XS_QfP|dZ0=JaEYZ~A;pPDX z(*jhvW6gC2+*{REHT6?<&i;Ty3Mn z5H47)cH72@E5fktWp#xk`0BMHI6b{%Z&9YSt)hCBKBo`Cw>SS_m_T1#j^QPsq-pKG((|qZp zaZd6{|1p8HZiS@e6j z?n(2Fp9#8NG{%Z^?#i4^sGaJRALkPM)p_Zsb$>xG$#%_*9#%C>MAjGTRT(frwjWR!PWl}XtE+7eIUHtm=xi>TBihL|}9aDpt2U84J z^X6=l!}jN3&7qkx@fr_JefH23cnCg0;X_9bnRW&@I;%6Uhkmhxn;e2z6aQy!ZCU4z z#^*1-I`{g_RH7vB3;89unhA~j2sLv3^$jRUwgt;4r@it^x0K0ni_ttYA{TWTQyNGlzRh3!$biF6}Qc;a$7A55WnaRdjTBPEz-LwL=#S;7#ui^BTY-pQul_k5UJQ;;?> zPa&DXnAxLz0v%H9afONSe%QTWb3s!#SG;%g&K@1yVYW^Vx(1^SkT~H~#F{&Dk~np)wssv!LUoQkTkgI$WJMNDE>zC;6m*K%jk? zDdy`@xCsO`FZ?>%dhKVs96+I2X~KRUh}Jj~VX{zu<|Mn%5QRj%z5wjj`rpX)stK8)O*w7?xkmXIg%TKJ7?I|F-2xiu zV0IRguq7<4Ew-#B0aR;f4hHPnIYEhb!6ugSH>hWj^+_Kg60u;uc!MmYP7UqAiU$YH zau#n=sj*%>Tz~0s8s);fme`i}b3~v3;BK_^LhF7lA_!TBgX}&7C8J^Wet?JRQvfhuE@?Un9WTdv})f*Hm46v9w9uS9O$ z2y5~eZi4U(J){0aHdY~>WR!^{tAEbUZS)CSS!*F_32$hzNVy89iH=m&38|Wp-DxAR zg;O8FmrHmx>qrT`XexcT{!3!XuW3Se67=`RUiJ5)1RmPmhHtVQpByx-0lRv$aVbpg zg8~$BY!Svdoj~1v3svhml6|Lr2td8-8M5WH8T8ZG_1*2=|LhJ zvs)}pzxp*j=7{=J>r^K+6WggX3Odz&XjE&U#C|_yF|j@uQf3)kvn2vlzm^FSf`bdy z#d?!E!KI>rb0Ei$_RvbuFE&n9A_!ClZn;oJWZMA&11ol; zOAXo`+Ecd}VsWm6R9N^%VV%l&2l$gzmm-eqXoXxXjz4qa=_j8*UQ$XWzsO{p?#b|C zK2P+;_;9R{g=Wh6Sk3Y@N3u4tIV7@BbG9>H5Iku4qY;CGA!35INj~XkS!jm>Kmf=F zyUFLknOfI!I=AfVDp?#1H|~eGg%6kd6Ko1q!&8DI!bZ6;S@o_Gc`^F7X$foRkas zA7m|YM$$NM71tR_yAww>a5+rqf?a`&Ep%UIUprjk4?0;~fy)gzHcxI})3IYQ5B(?A zZ)abV8Z|)&0+7pjaQM7gM7MwLWZl@a!WPuvwP@R|y-59s0a&TZ@Fx*X#KdyfC>jiB-B&bYX zm`YyFpH7~iN@k75DNO>Z&5&hG5~RK;QaqDqMYiherp;p?wYUdkUP z6RHz!QSGYkQgZH%ypA)om-6b*UqmE-vj6dT|Ko}N$EW%qpYDHrrvLHT{>SH%e@my5 zf1}{H2+UgNBb-A|J$LD15>6^;1`~mwUHJ^gpYtumxgg2GiNU+UsNnrm-J<*rDgd=a z>0c$nX~^xvSb$6a221hp^nPHF+v;xhZ*1^(DI0T-aj$gtc5HC8vg?7-d$Dou7~MWP zW&k;JVfNB`{WH77_0LZbX<)X5KoCM7Fl6$-5`E-1+7Fl_63yqJMeHhPLyWIc&^X&$ zTQ^-Ji43jQId+I1%DfnL8*@&MOTHU5@%Q?uXGXw&naFyrj(bdjBS7?Bd^{`JsWJ!_ zY7|cD+YMk4IXhXEy;U*vK3?p);&11=9g1=34w~uwjYr1J3D7h-YV4<_vsr-nndT?x zZ|so28istKR3d_o+SN&@pmT%a4#t!V0VR!&IFm(;Dd-i;I-T62Xsk;ntfNB+mlE3z zTk_u!m*(E_;`@1luktmHOyq5$WiXdyHDpU*TAy5@fnKJ4Osar7Y?LpQ9LoDo6NsLS zOYe5n-0zRXJsp|O+{4&n)=RCgyX$usR`jzG<(BgPNRLSx8dD=|xOHL;lzS{X7ae=V zOSKx0!wPmqglG`42&ck&Xf&@UYqeAXa?i$wt!q>#Yg84AiRQC#Ai?RR*Fg^*kI$Z; z;owImxK)c0T6r&4u3smFrP0az(`nQ5px$wI_x2+-0nG->t(|iCMXJ<{=9Oi-B7D!_ zepy$RZW%qA*7efJ|!Liy|&(Pf*JT!HAWj1gac^w!GWl!9`nBD&^UPuYn0$ZEEeXmT9O95YqNN)C) z1Zt{atJ+9Z24DF@aq>ZUKLZ&{&Y;E~v{|%CT%r|%>2>s+8f^<3#yA^aXDc+9dFU&@ zGblr_)5(Z}Q3YcJhFnV^m~7+aCfF7YfEzKwnYP^$aqq;7S)o*1_yiK_pE3F3_i4v* zr1}Tixt3{p(l7HOU;O@Ca>7^*3u}!XArz)%bg*`XxLs;dQhR1t1z$d}Nq*SM`Q2mn z1_z|Ii;Jr%bmI<&erZd93O`d(h>I=-YyJwsXpCSH6i;qMo}ui97ve@tG(;GE!=)>w1X3?-EUhahzKs^ zs0)8fqzZ9|tQE!lHkh5!kA-JXL8+lcq#YV?L5k~OBnf#!CXy)`;{>-AYp|5Cdtid| zA?J7xWWv!?8-ydS_$&!WB5a!66qccYw%Z9uXH1YWR2pO?BUM06+4C^74&)TA5l#(? z{@7{oX@eYFb7$;yw@dOv>W2h}Gi-ES{J4Xk74q)@7XE;PSHojF#=&0L01|!)Zc_o)SX~+m-7GeQ*TvdBqG%>{PKLNQaHL^7Sk`7c*-B1NV}^3`9Y)sPdg)0^P?DbRP!rZ+9n`WerVPtGtT%y` zgqZ(=cGL+X(eNNxNJqEim3%)qX^@yOliuk9ISEz=`L{C{s;qncLX~Tth3^uZ8nsb$ z&0-(h<6?l}E~tO1Zg>#i>3DS1SpVtSDV?i4ztQW0?9TOmjz}NZi%WuGhL8Gx#|c*W zBiLfw(~6h}h9c&Kp@`kQEKx4~V>)E0_d7Af#_^gxUMP5aHny(nBqu+TRmXJbOzQHc${~@#Aw!5o9(AgNacX- z8LNCf9uEd9EXY-OOpH%{ePgo*$~OObuc1|~H5PRnP&YkN80@AyZ~!xcKgv{gG2B^2T3WXB4t9w z=_Y=qtZP-e-7dQjDP!j}&o(8nLe_`QYCArC{=AKD-5e-y7`&hKvtL+C`{<&^8+w$F z#`|U1<7BZgW~declDsr25ILc}4Ho90hY1H?L%#lnN zMQ~--kIUExy@9|8qZ^HJtz7Zm^nAK`8TDLv3+DH?&^(AkP~y3)1648wxa1hGa;G&; zDwzYduq&CdRO1HYv`8b_6Fplz?DdCzHby*yl!C^NZ1@Ki4|oaD%G_Pp&K|&!be}CEobsiNKO8!+7`mj z^941Q=lK=o`Beq~Oc{mVRkJkRQhS}VAMcyexe!D1?rf)&rJJMt$hwn6PR;@LxYy6U}`=&gqRMK-d}JUcJB0V3R+Ama3jfgfPp^YsRRSQ;1YZnIwfix zAfS+-F7^pNn0PhSIs&d4&9p88k62(4>ceL1QyYgV&DT7e+9yjBC8+-{O_Z1~CTdC~ zc`}Ucck{{GnhTq}a_S`%BJ#k0vn%H2Bgjc`4*$K|>>{5*p^JPMeahKWUF#;!e3tXs z)7fe_kNbIS0cB9O;o%rCS8;tr34C>J1iPU0D`UlP@n|Lcw#+&XBDCp8Xic+!G#0ik zwqL-hM`J_Ornbxc+-`$R3|fNW)F7&?dJ0;i>|T;v$=*^K8DmDzQ{)KIwDPVm4fIc$ zqyiA#Rp5v)`M(1!oJ_IGEpDZHM5z6{wT}%vXIbq3o`dE#15J@*eJ1&&Un6kP?0z{~ zyJ~TRQD=da1TW(Px^X&g^i-<*=o5OX%kJd&h_PH^j>xb@`ri+^%b+NIdh4bS9VxCr!+rBUvntEozUE`x+#cI#-f zuz28GVS~H~>BW+UW7)CR^l=486-+3QY->b5X-My8YvNRWok7odB%}HJR760~teYX6 z4k!PC$4?`U{-HoX2Fz%yta-W|Q~w@We*jO-8dz8-3|$rcc0uxI7+OA6lN^BK21p%O zL}|5AEB{t-3G{nYZC2OIVE*%z+CsVbCO^!)i6GV>hvc(w@|{tD{9@TaHUfj-GEJYd zSeV`wk;W>33``;Gm z?WFwhD0+{(N5@7-v9Rs6O>uU1qkT;vc#4nlsePITS2J*G!<>pgLWN-ZL`90?8SMQ)@k~o?FW>7A$x?BnNbh#3}i99NV9{TUz zS!WH~XzX&!lW!`H6LF;c_2hi+SOJHrtNU|k96!X64vF9$(x4CdWu?Z_KgBAVQcMZy z-SouE`tRBR_&#B=lBbP)+0UQx){e~SwO!b=-dOQGH6=P2W`~z-T35O)vnY52B_G%| zWqU^8`7FUFXKoF?@7GQcC`Ma$Bk1T#itk_?U=?%Yz~7=wK2@jvmt$l7_B!Vk&;prF z4(yciO`3F35QjJTp`7>0D=`fa_|n{4f--0F)pNRbyE+kzAGR~*;{J{AHDE4K#kyl5 zXE{%0@f`aPP<>GEyBdf@6#FRs>4s{v+u!xGF_w6DMci? zbN~-Q!2XzfG}TKSaSq;YcSsC%01MH}rhhW;sz(ef9Igdh!V894&SEA{o+hVxX$rd4 zfQc#(QoO`4JaO|FN2!iUYCi_L2z{_^ofY#dSM2IeW3P1rOEwCDCq;-l#sPvOksw1X zW~az2OrE1JhHI>QTwPW-`w2f7)z#rlZjl?MG>?ni+=6{qlpFPdU%{ijz*Krt>eh=9 z-XS!08`$dC+ar{}5Z#j()waA4{ZywMO}vZhun>f|)>uv+;l(D9p$Pj^+P_Z|k%dB< zAR$8?1JEx{4C}Yn2W6#@)0a}VRvzFNA~PGs?azbSynPz$gfzVe)i+I;ej#%E4$gzB z##8)q7} z!VjBL8Ps-OSI5c$0&PAVsQ>1vIlyz`=i52F5uPTzFi&%pB$d*-JiE;u87}T&d?l5I}booNuzByu;!d15nMfDvh>o zoZ%;Vty#4h4${8QvOjc>S~C1GL=PHSK-`xonGfW4WbCBa% zKOQC|rw^}vvr4t#lc-sGcSp8Cx$=?u^66B{o5k$uevEujh0c{9qR&{_4FGhtAuT(a z*OH%|)Y+NNHMU=RdbhgFOcwZxIW*U+@^lT-xS#c~Ir|!qpGvmXRIh20w5ho{K!%Hf zS~g8NPP?DPVw&JUP-uwfTz@UlGWqhkDK6F8sL$9qdfRQmk&r{zvIz&yiK_tNV_Xt_ z)Gxp-{|r`uA&sOY9DP@${vXuL2v#&RE`HsqW`x}QSDiI&4zvO{gWOMbSsa?P>uWGP4k9}hpcvN%xZg$qsI^C9S*xt@M~%Uca#zlJI@lhLc+USQb>qsCKnV; z6Kn#l*mUmX}_r;ADF;o2<`+=)r>0* zm!#X8*=Uuz$QiLdHNqAuHOZ!67?NYz1bljO_Zn4wMN=VQj)qG22jy6N2MG)qu%0Wk z126D8AMH%Ay!P+QU^W8+vW=P-aKAWTK(*xj&*s+C#K9aEe@>%OmC=wY1byD4S0*M)J}xuCc3Jb!9%Rq?pYO-D%#H zdQ%LsNMebvQ0@8)vcOmAyRC@>_7`Sj2xYWp{|KGKUg-@rL|op36+hkUJG zAxp7Vim?)6x48Ev6O7OhxUveRP9<9sR7(9za+;d*c`#Ce=YBuLGPSxC!Ej}MtEcbW zG9x7t=j7U^$~LEfHZcq)?!jk@R}Rvfz)q^=o0=pMa~+!XgJ5?Ige$Mt@e(G#{i@ot z-UzojYjIKiGXCb%*b&ZC%THvz5o@t$JGVp)kM3%Ih4z~Iney?+)TVBnNm2#YqYo5| z75ubD-GeEt0F-0b9~Ih=}K`y9{?tTLLHTT# zTDG%YuTg1Yz%r)h7>6g#eE~og`?zw9P1uWm z7t%{=-hS+Ac;I_0_i}zqey@V6AwpuqrITL+!vhE7{nPt@?chrXzp?+3ga7T|^uapu G=l&n?yQ41v literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/macpath.pyc b/PythonHome/Lib/macpath.pyc new file mode 100644 index 0000000000000000000000000000000000000000..7b81857965fbd21d6b5e30fd8257395764a4ac93 GIT binary patch literal 7362 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 L+NIi4wYmQQU)MoI literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/macurl2path.pyc b/PythonHome/Lib/macurl2path.pyc new file mode 100644 index 0000000000000000000000000000000000000000..0ad92dd51b6b4f16d5f2acbc0a73b3e44e047496 GIT binary patch literal 2184 zcma)7O>ZMb5Un0Nlf-d8_A{{*l$H=$Yo)be1+282MW77_#1f>jAW~RlCNu4%?QxGY z-3}X(To(Sz-Z*pT06&5M!5P7;9@_~45iEC2byam$clCQSmEV_ZKka?fNoev5@caCC5dU=>w^abt+C<`cM3JT^+UIc{oky4b#a(coKn#IgBdC zGYtDHERLuz=#1!lfA+>XCW4B0SmI!V3hU1I;#EL~I228h=*J+SV%N_@+BzpPo0Ew| zYuMSpy0DKvE^wuDB!sNc%b)42Las_@0ow;e#g2duVN+CCG+L5+ixl>IJb4>KW$5ze-P;?1&0yp06fz_Pl(=i*8*L7y&0>3`Y{Z!KEb(ylukHzEcbg1>h)))==0RD+ z=1@gTJmqS`c;tA}9T|ojztug=a_a%hh5a&Z;{zM<7oo|^q7@cvEN-w3<2pz(oZiK- zn;cxJdmu6hF@grX$W7Wnz z<=av6*mIYuR+5f$d;ZP{_J8(&2dh5i++2V}LzJ%s&fV>%dD87htVeetJjc7;ILlzg loFc9naf*vl|4m{4R@g4T^B;IzaPz|eeGBTr;{C<-zX0Jg#qt0E literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/mailbox.pyc b/PythonHome/Lib/mailbox.pyc new file mode 100644 index 0000000000000000000000000000000000000000..299bd3d7c5ec81cbf2ca84a1164b4079f9501825 GIT binary patch literal 73406 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 literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/mailcap.pyc b/PythonHome/Lib/mailcap.pyc new file mode 100644 index 0000000000000000000000000000000000000000..b5576b502558c32481d83fba0689715f5c066177 GIT binary patch literal 6883 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 bXPg4h60a0v2we7J literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/md5.pyc b/PythonHome/Lib/md5.pyc new file mode 100644 index 0000000000000000000000000000000000000000..8eb36a13303a55eaf49a5cc55fa52a56ba4b0e0a GIT binary patch literal 363 zcmYLE%}&EG40hTsV`E6uo*>7bCUM{dLLA_RIIzQ{Y7(@ywHo>}Etw{`@>0AP4*>RB z2`l;R&-Ujy@z2Hdd;Pj9VX#E}om~GQfN~7f02u%QycxgHGe2{ BP4EB! literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/mhlib.pyc b/PythonHome/Lib/mhlib.pyc new file mode 100644 index 0000000000000000000000000000000000000000..2c16c1f150dc8db614f6d77e0720f572cda70ff4 GIT binary patch literal 32633 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 literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/mimetools.pyc b/PythonHome/Lib/mimetools.pyc new file mode 100644 index 0000000000000000000000000000000000000000..293f900d485c520009954bc4adb00ef4a0ea8aac GIT binary patch literal 8122 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 s1758(yIh7JG$FoFxm5LPxT*#H0l literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/mimetypes.pyc b/PythonHome/Lib/mimetypes.pyc new file mode 100644 index 0000000000000000000000000000000000000000..add57d5b2d2f862c3f683b0ca12432ef2970f0db GIT binary patch literal 18162 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 Nj%V0DhP4N+{|8FC?;-#I literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/modulefinder.pyc b/PythonHome/Lib/modulefinder.pyc new file mode 100644 index 0000000000000000000000000000000000000000..60620a72ccba7a91ec188b1b760c17d61ffc2c00 GIT binary patch literal 18201 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 literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/msilib/__init__.pyc b/PythonHome/Lib/msilib/__init__.pyc new file mode 100644 index 0000000000000000000000000000000000000000..f7bba28390c1d88c41aa57c063acbebdc1e9102f GIT binary patch literal 18635 zcmcIsdvILWSwB}ROIlgBY{|ClIB{;AD3KjUN!m=(CT<$NoG6u7=1R7SVt2FJdnH|Y zwJYttYfGtJCbemqK0=|;KY+G88d`?7Fw?943yWvbcQnJ z_xqiD?`~vARR&n=o;~-x&v(A>_kHI(XPx`^UEQBQ|H4e!B%d6o9(M%WJ0zI?QUx1f6EC z%lJFYT;BL7)@^*G>@or-puVXez%$1t(0El?=*9JjNfDC_8Nbend>t_-UQud zG}wu!2hUzSeP(p7-}tC>pYeOm4P&kw^W5A%47@%Ls)`%R!fzt7yjWDXd=pLufw z#^0yNLF4aNEYCIm z9mc=k_(!s&yNr*5CyeiANk@&3)CY`zG)ubM_;;J&ZnFUT-;<@@WBftm4;%m9ED7&z zW@hL?tYP?Fe1@=&CT4KF5bwa($m#J%ABj5=n~Y1fZ%nWIe+aRyU%7;k0>&6_g1WVd?8 z@EsjMaMdwajVT(lh&Uo@az=A046$^~y4BK35O*N55C#=LYGy=1Wx->KAv`vS4k9*u zVJe)zuo8t8d=-mfHH?eJ;nj^8b2RDu9f(J)Y@EDPW+Z(yJZ57^%lN|}@z-Xq=FCFQ zTz8D)8_=Evv7_`zEse0Wx*Ak{&Di6JMaQt}2kRQArW0?h2HPEQ9&MC-zo?ntg_np_ zF;1DC@5IBNHQv8O3aEI^QHa5&W515#81JHE;#`u7DeObR^>;e9)cD27xsWs0@Yimx z?chYQqHn_c)g4@d-lwj0n5!M8{thlM>!3_KQ$UXcPd`%ysZg-PJaw&8u};Lg%+)Rf zieG9o_0O5Bou>X7;sqiHuI0_z(~gh6@}~MhmCLK#H<%5mK%MAoChj)x0!MVHSg2w< zRcwdDVx21XowQh&ijAsRkBXg8F|{1s?If*rs~7}!CnJEF=5#uf>2NN)%v1F_2l#WX z+f;#UyBT4|Ze(0>t^&n+&11|2WbP3)@&>6S2)QL^PO@|_O23)BvkX|;%VGz}KWlF` z_&X0sT1KKnp2B)0uWfpTQ1z!{6Zf&@nW24H??TAckM<)NjD`mzw^6-RtzD_Q^I;sh zgX@gQrKIofw-Ha3sw}x2GMY z{e;yxSPbeeIoTcbW8|BNtm+n~XWhctsi_FyV%(|ev5~3CxslPS31z=97`@;QMuU;$ zj&EY;6K-@jijR2{BeN6kEQ_O*JA~(qH+g!*d(M5^#B)eGHq?i5R@ylHs8)|Pg+i?w zfV+*U1l5=W5j{u_D|Q@>Uy4gn_+qe9iY^HVIC{NMj`&iH;(AzJ1f!(yOYC4bUPq!R zsK;TgI#I79ja{flrH1lZ{rRw3s&9aIlH6*eQXz)MfYr2oxl{>XR3cYNja&*gJiTyE z%eAmN#1@4g&AFmb@YUaVOS;aw87B zekKSZE43&XV$T+p*}p$8b$NNaWFefF>p>|F3W!B~HJIlvXGlQLkra!hc(EuBDi&92 zexrg{k6PH%nsSKV0|=VEDz>HC@;Gn`p#;0b$+zco`QtH}x_Gu4tp?=~`oS;bT_2*u zC>|9Lq^Y5WnI+Zf4I}2!a(G>X;8M-tk;rx!X-v|VOgqN(A4ahL0|saS!eTkGkoX(F zc!^pC?*P9;P%DS9-qZ;|x15RF%%v_Tf+Gl!sd0IFE?By%y#%ptQ)nL=0;0Vvv* zPePl_to57ofB`6wcY$}1prwf(=LnZd)y2S#mjX8m)*3;z9JtlS$~;i4w&0ekZmCT1 zc0kHxL0I?d>36!E zGDko-AscHUUjhSxst`&n7gmcZi?%?H5{gB^>oV*h7#r=>AXrxx*kRUBQc}k+KH|V! zz${=NAOqP{=SA8FHU&z3{fm@TTXX#4rw#1}WOrhLWi-%q$dh0T=nl;CN$TF^oiY#F z%mA{H>a100V6beDN_|D8cHLYGMF1t_w6B|HrCwF)aM(0dI7|xLG<0&>dY?>|F0&D@~0Vii1-W-NpH!F=kv0e^Vi2^bYKm^+wg|Hs1TCG1;2}<>Gm=fM` zBoA>K-u>)A!YsYckzS^hM;^CI$|;Lz1m?QlmG3>4X3M;nkZ*fu(1p6(8PKeG0dZ~1 zjMER5)B~k-1hHt>N@TYt(9`Vx)%@tg$4+?$2g875f_2311q8Iqz1A6 zpd1i#{fJDT4j^W~0I<_63kE@IXYE<2GGH6F9>U<|yt$qOy*tb@wjOpl1bqNS2%`@? z=5he3@D2nNY^LwKQgsDGJ&$x_&nV6{-Idd$RoP5p0LGAyW7fr?pKfO)frJ`?v7 zs#=oZdg*L^-%o!|OFkSgm_yRUfN(CEASMK4hcX9eVLyglHX@iqyCNDqQ}&ug3@ahR zK{Wt!%xF(gkP%*lat$F65aEzoS6ie>Vi4?bsdsXlaE8Vc!Kd=*BTqd1&>P<PM4~U1y~`CI$EI$Ps&Weh-j1+17RnJYK^#yDB-;w!O$TDU^`=KkzlS- zt%TSV(CD0=u@FX4ftoCp*K3$Peei;YI;XW8ecz45W>vxV6#<;=*_ z6E=m`xH>y?hAK|fI>Xh7V$FW6wz3k&LmaV%7eYW(Uc!#idya{744!9jfq`^@2B)Qn zwr#9&vnU4@_*Sg>E+j-xA~3le%(PujyVKLw+qTEq+t%OK3q0b#4qy`=r1smCHte^u zf83pwNk2j``9PROy}W)r*=~(ryp!83YpFx_FlyK)7B(njYu#{9KnW*aE;i%^48#g- z6C7EJ-5q-VzYZ>krQB&>#gNc<%QT9y+)+Bxu5sSJEVXpxm2k1M& z7BQE&5yvkcNw$#OYQSwJ4@?ysgPeIgEV#R*%%tmpfQM{Dw9Z(zB8$(UQ8*sam)zU% zK@sF(#=cBb0zik?#E?U5W{3b#(9USM=+XX?GB1XR+30XYF@5{D+Kxm!1no%3Lm$2oZWQZ9Y!1*4X~fAeWhCmu z(P*Uz3s@Xb_j%HbJfE`bb-gqgtZ zXa^?1Qo*{x*js;qfPfjm#-V6T$ncZ72Yq~iUK&izfg7~ltR2DzMkOJXgb~;<_(~Sr z?pN3?9hSbujCbSJ`v80ASYUuzvT&Xf2NFTJT&XRFaGMF_i|GsNtk$;e)MBet5TXBD zh()^*5MVmsyV~RICe&~__+*560WZV`>~;l?m{J`^43-imN;E9OfEd;mvpx&707n%` z(uP$hJ+Q+Ac7RJ{)rcxcMV{VMrXXud@;$JU@y@bmQY(!7ucLKpt7MIC_$qAix!xar=iOiG7^?x zC&kM8|G1WgmQydjuUv|Ql~ob#bl`_2ah%ZQ?jhPdVjdPDS9u?13a55zY%+lxk#-hI zmeMqKByHX~#KO6$$lo$MO4*_?yZJhvNi z0iL5v2ml4+A8|0z4xZf5l7WZFBGb5#30Ym-GVpu}F^VCot{uis%E~bIAC{ZIhk$3W zFC!90Mo?euT7<-+1*Bk*HbuTDFd!4Lb?QzrzK2JsOqA1!5o}j-rv6PH{lKZj;~ne( z`?N*2-64*YP8}@urai*XgwwEY8rfEGH~{d!PS_GDL5UebWb`6biDg^2OZQ z9sQ8>ab|1j%BmW6XP1I{;D!+@lpFOrOaT{+w~BLTa;US_#WxT-k8TatirboAFY;)>vF}u?efk#jMX0 zE?Ny&vT9eBf~rgL!3Z%>XahL3(w-MWm@CZ|F{okp)TXi+aZSU#X?iE%-lc;!%`eTX zqv5Q<*;+Dc5T|95C6_zJW{O*zUj~&y@W78;v^Ec4a_W3{hstmw&j(qfJd!$gLL;JA zg5^oX)uoMy%B+MDrdHa-{O(R|Z zjPN=N%0~I>#{8rUl|eh;2Xa?dH*#V04_js44k5)+p6`7Gk%G=8y>}z3En6||KZFVM zGE(jSD2G_NG%ux2+M<+jIVFm;mv#3MoU?wt_p@O_L&Os~ow8ViDfAtaAtKF3uWkJ$mnO4r3RXM=ANDSf3*p!xMD^B>^db z2RgV95{_WAKr6!_2398N4^c^9haYN(slv$uy9BybuLK-hcUE-)L~u`|uC;A(iVfRu zRb4n{I%&7v)IX}ya9Tloqe}pm+)4JT08@Zp?dBv;&(S1K1mNUBDx6g^r!WM*3Vl(4 zP?s45K;~pff6d)KYz>U3Szpk-45W1k_cy^K)&7X@^Hc}uR^LcvZ!85oD->4nxTyiF z1IseDkp!hMVlgO;GLcDHdt=z0T!4qYr5**AsJIwj4yso6v(l1gW;Ve0Y1IWBC&J&8 zwf*Y4*$`~0n=12AS7>>w{_cz1gkiJRtymLYTgQ-y&Zcp{E!a3i*usb^!2)mq7G|nk zGCF20TP35*MKUF_67Va+$g<!|J1tSb>zu z^9km@!a$Z9#nqm6S(R2y=&3Dn=v#}L)`V@5Qj?VM?qyXbB-7W9L*66W-AF`rM7Ci@ zYXF6hlE<6XFJvbfjaqh&EZOb?u!m6bDJCtgf*$9_q2SIM& zf}pbl284tb_7if)Vb#zyg1pMkfuYS;nB@=@S`${^L zyvq`bUXiH^(t`9sByB($g3NS+4y}_nwHw}1*G*5jI-(h;9 zZ)t2AC%nW-p&h1q|f8oFOX8h<(hW z9K6(+a`ej%SP5r(%vf;!BzDv={pwHNMSf>X9md08lH+pTOAI;Cu!{i&QM-=8 z=$(T;?kzBC){UWN2g04abU z9nM2Y?SLPcH){^V$7``9hwlUM1oxVDr1b$&=o3EVlu2IheRtv+!xQ}~x*!uGdQ=gx zEMDRL6`OG1O*Vy_bByc*wF_9xTo}X@83swBoS@`p3rnyQv}d>4UHlwVXHzb0Ke&|# zIsK6Ogb9MHAdn&oHZ;5(tWfF8*b)JKBug021>haFO31YZ_D~X|FQ@Hd@OF=-n+Ceg zD2U=vu>ph-NZ67+A;*pVl~4z#`PgpJFu`_izlH?g4tlozfC_d4CMdhAiw6r`si}eC zE#vyII<5bT)2y%KJ7CU$r84lZIRHy(+;m=0F94vl6ljqRv$fPB2%9Vk&$)JU2|-P3 z+h`AyS~jVr&@^Fisb$liO)3i4+g!V4#P%dp-=PZI{UHsS%^SpFcXT7QCahUQSx77z zyWxy#je5D+B6nQuU*%*SxK~105ZE$VKQy*LGJ;qrs+Vm+7#rz^#6RJN*n&3AF6`fe zI^>NP9qIv(^De_~d-awtGq#4^X&vO_+;0PBo_pDzvuPt(%BEdOPS#wzb!+yWZ9J{{ znCz)fan7lw!?mDXWdL>YXaZ+f2P0jumPNrjQ4ZyJ`G-z;2EYOSMBCi#;7+b7@3(nCM?EB?cv$qrllbj}&QZ*BTYjc#6 z*$#=LS8{qa$)Ys(b>5Gsd1M=1Xe7ya$`sCHx3+C(FGtA(eKzwn2pT<#1k;fxeCl%I zLBT6cup_u50qDfj*G_}1&*|UUi|^a?z!Az>5lHzxh9{av0CyA&Fe|G716pM{v;Ia} zQR5fy*F_1~I*-f5fZYSsd)%zuu1ytc3R3`44w885#~!jp+~jK8;_})Vuce6$o0+^R zx0EX>7wswq) zjcJ(}dDyPwmyzD$uqVSN-H8E`mb~{NU2fQgA;h*}PJ4fVV(VNqsxFh`4a+_Qt!EDd zDIVF*SAKG<(qL?+3jzfsWW^p5loq{#^F&?5kx1*(#w^xD_bEGpTUf^SJWrRBt-QJr z-|~Y9Y6<;t{@^fJ+s|d-Eik zt=eNS7Pr@VN%jRoUvnB;&w#Y}Arg&km?mfORlO716NWOpcF&ALbPS>WRmrfuiZ)b> zhUwiK)~#)*9}eQg(ZT5Gv14{ox#X{ZdAm@nhzl00^ zL!kq0xXx6sRWd%xAzOU(21GJG zBFg}ZvD(<9gO%{ZJg}8zCAlnF0GmmBgIh|N4RIQx*#Sf{bVyhVjWuC{C9$gkO)HBQ zF8E@3g4p%CPtt#qb8SaWo}^2oJ**8Dc|KD}Z^8>~1FR;@1L_*9lMqie5eE(KmI=`G zcWU4qazXC%goYFFBE~IBL*o`ha~v(omtz3yf?>N5E7cbpD=GK#_IQ}xX~jj|fIo5B z?jrvMn)_I~$OhcI-x@@uB{^Jc!G+zaceQ?oj9({!8b$5BZ% zGs|$B^AUrt*p5ElTu%rk8~?wX)E=~!tRcQE{kJo*M>zMtLa@#GsO%?OCsMG!i>8E2 zMM%s^HSce4?m>NRE$d%Lt)E~wU5N1aC%rrJ?YdOtmHed?ln13}BnN_qdlns{umH8DuhPp8DN*J|+lQBsBv;a=mPM}$8qus=J1hXF2$Ov}mq z1STZ-04;|UC^{&;6dbJHL-mDxDmEz8j#9u&Tra^lXHMeT%dagvJ_NSw@D4@C1`3I zPQOi}ke&u2^YATzg~KIWXjV5f2>8Il4kFigrgPRnXE8KuDSsPn2pYt_EwjB9n{c9< z-!^BXvcH=OrGbm3%+=;Y+G<_5ngsBTlhA=rI*A-A7Q|+wVGIp!5su2jYtDr|e2=+s znYK9%^@g7iqqi?{GVILQ<99C4>zE2AVgIxqb}H>?Vk)c#x15NylL8jI758m-4y=z~ z0|Z}bnE|a;KHHjsT?UIfm_!Rlb)$(hjcCbg|IK{G4!*})WPIiQCkk(OM(lPK-NGRV zqvMZS=EWR78F-w=%PqkJ9QInUia9Pc!9!?Fw81Z1=%>@#2|qk)9;?WtU7H{xMW$R1 zW;-%Zy{IhUEy8JJo%QeJm|kK!St-I#`hSNh=nA7`@F@n|-O9zM z{~iFp6%2jv2r~v49A>~@6L<$1+|Gbjws$9k{S4T+esb)+i7|2LImWIqc#*-o8B`g( zm%;lPe3ZdQ7>qIC7Qe~t)~rBM3n{mxqHOPz_6H$P5{ROw5Og~a;a4nhvFCWMNq2nm pkFnfsZT*k+JH0*m!}-qqG0?m#pXjr{>cp!)dgU92;U=R-mH?I;5 zydD!geign}(4B(l*b?Z@L3EcOIxdfOd=T9=h)&3Z?iNIMFM;k6ME4A$d*!iC45E{Q z=;S=;lpwly5S^L_-6x3dTWWZ}AiBQ?L6ZlFCdUNvF{a4_gXlp@L_yF5EgqZ)L6gvf zK;$$ba;G4^Q!fz(fyiplRzVo^2Rtu41gZNk@az+q6MA<3`M9vJNv+^Ji$>@T} z8XeZgch5m#R)-tLT?KNp~aRUI#0V5EzXw~cMIaXS&IvT=tBKkL1=M)2?V7t z3ZmgW7L>j?h%U*4p!B6B5R|^G1cK6+mp~X?BYsq>5ExurgJ{%?Jtkt`J&5maVvl(l z6$G*2(&O4fK@b}bx-Aca*jMCDzFp|vBZ%)|bhmpSP!Q-&1kpp4h=M@(${^a22Z1ie z@y~Lcc zJuDA`9cH|S+7NcQDTwNMEZ6});9{;~!48OFnH^?D#*>2hB$Kf)7UtyZlY{tV`#Kvv z3W5q43z4#g(y_ESC5TV47W2OI6@(TGexgwjl!hH#5LXbCUi8LP5R}gRK|xSD@s6Y* zD1CFOA(Y{U<@HMnV%{ML>?PNw|M`*Ra!hCh#z1rZuOn7AhdX#?=S^{?c@ER2iqqIkp~9x1C7WN zJrML#~1cJVqCW-}p zGffl(eKSoI1bs34JVR}#An5x{KR+u7`aa8Rq9Ew|Y!5=uJx4Toa1cM(G|75SLD1y6 zzULGKO)#grgh4^j1Owd-LePDl&<%q)?4_%q0$l}x?(;oe1%YnM(^U{G1XeFl-4z52 zU6CIKFBI;l1@URdeYfu)1%Z1uG9d4Zq{ZqWUTrP1v{pfAfuZK2n}Q(ki~Yz@5afM{ zk369JQlWc#5T9;zvr(-e(0y4DyeZ2y|cVa~8#deP83Xf(ow{Ru2i{hZw8ZdR7VoE5vM<11Jcr5b#_sq#&?@ z$sKpleVx!fGlB^|l~- zyLP^U!0H`A^v*m8tdNwr^bKs?G5Lq$u z-7r@WB5T2MKP57r8^q_DjM8cqD0{22G;PXOcLlAH1C8D4L5e1crd_jn84C0MOL% z!cY)cebY|?3IeNd`5~wvu==*oalq>Lgw^>$e7>>zjt{8{0;}(O_f`;Ceb1XlL16X! z-h&hbR)64E8w!GFX44%0ZwXh(H$x@r5Q3xI5=j5CqD?vw|SdpLkXZf?{>5a?#MRuJg^tzY*m2y}l^ z0>N^BR|26cf9gTt{`bQD(jdOnxc`Hn-xLJyKg-+UAEm`*L429D_$RNlg3#iPLG;h6 zp@P)>E=K{|e-R>=2l3@b{Rtf^EfA`!K1XjPy4}xC_tF1x2)mZ)7vr>?n<`^}Ng36}(jSv|P z;!z{=AD)PU3i2wbAg_W7rcqGYG`|&AV?jJ-tTNYA5Llh=!OZ{)DG01ayd4w- zRzLGzt{}MHf8|rFBf@<=h{uh4Fkq>bg1~)Xz!C&><=_B!Dz*jjHfz!G&Z;1^ST$g4 zBLzX;EEFjS@*Xo_8MA^QZx)@v>Q2JyiXgtiSY?x;g1{=93>BnZ=_W%3fz`#{GztQ% zY?-Yfm?m4CDhL5KTbwHBl>Ef1AS^oztL0-w?Cn9k-NZh2z{0SCAoiWTO%(*OksP^1 zKtT{25!8)W1wm{?P`7+n5X8>LD2#R&;XV<>6UIHu))Z9Wt{~;^Mzw;JyUVH+1nz~@ z>^Ncd&>()OvC1Yu1%Xv2oPxmWdasp&!0MwufG7y8j`tRVR(BOvR|fHw#_F!#rV0Wp z&~*k>5Lkh(t1~MItg<{=L0|>TyF6Jzuqn*!EUzHALY5~h2(FMR2N_Qg8FvKn4wLZ& zFQbAAmRC@r-xXBocLhPl0;{_TtDQl-(^%czvr0g23ut z9t5pU6jr-}c$cxt;*)~F>ZE~O#(uK2*d4^Xt;NY+I0c~vJlpk^f*{=U{TNjcggeDY z2n9j7dwW(2D*OMb!hKH=?=kMDdhQBR?#|g21n&3otP}+9_w{yA5V+s31OoT_mq758 z2MpM9L>t0W9#{e)XgsI{x*tY%3541lOyCBg(n4)6a|H!GT;^owuIRE*OmI~YUu7l; zy$KWq6YTaQPC+mM`os+b1;GRvD+R#>FDW&I2{IWK3nsX~A3q9$2~P7pry!UhD?Td- zCdi7<3W5n%mm0zZr+Y_+zGsNOlR-Rb`kvwSRS@(=aBy9&An5y$0o#vJ5cEB>1cJV2 z4cLCVVnN?EB@pyoTLMAfvr8c8dyel+h&?1?PX+Omi9O`SRuIHqHxShZi;R1Nc(2KbusxnK+p=hyZWPIL8}qWcKL?TYS?$5VnM5m2Q2f2nJ*E6t`6d> zO(2xET#;Bo5a^NtJJ_Kh2!!;`6+9FKfiCsoNI?*&<#oq75gf3<@dzAlz|jO8EWoh< zZ0chh9sA+6IdiEH$tMKx&S}8VN75PNb1Y?~p1XUqK#$`5n_IrZr4A zm_HE25yUXAF-G9Ka1HeJ)xpBv;JRy&tPMn$4@4sa@wI{fi?;G(G&(R369QqZ0%6<` zwhcsA6e(;M3KNF#&Tqs|;bXOu=a}WeC$kVede+ zuSnr)L%5~_;aWquu51SidHq0igCN{E5LMaXVTLeMrr?CU$q?#2TGYjovw|=;5LHo# z3?c5J5DSHQLs$?s7YCxGXos5x0nMu@>^Fo)rbV{K7;RO{4FEoS~RUo`r5Wo~6s1)s0im`uB!4RsV+#3zyO&NuP%e~nU-cq6FTMglD8HGZmeY+sMV<38Gg%4L0SBbAiztj zX8#`>0y?Yc_RgMvYX~4xL~t?cCx-BMnGCM2n);`PfFNcRTo6-B{=FgmLq;L`SLHN}GvW5O*^Vfz@m4W=m5PCBZ9XS7C2*0HkeFEu!3c`O$ilTwE znCwMI4B^%uJ7{MGgG}~70S;3#RNi3*2BWI6IVco>uxhY>Fh52RFj3;K#6o4blOY^C zSVlN@5WN=N*%0nR7Oo$4=2Z&E3BvJ%M@iLy04u?gy)%xcYCx#!O-RjDk~8N7hM#fF@OTIN1=Y>~M-9RN3L)h5#;o)jZV@?vn{gn|L+vYY6wN zK)AmlJRoCHpzuILcn}fT-4CX(`oAbNgx+LNNB3!lu)2c6>4I>^VDHi%T%v~zMrRrV zCX|vLbZLKj?S?Q>!Q!EYaAgmIrtUioVP{WwtB|_{VfSF46h&jy9z&?gtFJPIDlH}r z0bKfa_mm(^4@UUwJLBv%gnd0~)+H2QEeO{PMpfhDT0^KB7dm)Bp?6%Up{_Fu*H>t9 zgCN{E7_GcI078|aG<638{z`_@zId3in91xA-6S)PBGe6GHiwYU#O4G6O|ZTwP0gCa zM1~Mo$S`jR3mF0h#xPeI76l=xw!_VaP-Tbxg3zcQI7^1m%*oIa8Px5U1pyHJl`N?U z4>yE%4}vc3JBHBBELn(?sURGv7V@AW9O|K%yy+SI&(+%Mnv_qfi;F*H(tUkTzvO(Qk00J_Q z($LFqE&yRc(u2jGRrAfVLV5PlSO8&V7C=~;#d8Lu=VqN%C>A|W)C9uwD-d2F2rnGu zinZiX>JKk61PEC|P&>R>5MI)6eW87!t3@DGtrlNu6siV}t`q44sf$pC~Z z8D3!&dSy_jRT)6xs4~1V8+sASm41EkDq->J!M>Z1(Q5{y*BZj>G75zt_Ig8jL)M#x zH0h0o@FsEly*(?nHygrRdMIdjzf}<4HW>Bha*vg{`|XDCjvgW3A(_}a4dGp6LG?>@ zxpy1FdwM9S!@SoJ-X|1#m$dIUgb!3u_@E$sXpm#UoVGA7K5PgmfqI0Ga2e(7`B6jo zSZ1gQ2);KzE(n0+C=|lrCk)|>84E{Ti>RM8gdB@PZ+=P;K0O%a5DGGU#t=SR6w+() zIYan-hENdl3x@E;3WP5i!k2qYty+9V5WZS1W6_PzeKyGgiQ|PQeG=!?${*MfyD!2c>A^b5}aLy`~ynbK^f6}9c z#;89vgdg@G=*aprLHKi5!N_}p)8#J=p(-oZY!DQxav049f$*1^424aWzcLm-szCT_ zLHL{MHO`L>p*L2mnty8uD+~FP!RYULdQ3=e*U8& z{8L6D0zn@@{@D=zC9{L;1(o6FhVYAwf|5XtFtvaXucSG4EHh$C-xwy9ZoWYlZntLh@Bz`_pa`&Qw^c2v+iRE_swL8 zAhRD?_Y;KsSKHwMhEUa64>W|84Fwieeeocp@Ze0yLT`qGaM~)jmE4=;tTqHxo7Iw~ z!F#$P53$ZF752|G3TI_5S75P55Z11W&Nd1qA{p&mPE z1!J8c)K*p2Va_##s=nAH@c|U7HhR_@g$+GgsMBsVgiSp{D#B(#*uv)h`{F!9=-p&d z3g;U_)dJ)KL#Wz2xX=))_6{yGgsMH1VMFMhH#Pac*br7;Cl_IQ-4d5KWCbQSB9 zC6`kcml*}=$Tp-O&da$KkPMxDu38#2vyaj zs|^8Kl+@I|(3%*8?ClG6TCIrzp|{+m2wD>Z0{;3MN?q=nqj?k%s?@wzv;ab{ka@QU zLX}rvXB2?5f{@o&%W#8G0K$zufmAK2iy$C8tb)aiQMic+Ob<#kPTde@D-h-cAzD?r zO%of!yoBrCiFH8`7NsvrcF^8T456woZZ?GV92eALe{uLX3;|q9EYwiy5BPSe$C4^T z(l?#Ih~@iarIa+s$Z0yHgA z$d3zr`wW_zBde58KGP^XtK1iyah|;@dX6DHw~XMHlg|@`=gX{Dl0p081%?2e5`qf( zLPK~_4+}j%`C>zOiD^-aaxXQ6msKFV+z?*T!$K3SR~o{rDk!|#5MEP(@LEH7T?LER z3&I;#MfmG$hc_C+n~cSqi(&9BhVa%N3aZ814B_oW=+oWrFobs+i+2@Syju|7Q#o+p z6)X+_p{k>8$rzL-L9ln$4=I?W1af73Sa>H#9tgxc6MP(A0Ct=PPXU~q1bwvL zjTc(&!%0YVVsVu4teilkHS1c(9{89WO06 zK)ZV~8$?SiQ8fTNHG=H+jEQ38GG8TWqfg1tUQ%0G}Q#6y>@c|&86Yit*~9U-D(K#)}+yx zZPnY+OtO*YqT5U#UXGKEaH1}q@|t82TFcvOh2GUk)LoSR+a4zii(T#6ZnvGxqL(^K z0$rSJWS7!0Jd@;1P)#<%VMOZP?I><1&4n(V&2?LsR<|yM&EjS^Ig<@&`st(#|Gpe_ zlOrU~c4J8g{-TrfKSiM_M0*L0sYeo}Gv^aTe zOB(Tvpzo=ts5g2i>pUAimz0NVfZ+Fz2 z3n`c-CsRV2XLNK=t}90u&Vy@Mk5ypHs(TqTc-i-DW&E;U@5_PDVu!jC0H6<66l3WKS4lm0&cF}a1FOXZEuwgfRjB9lR^ zE7`jS8?7VuHADjk!aunfXn1)M#}7aVF`v9kj$C3Yv=JoZZLJ0dpf-T*T1y&`MU|;m z+C~852%4_9F*d|w#@c3de&L4ac2ecg8H<-OVyN0!y4*<6JFyHM8QyS1xP){priHGI zMYVjV>jYuPjyDe^?N*cSrh+3zYM<w zh<%7M$xRGIoQq-aj2E4ctb?+@G9VpQ#&x6!`qA6eHrb2;s zTAZpQZxZL87A2<^5x}D^@&*~O8agp^iEl6d04!oK8w*wd3UxBsN1uh4kMo&=tt-7 zRCKo_M;#%wvy+T;I`PtMvCCvAYwc4B^}?D+wu) zOf(tCp4yCOINh!{I~ZGtePo#X$RR6+5DUmVCL7v8W)GeE<;y+wx%~{AG=c!&;tbw9 z>Gw0@R(sOfM$*9$bmLYiUzK9@F`vLM*b+`B?m>Ac>rv9$ns&Pw!1NubsODIct(Inl zfZAL^4VWvtaX}g`p6qNzv2>VzZPAVMo5QpG zxD1v{IwD%#{Vi$05>& zCHQb0r4s(pfn3a|UvtEVx3$_!b$&l=3-VzOjx?67tAaHj6C&eg+v zm%(ea-ie2Iv<|v=46#jELWp#RN1C!$7`{4bM59=Y`mZrEg$;&yCeWzlsyc>;t%HU~ z>oO$|+W;8eJGmoeet}5>Sz`W37yTS|Tj9aQWNtB>Z?&? zFl)1kl%gZHLR;q6<@j9P>kA1*=gu#q(P3msp9fv?<>96562vC^Xe zCrjy)c36mX3`WyV;_zfIDjHn5KbqBn#2c?2-ZgxA`XESp^r z2TBg^NJ|f(Jb*yi;a8?e7^UJL4$X<$YSz-K0#v%Sui#1ZKx=QV^*;!izK5vP7F-3gvp=$nY+=gyKG=HM~cT8KV|87qdm((?Mu&A13hv;hGFRtvaG@kY0(GUGc%N6E}2? z=A@!x2+!sA6x%ySv74tS_m0;jtVwA!TaTp`RZN*zMxq1V94egFS`m}+Zy`Qi z10ko;i-qEZ9t zX53bf)!Ah|Ev0iN0}M0+no-5b+=T(vmWhMy5p=tUHJ16xvZg4=*V6kq+ja3lvL1+! z$&}@@TDlKkB7f*&aoPYB5kf+c;feTR1B*L+*=|x?4Q;cn6ooGYC>DD$c42q-jVI0h zl93RrFQVCez@bL_Vdm^&xIgfnt>T~$aEjNpmk?Co?~|DCI`b0=Nt6}32%@EN;DFk6Cq8H2mCprC%^{+AUdAf|ne%4ugVxfEAkK~!rgEfqmajrA z8RZJV0s$#%cp&K{SbSxQB6F;zSE2d(;SIwZhc^#z89s0Lg5e8?Hvn+n@P_k;H(W5h zasBW{e7kXYG(`!u#`wH(fBi8GjcJZ&^RQW#jOcO~YF@ zr!2WyA7DA<_Q=u;0p8P2masD=L(4)`qKie$Y~eDN_{m(_sAGZQdPK8VjSPNILx-*Z zD1+E9xzhb$l=o4(oyTRzXeffE5zFS21#Fx~p;$H!_fFKpk+9inuH!1fEl8weuy&&X zNo=;=I*1ttF%9LQT6(MFm#EJmd^7t37ft(A1K+zY62tj4Gh*fkM=mzT$Xc&0Fo=XN zd?i7j$%KfBn425`_(7(VnH0_?cas&N`hnSZB}ZWD=V~}Qv7)-$PUdoHET-0MiGh@` zZc%v7#<`}u;8K(P%Xz?zZkVJm00+O0VPs|SV24u?XCmkF9nL8-aoe~uJPfX83-Mo4 z%2;!HO>*-_CJH*&S(NtW@(`aRDG4)wX`^B%_SBHAt9F^f8E(?EAnaaEaVToug3|x8 zy&7_LRg*?sDWnf@Zjd&SJZK(>c*u=dhsm`MIO)Etq{~uu6$*TpUgjtOC&t>P=_Vh3 zXZDz8w30P7=Qzeco)ZucVKS!TuzVo&`KFV;17t_A2FF4iMjs9lDjEq2A@KTTBIuCt z`JK49`$Cqc9ochdfOado1T|AEZ?K@7((o#@Az0c$0TrHI_uO0##ko4Jqr!mYM59GV za!Eqx;VCOKv)Jn2AH$umzcH+(4~4+C9J*m%$Tb`_65Z3a8V1hBNb|(G=a75LKAZjN(je;uP<$DwDcb(5QCmi&D(CBN9{e9 zI)zL2G|^HAW9e)gn9D%14@?KrIrohw2NEvmF>V~no&a>MALiinHh^yG(}26qf%~k+ z90(61*+(@nzsbARux*0=G^Q+{rVjyAzM*SN*THPFhgl$4BMsdQjYO8stYjxcjT>%k zX8nqFx13T4Cn8uDwqB~Q>%{0!S!^LyC`{}%SueXYm@F&C<87I$|dyL|{7^A?rX)OfU#Wt*r$y9AL|?&vOyxTKWu7oy7Si96gZG;r%TOY;KO1 zL~Y1TD2M5W=Vv3r#?1N1eQb31PPi=yV^FdlMHV^p$=YI0zgpw0d&S;~G3R8qZIYf2E-l&Y zMAX260y$73#C$yg{-IO19CPt=hYGb(kCC)sM!eaZ&vuVp63xkTxF_- zZe$4zLywVPYnfQ0Hqdq5MQq9}EQXZ1i;XDPT>XC(iwxx8>G_b09@n(QftywuZn@&r zK0<`*2)q_T!O`h!W)9&$si%|=;>h&H#B`ISSH7>12=l-XdIy7G&T5MYBDQaqs{78Bi^*J7Bw2H;alPArTTK> zK1&sdVUJrfJXVx`DDOhf339Vb*?s8I+pip*lz=VWyOvq7WH?LEC|Sm|1KV>s!{RYw zlawqE``JF5wUMhL{fd_oY<;vaf3O1W4WG_}Y{#dY3o)t)3}6?9>xVWBZLHPQ-zFgI zjHDiXmp(PG4SK70uo5lo?^2KhV?^f7QgJHNwiaTeLzXuO+uVa`BL1;DO1rqDKf-}F zk$j$?APgl-(p+;-;WU^GbOoj7Zmek8lO9gZnoQcHgV{1L_i zJ!OP(i!&gIsmxMkcdI1|p$OAeI6+)Hu%vRIU?V~BzJbnN(&E@VN0;}HwaARml)~=w6 zb6Vr@Evby;G8w-bu-sT8hhM#UCXkW44>j4>8#UIb!m@nlt5po1Ry~pw4+iighHMs9 zN4HtJmVQ^ncM}ZrbckEeuk<7>b^>UY0lJtUEJ;O-(3&czRm40brf$lF1F%Bo3QW>M z0wX3V!z~#xeQ4pg z@suGq^e@z;-w< z$H`oFy2#G=ktCm1GSPklx~&+wH^Jmx1Y`{v>qqCX83hJ0^u3#h1eY@rKuNbIQ)$lq zYT+(+nIq!kPfaR@x|(AehJ!Lz|B-c=AadEps_f`U6$xcL&6;fYGP)767Q>H&h4y;)4LP`gR zL2i$NmS)!I$jF@(ft#Wm&T?&Pau=a z^My3@)%c}m!7$~fqs|0^0AtOzW?P49Y151#yBjWD$)&W}M5vr`M2Nd~E)~cAJ>nxL zA=^*LHT6=65h1%%m8*)~T!E*L#Jk?2X(2ptD;7Ztx=KuiyD@nv2@9B!%PiSa`Y( zLTt-ra<_GvkM?`eJ`3(TC1K;4xo?V7xhyRdQ3?ycCjrA%&vNAqgutAwWJC?+=PQ>4 zd2g~(w^$l>cO`JihYHj4Jd1m>YH_33_lT<+>yiN#;B>9)7h6Si(%E&=Qgcx)-JI1C zYBgP#Snpa8dlN_$Hpc0*8Xw@Fk`QXIYaH{dS!1a@GE1=B?24EAl}00!c5z6LAxB1L zT}zm*v9DM8Ql?FWt^$pj&m|J0NMx|_nBoAK#9sAV=1I<;44N85bl~u)js-+motEat zWtc{wke_t@H`6RZ30__R>mT{RD^cyFvEW>!A!gtdmJ}`kn9CT@v&nVrlgUD->jjelOy0 zNccP1GBxSA6?t2CGOZ2IkH|)*8M=D&)0*%wN8Z5$ znX_)k3X@X^w#4e(gomr(`2BvFRn%9c3a#0m^B!f#M3yxxObQs(oJ^Keoa~l)5MSAr z&pmQ7K@gTCWHT)<6b6`-D*Qk(sa%SC+c@$3q-iggX5=JRo{yuCA%HEXMVD^Ox8@MS zeWIQzHz&7XT!}clu#<3jOLmgmI`(C47hW6{7_1(yU$Qro`CC-F{|EN)`xSjF)Q@fgZYT=R=L!q6g|7V1m~u9tc-d24M9o* zF2M5TEH(`baw3i&M0VIZsMA1p8!3G_*zL1J7`I!=Zfm)$<1Eg9WAA!pC3$Sf^(6k$ z`a&84=p1Mm8*p3!4v))DYJNB#<@!>6W8y^0Nikso!7qVv#316 zJs{m`vemCvsXJ)cMmb5^_sQi={tzLKW|g5NM*(Z;nAp|jsZ!S#+8F9MU)#b#8g3Wq zSl7;AyejOb3)h-dY44z6r64;l27R8>)2|>k^knYCF3+ES67CL3{f15(Vicng;A0eY z;${&70(^{P7ps3~m26RH`}Fg?KNxlo;t(kM9ovgF%^Pxe{A6orTh57mL4+By+{?1G zna6%|i(qd4IPcCop>Ll%OrRwj@wwb>!sH0Ha?^)_DzgeJ%_1T*O4#T{GEGLfv)9qm z5Z1nO0Z}%`IKugLq^86XTj+ThWjWbT(2dJlI#m|j#+EYSej{oavL%ayarHKj!(t7m zm&#Rp40fp?qIATAkX)5%5kL={t66iW&*gXl)zUQARu#S&<8*MLmlv_ z$=VDt3>hs7Iq35t{VFR5C#^Vd z=WvJHZ<>2zdaqlh5Y_s0R?u-_u60miq7G+graf8`kp-n+&uC66&A4mIv4EPSCG4`L zUfNB+KD<$fnXJ_jMQ|b-ai6i7t8uxjnzo(zus23nCXg^fpv?{|=gbOiuu4g>n~Ae6 zJi5Yb_&i#HicNi%$3nIIp+u>Br-Q8^sjNVb_38tvX8Ij(Kso&(I|nSp$OV3o#P$vd z@DwQ)+l2uvmh)n{;Y%6hw2qVz;SPK15;~+}6tz$;V(DB>!ATQDZOJG?Bb~ttl0j=e zIRud-UW@Z3^<2-&sclmo14Yw9t54m8c$nFrM$3|hLeE71F zMy|OCCdZj{^3xgG(~v@it%2>raXJgKmS$s)u+?9_`d#ck95`q-bVVdKGTTY05pyCh zK?Jj{Qr@rD65N=(^DMhCEMr>}Xu1F!OA14pWs!LtiTEgkr^S6ZR?FV@G?-b4B;&a0Z(iHMj+z|3B%+^iS@d$bX0d^*>SOZZL63ZA`MDz3Q*Jv# z57o05=dyXIrx)EeH_=>-D6$seYLY7TueJ134`+ILhRunsQ#$YBiLXt#yd@@tlNRna zV7@7ASS-p#RNd>F7$@QyY$&e9sgAjJ3ua))xjXCW<#;bBu8^+PM0a7OOjt%4;|W-^ zj>cOq+#2W1Dp`lS_ULH$+ZVM zPu|O{p+8l`u!F@K#u;79WkC3(i4xu**2n8LY&OK!RS!27P7}$d+x0a}qumAsG80tNXI@f=Jiz(S2AML7s&I`?RLQ zrbjKkA0+i{a^+>WG0SU*BCI~OpnRGXCkk%6CK?mRjrUA(mpI4Ui>If+S~$cWwYqEN z7Kc0E=*M?Q?soOW0EcFo=4nu)2glPeES5YN|FVZD$U>2zK6Zp>VoM8G&?Mw#ZD#a7 zh<{Fl&=^(JzGN6Yr5}Wmcrf~2W=6-s9r`G;!;(eW^VAt~3}kV9xI;=^U1H;!hwG5t zA$`DTmlL;;Rs503-64?jy_QgcTeYI19@r<)l= zN?nbCen+Q++QhC2+iKw)NgV{nUexe|Im@5#p=eMNNV$_K+C|y!U*GeIx_^Q-4+gSS zie=T&SG&@}2q`@>FLn|6MpjB^z>^d5d4UrI`&CebQ-0W^4tMu8Q*{sg(B5<(NB6WmyHMaNP{NV(qxtusT*60Xx2hYVW zHdnSdy@}%_vPZ;nXHjO7t%*Ov2rm0rGvCtNuw3|}GJvHU5@We@#gv3TK#6ejj3*GC z*4q1S%M4iJ5ps?dAIc|gi&QvYY~yiKIfP63+~HDPl!-~W8z_mtAW}cczM=Sf>1d>1 z=xP?z;cT4C>d0n!m19D;C&r7_fc+Sn!O;tQtct{N+6~6{ z2yTtaEks5Wy%eNFTXuIm;*37ECFQ}%m56B1CQdB5lURC`OS&B-+-U(xwrsoEl`VC) zM@FDkIGpTD(4SnnxQtKFd(~%g{-;b8#nT1{ zz*hS~!effO4C}&XA)3RE(-~ZvaS{cA0cU~^Y#d8j~Mhl0^BV2^E`&7KWCWzBo ztm57U95nwJq4ZS1eDEILhKS-%97$SJ*zv3*sLQQ-@o!45yI}I%A&DDf@>atT-BGf8 zU14Gdv4hY^*76iBoqg$yQ2yOiLz zKKcA8k-m_-xdF-O}S$p6PFORT)GfJhM;}Q3nBiF|cM(xo2j{aW=*+JiJt{in-e+{vgr;dA^n&LBR8Z z(nfafx|6PkV1DM3RVm7XFa-Jy=Q0cFV@a964mW0I)p2NS~_7PF3)*!Ae1@$9*30jE;Fnjv6UP9{3%vi4O7 zjUAtCp&G84k`3~jJ9^LkHATv;L2@nIau>k_M4{5HQ}hV2w%p-tA`5N%zyYL^AeZ5B z(|$CVXWDHCSmwd_m=ljAv@QBcX=&$L6XPYFYaehZ))}IwErYnVbw-okC>hYV!{!qW zoA(M-;c?6dKsn%864vP}vrcS?rUFkx*W`k8QPSJch-MPTC`$J?lW^m~{k)m1iSd(z zvG##R>S=Xij#2hdCmDGDX)~F#t=!x{B1)U%2B$oQW`*X=Gwhjo>0x|8NS1ix$AzTL zC`+%l%Z#gK5W2+81^YHEjz@^q8(f&##*qcL!p3i|XkmPH$LM!g?`42we92dP{hBU) zE|lDbRKSJNLU|XL(eXeS6j(V0h4pzXgm|i*;StYALj>nho@JbFMEr)KWY<$Co;)vU zY|1UOOPKEm>y3;8N$aBZq;BX%I+R}3+llvDQ#(Ks*{eh zGd0_EOSIBa1>cy9W%MIfzwqQ-{a|UnB?Sb|FS^I3Pj5?aG!w#~|67%L>nUf6tdltU zlqI`Lo)jQ`=Aul_a%(zkT~GFQ5qGGOgvw?V9pbFB&teyzb=g@wBO1-&m;n~^EZE`s zg(L3ij{2+?_aS#&P}X6bRSSzbp3vw?^JMOoq=B1-xynNRJ{AQ-*-i!%G6dPu#Ngl) zCb>(j=jb@yEi_uQaLL?vvV$X{*aIjfXY7%KI%l#JMZqJ|f}Rg#{@T97`Jm) zk#4vcuxVh46VnYX>JzX|OBB5MsE=^U(~~AOe`?H7Z$E{~=V$6AL}WyA#hJA-+>YVV z8GXE__yNs53u}tavDL{V)fmwkmOK%l_sN+uNsidP4?h?+ji#EoW-o37gSpmOCd0eZ zM_HAGYoyq?Q!Wc@*$^RzPgTO&I*!%~?Ow5FC-P*CzFSmX3y2pGA^v@)36xEBhP7- zoV4Kbc?wAWGgP+#=6S4Xj!szzVS3cl>^!Wc!G@~IZZ|gi3OCawzbf!z1y)fdv`OW- zfPffh&!zH7jxG^Zde*3Oy;WjZ<62Ihx+8buC6p*Tv4TY9DL$T7N_2josGWaASx!VO zxlsVYQ8I)DFh>xcyRuET9YK zbhbtUWH|oryj%`tUf~SHM8cIoByW^@L>}NqDsF&Yf{j|7W<@r#;S#Qdv8#bVih=wQjH>KcNhnOO zE|c-q2np4w;oR{jW$4QTMuvN z`N%5EGgBS>oPbrAF2igo#~K9=3Smxi7iuxfqCAJ1U6jtD&cGQF8$FVM-h}s3;e+g~ ziK3`3Md;i{kewC9bBP!}M3y&p5Q;(?_R$x+9%MY8jO>_@}Vtapz-wIHJiKfodsR$#=;J%l`+5wUPciD@P{rPCr6?NPvAT{<=ZJ+NA7rjAXY3)OMnt-!S=a-9lwa zMz=I9`$tgfcM#!w&f|5347GH3(J!_Cr!K3q)W--Y2X7$TdM)`CdxL8hoRDFG&X=+D z`2sUuKr5vd4hx&nS-xV5kzN5c^NyGIubl7o9K@XGDp(CE#aM0)ajW6#(sSFzwJi0e zUi}*K?6u+iw@Q2*WRyx6$xj-Y_xEGV$zwtfU+hHLL5{+@&#uxeOL_0ONwTDl%iCxA z`v7)uY84=OT%;V!l2k+w@Q|f@A8#G3ZArsU-ZMiq6;Y5L7VxR|53?{gGnEnOzH1}}o|$v9@sCB%C;>| z&eeX=*k^oC%lPh14sh+U%}S6P$c}sRafq2N<7F$hq2z$uMc8@L?!-GB^1x9K`N5eX zeAp--TFZQY0p5>Ev>FO=?%ta4SV*CXesXR2K^w{X)t(R6kxG>RK+cO{g$7qA&7Jk6 zDZ|q5-($xn-Gy%2ExI{wO#3kUbOT?ni{U2)s1~*lOBT~qf%kG{!3P`SPeK^RBySN@ zQBi#yr@<>#=h|MbGMH1J1Hcp&OYlT~7((w%AWk?L-LXFCmD#)aBS(@-+pieOfqB|O zpK-3^-bhh$Xr|90ouZx;daYzY{`$tX(g~f2tWENs$%YDht#9G_mGv_IA;^r!unRmK2HMx@A zH++@n@InmB!m%DM)4g=g-291IT_518t_ZCX;k$Efde`S)_vKm@G*LBHFOf5Pl4^1E zahMpNn$#1ivEay4>iQ_m^?P5|WB!=5CgcT$eGZ&ELv4&T;l#-Brtdh@dki=aeibb% zK=dBC)A zlpuXHKH?$de3mofgglGeHMJZPrEtzkS`=_4F~@E4ime=7xP=z3ndEcduh2(`Y~@e2 z$Wyr2uiLm~3m$I>#7n}-@SJetmh;ZOLjQf(#Nq@e1ZXs7F1W0Hu1ubvR7#Ty!T}cq_8dD!Qgtp3Hl@H z=Xip(*K9a4$=F7YV3t(esfuxI4%gED=m{yb=@Of(WaS{~^q8X+lhN3vQti&m4LiLf0#?bE(OtvDZJ z|3n^9Nn1%#m2rW}iShFi)WlfqeT#S2lTO51`dH^4r4eo4hir`A1#!b*xA|!fv+@Pp zs`EG3-8fU-mg+b6ZP>&>4mX@94KdyE(Rkz|3%%Zgw6Ev--lpc%6H>a6;kL9O8=e=y z3;tMj=ur_`onc`If67uaQL>V)DOtMZ<`9xK#bqZ=fAlh&G-UIKztd;7C!lFRZDMzPBIJ%4~*x958_*YYvSXc z9qZb={)4SJGSNXE&PNtV-|BaINLg!Od+Z*bJ)aYeaMlnj5qLT2NWDzTi`+rWli?_z z=TAxLSr{!xiTvydlh}c+(iBVK_b>~AknP!@NW4vLaN|m z1_Yl~r$k?3edvC9hie?UZI1bb&)|^lgARW41LK$urcqe}ob@s()#T}l7EoPz*CL@? z3HXQLV`{KHI=1x@)8Xkb9Cg1q%M&x~S|h^Tqqb`e_no`=f53bF!Q=p5~g_Jb5x-c-(RF-hAPKtVw2vlU%1xp3N67UnV#3WiwyS=gTF0xs)%L z@kNTBJNRxVUs!ybq!^P^eA&yFYxu%&IyuXih%daHGs)Cr@@Bp)@r6fSC%G>$No6Jv z@Z~UH9>o`?O_Q7$CLhO_C-CJde0dsQxLBHe249}dm*?>1xqNv(UtYqOSMlX_e0d{Z z-o%%;^5va;c^_Xs$d?cErFvF)ru zqab_fumfv1U^2O3sgq!`xS@kb(k#_$%ZKInmM_){=cROv&Jfmd_Z&Q7;H2LF8T9u4 zYm~HI{?)$Ge~s?IN!dHY$hYeMZ63o~75^=^>xZ9V*t;T@L5piaUCa(k85 zu=;(frd+1giQ2C#%7RXxN6*pM@3rr} zPE9NqTE&8e3s6)PR8&+{R20O>pQxx&QBe^AqXMEtMFl}cem&nk@3+%Q#4=eqsr1a; z@7#OOJ@>okd}n5!Jo$vZ7hKrwQ~out-_Ozi>APA){C?sO5MM$3LE;Y)UrBrw@rP-! zkycv7A0hrI@zum1BmOw?Cy1}1!SS@Rj`)+rpCbM=@wLRCA^t4!=ZLQ({ygy)h`&gD zJ@J=_zf6P8v@%0{1M!W-Um?DU_^ZTwiN8jCGx06Nw-Vn*d^_>iiSHo(2JttEzeRi} z@wbV;L;PLheZ=1*{yy;!i0>l)A@Prhe@uKg@lS|o5pZEdd zUlQ*p{uS}BiGM@j9;er(T>ur7l!RfGUYQC}A)cr5!0VCLHE(vsl?rNN5x^OC&Ym~;PDX^5v@_1J$>FR8n21ETx zPyd!P6h$0!Xf7U(;wXr8;u`^B#T;7Hb;pU$xe5S6kORv}%wzSR5MQj-2?mm8K{6Ni z(zG326wA|a;*~XMVJ!=yRFCZ8oiA7T)Ed0hURv-1*Eik55YW`j0+><-MrqO)Nb z_w~@WZ?dO5>h%L3U3cF0GjoOnESrzh37arsH0lPuq`xYcf=3wIDiODbxbwTz5kE9H zx13u&1uNW^1$QwHIY?5;GzdNr^FbJB%!6dN^n=t-J|6~gul3oG| zzXMUh%PW?{n~)JE;dGr~s3(|j#{OL0eylXk(S>NYByluU-gmP^qCqN;=!#=?w6IuH zMk`QW(Cc5LI4;Q6w`g34W$k3xwBX692%JR%!{AqLX%29BZE7| z5w?L2IGNHT$x7m#geW8S-7MB8W&D>Aj7RJ=}Z!`SZS7bXOp(L+B`2!LO4(kRSUT-nuP4IIaU=; z=j*i@z=zzRsGv?zwG9T(N?2*^eC;+2uI5<1fIDBo%|zo}mT~9nxQ!!@&0_8Z)x6rY zUecW$D6yKq#U(ml*^kzScz_MT;Jjk6?T|+x1xz+LuNx|)5)aO+hswo5LO8D>Y`k`j z|J79;wU{F06AH(9iDQ0)-qUoB^FpUO+d*o_dAVZ-*keNTI4^n(#@U+6$9d^ft!@vm zrhl9lKxR-cWQ{E31Tx5skeiEDiiG0?V#x66ipU8hQRT^lRm+?_zW8)T8F>31g(@CI5G8!Fy;8E-J|r_%CHAm$CJj%YzBWSJ94`pLyh zUGD_K-eB)@rS7LZJLrA0#mj1ne&1Ra2(2vDO9n0PE`3e0k{ zGng<$pJ0ZEZWf%NTQDoU^0F(aS_UWR8O#LFpfo8O2Pfzp>T4vE?Sm8a5A`)llj5zQ zi!g(xte+_2=q1byT&a44{86E!Fc{gqf~zWzzQQcPnaZMSE}WpdnC8pG>qC!WW{69n zQOicd`A(x+=Me3N6Z9Kq23|Fr4kze348;XaX+4~v_b?On=zpxjLC0eviVs^R|Fdd{ z03D%D9g_m{Qc}s`sH4w{GEEHR^pA!e{Z1XN{M6ArL>*|B4!}&GCuO}|+OuuZpQ!ps zk=4)IsejDbIZP$gZ)x6;o;BK&fh%VZ{ogF!gcZ~M`Z3e0|J$_w(7)A@nO4)Xi5;uo K4)4RJnSTTDbF1_K literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/msilib/text.pyc b/PythonHome/Lib/msilib/text.pyc new file mode 100644 index 0000000000000000000000000000000000000000..52c95ccedbacf05e0ae378cec99a597571e93bf1 GIT binary patch literal 18475 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 literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/multifile.pyc b/PythonHome/Lib/multifile.pyc new file mode 100644 index 0000000000000000000000000000000000000000..82adce26ae4e8d22e8c2213ac132fa3405ba50a9 GIT binary patch literal 5194 zcmb7HTXP&o8SR<9NIPCxie0`0oTN)6WJT-+LM2tW2!(N+suaXABZEPh+RX0sN~4{f zSxxs^63A6l93JxvsG{KARCwgC@W8L&2f#UB?`ZK!8q5d0cbO_i>wT`a-u ziZTr~#J*ManNrV``qd6zDvi{3r%iExttoX!S0+jGtT3IeTh<-tMrVaH z)i458HOFrWK2N`w`^2Ay_PDaLRlMMD` z_X{@b&7m>*rp~jGiIPH>Rhkt^b*zUt>84Js&dXw#zsKcNPp#3zNq4DlSL-`@ULIQ5 zFql?0dtxFix~Yd{r3+)7N&j16i(L<@vY+(xW8KFho}0qdT?1RI=rD78dR(Sc*fP$> z#+7AmVdeI8ch?_@^|zx4YUI7)M8BuYi77hWZg(q^;ldT2*^;d&+N9FjmSY23p_v|5 z1V(f(MJT8bdzya&)1^4ImU@ z3N8SVEP{wKSO_umd(k($St0Ji-2iwZfUq(J{LBFImH=xH_n_R;6T@k)5BH$y)Y8uj zus})RE`c(|t!QBvVri1GF8ljt;JQ)vZ~S!v++9~kbC@9T-{%N7P+TU0XW-p~FZu?O zQZs?~6W#{ML|h&myS=i|Z+G8u5qZERgHdjtm^=%4SPRWUFGq5^S5;*-Ku7*4|HpXj zDjHDMPN3rL4qtU-Kc{=WA{m=rPXzROUZq~ouac!~>?Jha$3M;bj~D89C&w{(NxjbZ zJg*rnBy%W|e~*rrOu7US3SE8{s2wn5jbukg1dY}eCmZBUP6{Ei0~%bBnbjFz?zCns zxf78gxdyy>K{{=fwxzSC(lzN^q{SDZM21IY^vHlp^P!S=@z|fEISJGWyrI-C`shGU zKO;JGrlw9pRsD=~&taYIKK_H`{g&o@?}{oUJ#2R<=KfN2haPv7JDfw6b5M$Rcaw6IRfpr7*&4 ze1Wf+?d00TjM=#c#N6}_9!sNDupX=g65cvS^u2`lALw{>5vZp=jE2Fa_6X@)68xIF z_B2oj{zWJ+(1$%hLQSmv#SA2{P?q+UlQjQn$ZZTc&JI+)HVRaEqE4_YP(`T1pl$zr z`l#p2qv*fqa#BO#BpgGbb>hlna=)prJquL8(>*YK2RB2ZK%nLK1=vCg0ycXUlY^vq zQ*x%z*ucE^wmvq_zKmCW02QxFlw#sRF1f^LhA}geIK`x&4m~Zw zf-jUpG#wQpaSn{EN2)gG2l6Fsx{b%)K%;_o(8RNbXFb>m*MnDrSJA%)JPH~KBMO%A z{u0=v%cK^gH!t&w3KRpPkwM2*4sf67X761%l+HZ8lQZx-&T6PCQLqF)_c58D=!JyJ z{#Lma^{Je)zsl2bV)Z#Y+j#a{A~sY(}G@hMnD=w!dGPU<{^ zfc)p2dm8G&!58xtYhPON1qsuu%N6+lNF+n`i>kUA(1vxYK!ZiM>s-Ad@Dk8o<9K0y zT>$(&QPs7!$|FZnBxCDYDhQk3V4kUE+wPldn$&j&=)cKgz76PgA7hq#7Yp zzhFy;2=JgIfP|Xn2MV-uQ^X_((FlwYC>`$H12tog-rdW;C=8UM%jXIS}dacVn?RT zL}OHn=L4TN^(T1jyJ*N@^}`y$0RHt_yS5oz!3@S|SHpVP3U1(ntYgi9 zB6<531pPe>kjDV~qi+iGA>nyBP+pGEe- z5V!W*LOZkSK*}6mF@L*js_Mx);dL0pS53(ow2Hx-aX5OaBRFRS{DmOVdJytzcqIOx znNsZKC&lk@f|LWm8hn2pi1O+FN-!XP=FeTO`veWGTTtuQ74Qucmx)TUy{8yq9q{jC z+0$Sdz|Bp87<(%URC&sHCNOV2B&joUlmD#nxk=oxigi9CiIcv;VZ>&Q4ZX4~Cp?k~ zx0t+jK30h)O8f(UEzjbGYy+UJ;IfAY-LuF%f5X7L2bYb+?cEccau2+PGN5`_sslv5 zrV5WJUqCjbmLTtXZ=os))%9n-#`NG3&%tft-&Ix%6xyOcXU_CV3tN4mvZyW^N@%~X z4xS6v=x%C%-(E+1x(e{$Z7c$OF@XiDBc2sUGfH1VBZ*MFElf8~j^r0-EQ7K1zVK<% zx3hZh+&ILnML)+Qb&QVz;t*~GFN5+}ldhiuR>m1X#I@A)d2InL#!RmGty^9+Cxj-x z8imCynf^FG1U$k0^XD$-2};O?^lLMUI$NGk3$8lf1Fzu3Kk;bFIZGtbITMMW|1CDY zg~jK~d=;zyf@dbP!^{{HF0qvDf(4nAQeE=3a1^OGev=Jl#7z4VLGfEmOJW|qR6u$! z_$G;IFb}g|L(>eKVLNIy+Ap=_RoX2y}e!1saRUANUXFAKt)XNpMZD NMiXeQh3)Wa?LU|2`NjYM literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/multiprocessing/__init__.pyc b/PythonHome/Lib/multiprocessing/__init__.pyc new file mode 100644 index 0000000000000000000000000000000000000000..7cf861d69b394e7b312868633fdb30b126365aff GIT binary patch literal 8075 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 literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/multiprocessing/dummy/__init__.pyc b/PythonHome/Lib/multiprocessing/dummy/__init__.pyc new file mode 100644 index 0000000000000000000000000000000000000000..7208aed293eedb460a966a9b955f47219e4b477c GIT binary patch literal 5160 zcmb_g+in}l5v>{0lqge{EZe%+vaR)6yL4hG51RmaupQr%?0OmR$cPg{i^+JpB@IP# z#xq09TF5{U2?zoN2oNB@k>~tZJ|H=#nis*yi>y%WR`spAy6RMQH7oy~o%z@6KWxS_ z{LJD1LzLp5o`}KM6XT1ih^dM>C#EK5O3bvFx|kU;=fyO{%!;`nJ9E;;{5di6()FZ` zg^u>64Gxa3NE@siU6nR?I{KWn!5s8O>DHt-CG9EcO-p-PJoYX~w=TUIY0tR!CGOBW zFYWWvYe>5xy;*6`O7DWSFSr?(bp}M5bL}hAotNIcwCB-Y6zfUnqHIIPB{>#368U|5 zf#>4DB^_8E4_p?zAnhwUwkYi-u@&hobCF$Q9j=I3;q3NRF;|tiCgz&hRb{j~W^`Tb z4QbyHdsEss#jc6DF2_*SXJXLlX5Spoz9nW&nSCziGbL_QxBQ~#mK;NwUx>w-zGUZS z^ET{OPN904r?D-HlE#b&d2ah!+1C88V+8-yzSiDA8c3*vMkNZvWl)3 zX}njS0}&`y2eoN?QMQ}rwwy=naXRQ5YbKqX@+9q>q)gJjE`9b6{FVA{UDlWK8OxXMv8pp@&=L9cf(RNB}Rxa=`X@pDub#sye_UH7d@qV91F z;G)M<^HjwG#J(C3R;@{}*`x$9S+P)vCn&{BRHaAQih?b zy_NQz{=+OWYMp%>?d5j6yojl9!=-}Qy$tISIR>hZ~Hnv_Q zZ?<}aZkY_BjiYWET5@Z2!j0@8xQw~KKq+W#@osu`Zw@7A{nu@X=RIu)?W zV3dP^EG7z7>QoS-)*ty%L_bdm(Ag5d=SM6)9e zXdgu0e?_-(;D7r4x_m%%L!_&4MzNxBL6}20#Ts9{w=070>+zCNB%=}4Llo~CIl4(v z2K0V7q)3)#4nLGeO*X#KsMc(9=u?@C++viW6Exre4R6Vv8{HZ;o^YHBP?&SKA<#gb zz{;ui<&iols%P;u)V2WDB8y^6f%G#5%vCfUU?9UW?k6N!?jEWTGkOY6Cc*LzN zzs21H6O6-?I|Ano-NYc~!%b*}L1v=TD#w7qMNP4{Z_W~ubMP4+R6{Xi7>g>l05O*G zNC==E)V{pGPobZF|1;V0+2)6`KSn7Ypt70}B2?4)knEjE0$m1(_l&KH)tnFq!+Qphqnl3CJF8$3 zvtr?ns*ptx&;zs)g3u5eYM2~_MD@=)W`$!#&_P275b|<3qL=}*p5Q5}Pg9F#PRCfT z7L=1Y6Ro2H(*vBNjwIwz@GDejzSMb|5J};m@qZL4c>YmQ0qC1!jhRUnJQ0J_ol>Ze zPg8}uWQZ*HFJLi}gyJ?MHm!M$O5Lyfb6$)t{ZJvQK4!&?2GF1{DCRKT8*As~1tTXKA0@m)JH0gf-@8C7smuKTvEV}O+2*3zYq$|?%c+Gjd z%pA~hRaForxvHg)WA!t=cH9&1CEn4BvXUnK=zX-2VKn#+1{~sugyHMS79~}}r(uHB z{0C&d)5A7jUv3dPoDxn20XpeFP=8;X zxcfolqay|Ukt5KnWDV3uqZ|4l+=$bD-|8Dye>BVYROe<+75s#gZ?k&FivAH$^FfQ1zVE28 zfcLah6o}JnU9ES|dCLQCr@vz~aOE#gHIUHiAD&3_-Yt~*+RC++DO}Uuf?vn`WU*26 QYJQ`#*r-?Pm4)hm0o!)g9{>OV literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/multiprocessing/dummy/connection.pyc b/PythonHome/Lib/multiprocessing/dummy/connection.pyc new file mode 100644 index 0000000000000000000000000000000000000000..c997d15bb50336adf21f4fd2b26f3cbf20c24788 GIT binary patch literal 2584 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 G-2VgWE!>O% literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/multiprocessing/heap.pyc b/PythonHome/Lib/multiprocessing/heap.pyc new file mode 100644 index 0000000000000000000000000000000000000000..89ad406ad13b9934891ea77d7ad5695d62249fb7 GIT binary patch literal 6609 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 literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/multiprocessing/managers.pyc b/PythonHome/Lib/multiprocessing/managers.pyc new file mode 100644 index 0000000000000000000000000000000000000000..6711e48ab4f633a44d0a6ab796c62b2c880125a3 GIT binary patch literal 36869 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 M9_K#)TiRauza`JTnE(I) literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/multiprocessing/pool.pyc b/PythonHome/Lib/multiprocessing/pool.pyc new file mode 100644 index 0000000000000000000000000000000000000000..cdc071276150afd2dba72db042c407130adf59e6 GIT binary patch literal 21436 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

    wfh*5CH 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 literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/mutex.pyc b/PythonHome/Lib/mutex.pyc new file mode 100644 index 0000000000000000000000000000000000000000..35aa7cc2c42ae080e37eebfc603d8b292e01d256 GIT binary patch literal 2410 zcma)7(Qe#C6usl!q+LTGNVHOUK*LiuVt0uYA@P6^1qlgM+GyZGn;kd9lM@! zH!HPI;am6!ev1!)b7yR)6;X>N&)%K6bLZSM=Uxx~-iiNu`ukBv?K8yhw|MPi42tL& zqaYPgA!rrRaYRB#qz0shq_*fv2=NU6;j&G|fL22~9+FVENX4XX(;q}vM86(yks8s_ z_&tvNQ$+N0DK?o{p-Wp<&}o;=N+OpU_S^F}v%7C&8TBi&NBQF1Fy>11%9_yzAM zv7lF#+sxue@UGXn)vqsSrEzI)tUQo_x+-fe$BV{f4hc+TTAwv5ZQQ=B(!92Dt*csF zOyuTFc5YUVd8>BIQrUgEPIJHPN||QQn;a1tCL_BEbz=f%xnAZVhh2N%oRJ4ViFtkj z2(DcPhI+%v)p}LF&>#lnRLQT02^!NDUM+=#iP0b{k z65JLppSoqOQ|0$q$@_DhhwH%&WC1a#FhFCRt`}*hW4?AyYl5sa2uOQa3^_oNWw)C> zc|P@Qsac%=gJ&!tEO#5jI;~B$IlQo6@C>j9;k0sM{hVrup<^O9^6>_jVdUZLz{M<2 zmu44*exZvTI;9YK3zpL0+Og$BW-$E2M}LRceu+V&Vo(dj!bh#3F4#b|MBYHn47`DQ z7ha8a)`ynl?cH6LmpynLSuXsI$q}ki*Vll=q`N4hwYj*M=KRxjr%&Lti zJxTbuB)P*ocpF6{(I>=7`Gju4KnCXo_&jMp!|+5yr=94b6)s-Xb$@j;?>cAH!Qv=y zhvd^l*iZNj&WxfSOwaD8m=0jujPV-m~uskLirBcIfbZoO=iWm+q(a47>E;L~%Ao1Nxt{NH3*vkVNl za42VGxejPB5+gB;G7jIp{uT}~5fZ;5s_)TD@SF#6K{moWcv z<=)>V+O~zj5pz$GZNa)0jyq+cR^^xAXp%={==*M_17sa+1ZHVUxzHdVV+tLyJA-iqTT3Uv>ZT_ literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/netrc.pyc b/PythonHome/Lib/netrc.pyc new file mode 100644 index 0000000000000000000000000000000000000000..3333b4c86a40e47ba54c5bf2a813bac1aa7a71d6 GIT binary patch literal 4534 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 literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/new.pyc b/PythonHome/Lib/new.pyc new file mode 100644 index 0000000000000000000000000000000000000000..2cabbd31723cac633e84a15677642bc1227d490f GIT binary patch literal 847 zcmZ8f%Z}496unO0nRe)c54gMODngni2q6tZ8i~g!Qwb@IR1({rnn~;syDeF>=7*5@ zDn0;rPBB4HZsH=oF=jQL(hWI7;a2JeRSPkKG+)~OA5ZAu`Z5QH@T&{Qj^Wf z?8v3kc+trqx7gJH|Xq-~+WT_&eUF!**uFBlnC2gyd zrX;=DYVMTL|EkwiF4tV1RA2X2GEo}It`3bL#2$}B}b7F2puv!VjSF6Vb(4uTg zI=F!ce}Sp@8UnbtN%x%gj>`JrGW8#8i17n^hiS+^C;6yU!DTx1ksi8lAoVVsPv_)r rL2o#L^_xiU-m2n`?jot%(Begx`O&L(WcdeNLt;TQb{*W=I| literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/nntplib.pyc b/PythonHome/Lib/nntplib.pyc new file mode 100644 index 0000000000000000000000000000000000000000..11f906dfbed50646ff1884174bc2f82fd83ffb3a GIT binary patch literal 20381 zcmdU1TWlQHc|NmTF1agG)XkEp$kLH5d6zQDh_qcRjBm0;QEC-R8Pb+aOQAS|8L*_pEKL>@4c08UVdk)uHt{&@ckM-;XpwtSE(7KmU0WK zVW}BhnCpU?DJZu?xkcr6Dz~KEF6DMBx2)WXaneA!@#rl-jspe39 zhk8$`yGp$^gK9Jc~se@ zT&-qybMA9knImcIdzANta-UK+3Mx2Oh?fa1?p5y7s`ZBD?Ny6t`l#xk*{{6)Y7spg zQ+H)WS?8wZKBHz1s3vCl5ngy`5d(Qfc?VF;nmMSvgK80Dsj}A9PBn8#%^X%U7|szj z^OW)qsflxLO-*=DsR?%g--q#i9N!w>&*J+C3b2i*l{=`A>kg@X$lQ0gpss?TXzr+K zWo@7Gj;b@)`qa!Z|cGq2SQJ>Bq|-f(3+2wGWYh*5evS`C^YA{M2ky|ucx9QmjLN=>)) zax09q(@bV#$mL)$NI;<<#?o5$nl)yT09eYPI-sAHGFY8vq%wRhL-{ zp5uB!x*9Sq_E?*X=XDl?b-l12_-0VLHK(0MLoa!tr%URf1(`0$umrXY(RzIEdiuK8 zXx$pFOtvD-a>2n&P}d3OS4~l;>7oHnU*B{Zt6qq^Wh@xl$qiUHSC_7PL0I8hg%Ox% z9vwGZQSx9=hnNz3@YZEP1C(s6>s5-z9A;2=8uitN6ECa(GyI#3ijXVHQ?xz4u)XER zy3i-u6=zL*6bL8SkbTJumYgO=X-e;mOD8gBa(m<4Gfw1~92x+R^q<8v8|zUey^qjO z?sggNM_K7*%5Ltlixz#=tyENw`;hiiLt`QLb$r5o>;M`Cst_s6ibbUg!(mU=V1rb6 zj3uE#Vr9a$B83ulkTGMOZL&%yJ`?za>>yHV(NedSx^1a1S;|`9$t(2IkG$D}y4*aV zicyEUQBlFm%CamdH1nissVf-MR1JDfP5MYwD9hN&1ZLj93AQGgWS--RWJH*`nw}$sQzI8V_6k7(S0M9xli8 z7=ZA2_{bw5o4x$#BY5HQM?j`L^=Kn_3f1gH<-0AYG%Bj=-aOReEk9ZSm4;rp_Q-2P zCK-RUk?mzwu|60|A~Bk}xx_h*`n|^xdy() zb&p&F%Jxb{pxNzmv4<#~O##WG7=Sw32Y?l9J_GbBa2)v66$Cy52rHl)Xw?;*Jp;gu zihHFZkn=ui4VV>~`y~@Vx?eI66JWD1;7~mMh&(+a*9YbLDY<@9u2JBS6h2BE&RW2w zS}vZ6LHJCS=$nsfG#p1kf;v?l^&~mqG(O=^KojVGYIj^1HE*e?pcXqMzo6y{MAs}( zWV%>Xi$bV4Q)tDfUGlV>P?)!%RYBcBW~T~%pw{=wQ_!s=X|1d-ulxXJW}BFqFVW1% zeUIFKPg!@mm36yA1>aV;yVW9yT2vZjr)%(Sk{yk&d|$n*6slbT>R!L1ZkJSWh?RQq zWgM`^c6Fz$ZkN^Kb`I@MMcuBb#Xe3BGq|%&-QFg3z)1zwe+RS1RT)=BwQ|TpvzMDY zG0Gh>s!Lg8-BZRN92m0vyj3qw6sSzzYYY zt%$C<-kh`AKsI4Dx^kVsHNFr_59Hba;w1>Oc;b#;}Q(5rl2rBecg=xS#!0=`a`qWwEw z1i)E9{p3;B0sV-u1)%LO(TaF=FARZ1+3k93Rd8|w%(^kY!j2#g8hFrHs3n*AG zIrRnjAt)>U1_#cy2Ix!cnh^|zKo$O+Ur(k2$Q`cM7c`u!cf`G`g52lLSmwPbt-hK8 z5{{xBDx(pOeaW9+0DAWTTF`r#tDQ}MIBgM1M5*Aq0f~f5xs~=ia4!br`I9GnVi$w% zebx!ducW`eR($$uV{dJ~%b<`HN!UZLUL&>e(j1wVz`0G!hvMxmvnOcwS&^w(#-{ zg-lPxjoGtV;b-<7u@BE4VymPHmcyl(IgL4@TTD=qkK~MC~YBWoy6n z1k%1PBH|8fuhm=Vu==e2Lb*`s=l~k;!T&xyt5|z*S1gpQ-9YLks}EPbxZ0K0t8=9M za3N3QBVG?xCk6+jX{iZJhWBEiCeA_InY-9Y`Ww`l@Qn6}$prrw!Z`04cU;txc>5{O z*1&Xdh3U}3Kc=*W2p0r!OTqKbEoWU{U)PBbQyUn_xE&(J_ELaWr&>WnqbE)bN;H6; zG43I5wJz>?k+{s6loeY^m1T1^Jygx?vRJ^>YeCURE(`)1mimpmd6)TU3 zR%TsJi~(RHL=nrCZmmYkt5Iq)GTSf$B`L6u~g5lBNVf$A-HT}R$pq`jz~ zk!5rY%NQaaBW(oEEs5vk=?m@$&W8(af)vZkB-Cm9qZiIjnkD5@i%TktE7B};+H9G{ z>UztV;JT^Q&f=;hXQfWB6KJ@*71JJWFgc0exyfOUmjUL}Mn;09l>}?64@}km~9M+a)5$k*Ly#^09pOl+U^AOPbtMR=&l$ujD zF|TMQx6pBDFl9OkRp;4`!N5e$z;>xBv>hK9Zv5ie*xxlOH8a)JpY=uy;lY?yshVQG zZUHGFz$nZM<#ycvDWZh}Dr#kvvPm28 zlbt>w$;ssy4g32?TuSIib?k+i>%)H-J5{!JC>TC`gbT<4slodKZVVUPh3Aqeg#dmX zB_LsVBLSddLFqfl1h*h`2U=dpm?b7P9u?&g=$~kg>=Aq`_!#dJuo!kp86+k%EN_m? zn3r}^O}x>hZlvl>C-7UVVH{)<5S}-eKGYDQKGnM^Gb{pfoSOc)C?nR_fO`5moy*O1_Uz$mome=&>lK6~QjVFZ_rGC-<|H z)A)q{garN;Xz=O3WGh&00s>PaQ{k^*!kK>Ezz@p}PF7 zrg?)VczhlaYTh#51eNHpaUdu`!?BKFc4e|guq&o)5_(A>kdNI5;{c2FLn+B~ZpsM# zMffjVoSd-7r!EOL7e*5Ra4Ya5Ph1OQLM2mFli^5VH&Hni^vfna_bl8BTUgN8$S~TH z)!@LXLZIC!3;%*!6ACW^VHf(Wy@ej&W@73NLDxmx_2O<%VNXZN+FrO9X>fbNs1+mT z5|039GOo|n3Wt$obQL$*N&HEHUnF%N?G78YcnbAo={}g2v}xVT=viXdssL3;>E$O? zg$HnRpD}|!!L#wOUq_h_G;Dnz9?ehXG8)XO588OKBb#UsK}Mt(EdBPjX_4^!aB8RV z2@fJM(}HRMHTFS?@57|_QS?(B^Peb%O)5qbw4*1-FHhJP-?%iDkR%7Ua|nBgF=B)} z%+8yxuCFgGxh}Rjjiwcuga&4z)Bq1@MlG^B3kyq2VR%m+7E0^bvJsde`ynw21fK2t zsPJaXj_mon!2pec5v_j+$>NRFfTtJLS70%!K*OQ`0G$>&(o9>Y>6?3wmEZ6(-aeki#_az z6LuHpcObxW|I*5{>M~>)cVa5ZQQ@y6$ynjS`Kjrg^nSP^RFg$Z&UVDdFXkG~{D7{- z+wcP-B^-sgcs6B8Oqd+nu+Jp7(JBs{$b%5)Od?Y_wQXX|>^E5$>#O`t2qGm1NQrKg zR-OA17CL08K}w{m{^Pibd`8q4(m8|1G5nh`{XACPQZg?#7Ti4Q4cQj0~NN;EQWmz&kY`< zGN6mL*%1SYnC6;%K4s?KC*aH#4b~!evqe!Y-@pY%1}`2=3Kc;IO+uD19<=w!B7b*K zqmYw3fZpMvVGn3JDJb4pTR~uPx&xhRZJY+@%(a)*9e4|7)2_szkkLoneuFRJ5ZYtY z4%ds=uEQVv2LVpjilgv%89k$jXe*9BtRkWG zv{@#A7F9(f5qeHgUogsv@dSGcnL^YW=U{9I0|YXz*;rr&)RWfCFw`doKwxlIIKalj z#&Lo;OL`C`P{X5#9YC4G;|a0^gYT-)SLnBP6b}N5_aZ1>vb524ZS3(w6wF&53G#q5 z;HVeC3GnT}38Ugn=0iN7G;YBH;Fu!(Nq#!X1I8$k&xG`J1Q7-LuCP|8Y-)lDzyVoq z3Aw@==#aVJk+R$h1xKN5m*jp+a=TP)>)^evd`qo-N3DEUJWGri?2Be3&@|TxEi8O= z9IKI8J)wQh>?NCydF&{}8q3K#_XAU%U<_p&$fZxTb+9SN6cKuslWB4&E}QnEArKog8dTs>YTyUz|q`0c4SGp)jYlahekFFpHG!kByFuh6@0rkIYC z@l5NyO6@kc7=oM_um*d~)E&1^Lt$-M61fudCCGr25S!lIjOVFDuaM^t;X+lonZxkN zc5y`+FiAcK4fj)`JMcM;k7$NG_X~0sxYWYqjB(D5U%>HMvo#BI_1Ij{?sCMKNG8sn za$uBW5k(@vbCb1@1{S==a=`UqRn=MN7qwM7=XY@f#Sd$sDRB_*!!!`a6HfzfuorhB z-V(|)LQcdfih;rnNkgQ^2=}UJ3ktU=abhEgvB?E4LcNvMIQ&C3kN6FD3Pgjp$H$kQ z0MS=k*<^P`1Vm3wpPC+o*Lh`{K;puw9CQ^`En0eXRJhdkFg;;a<2Pd^lwD^+-ps{D z7zeRekx1=kAYZ;~ud^6F57D!7st|#jNCwP9MJ7sDFs#R&NA5C`@pc%dYwF{ZIr&LhLv}i4gV}(!ctPoqWD6>SkSU`{ z9N9`B^M;mvW;A*|aakJJVjN4wr z1izdcGewZxO*)7ezJ?3Kzz{=le?wMZI;(o<4sX5Hq2i;UA(&TcnkPGparf^JV_6eTPrC!e`X0;B5%- zS2%m#s=|I8ix5jdPUA|*3Oq!F{{v+*j^jkqac5_>^04WDSA-ubyqVbMq}o_q+7?0C zG%UP{8>)u!8x11pGF`)SpT{~pf}r#Dh_9v0S5BkJ>CzLRw`otqfU&&aK-FyZg@F>T zdCb)(ro;;%np**K&@B$mf+tjNh%|bl)5d$FOJ~PQp#`pKtlI#=qM$7^B#rq zn56$dNi%W26U~@ged?)f^*6IoRGl$5eJfr2@|MjM509nmuBR@XdNb3~j|%q1pOL1_ ztcc3Y6{DA%O^DH(u;JYFevnS5Sf}OUW?pK+ehW81?pbIDE^t1y1MfYzm2(wQ9x-BT zHobI!0@yLwH~gKs_KNuH;&Aul*fY!O&YiIn3!-Z+c_$2~O5-gWzzeS#;@!0Y0GI?IwmI2&#m+dZ z=EXA|tuK4J<_*se>-5dLyekZ~1_hJ7{niX{)+mQ42SrPmR|Iu47#V5?qp6;FY)NT% z?`rH^UQ-*;v8yMqEPbl>_KBg7AylPbWt^(=s^}qEDcO_A9Bzq4+4OJhMJ56o9A2Ga zvciOZaE=HPK|V96r6avrW`Nv(Z}Ugeo<@5R9*GPXc4aOC<$ zG8}?VU`nuHKfmB|@(TeZejzr*uWs{&1N6p)WnRVPZBzYo!qV2|m67!QvcKTLe@X*l zlIDE;h`NI3ml;vQi_qLm>%lxiif^hWz|t4r9N!X8-=Cx53-Hvsd=ZUESTkk8A&qlw zV@&RS_F=Op#sT){DQz+S<`k%h4DMzQrb9}sXZr0UARl;mN7%y=exCBiseWwwFpNDQ zxYMkVFxOCs#Z%>tfg~DPi6;5fcs@0UPi3BM3K`#BBCCCPAjhN3c`9yKuk9 zoExABu&Ri_U0k#&X@o%XN;>mA@{%xaBmrS{gi&$I5|t1;Ps8fa(A_FHDIy_ynqhSb z#X>QIi>;ND3V(SP7L)Q53?|RQanw5omk(3S_h;fbSSnxUCGK=*rRERgy$(LVIRco;Mgr* zk>l)TCRE9r=~FU#ycPCesY>nYv+fDllXNLR-Na3sN~MXGxZJ}6_Izt6iP;kfh?jdA z=PQ%9Z0AJ_CNU_60k`3}721WP3k?XB8}DoWE&9*1(4|w;=eAfq?XY(XW7_otyff6oD=@sLa}#%Bw3N&s7w;Z@ZqjVhNhFPWOO%it*?N<2 zo6F(Q+*Y(W2#l`D-VVn%i}=1oUD)Afd_dB!v0yh)uQ9A$CX6lbFIYQFz=g%AFGZ_- z6Bj8LkOM$DSj%k71_%Bm%a}CqDIUjLHU-(F5j_F2G64Mc{SRaI6YG`K5yo{92!^?Z zkv+^fFfzn2!`h;L_!Y^4cES)OC-~EQTEu8jD-QlrmcoBUl5i4z@iV8UbGZ9HFpvl5 zJ{-O<2b0dgzQOAGk#ilcFT-W=X^oHKTXY&u`;426ZCsb=9UgulBN?s})-pQ@YwzS3Pq-$WFb74&TJ>`a0S75u z+1)ED4OSzs;$aEf6WIF0!_N`hA!}d!5Y{u{KMOdG144O0Z*q`OtYp0Z*M92d(#71? z!2>*vIqtWC9dPJ7`TdJrpy<2EQ8e%g&!1~|@b9B(%q~D2NE|YT>3&>*a2hrXet!ItvfE_( zLnsJdaU|*C#yLc=!h9@Kf?vr`UdWqde5t`Tr`gTih5PKUfS8ZMe3{-6!}kYhX6p>d z%Kic(8)s4u?B4xg4y5&^`r$`Z5a0euIWRVS;DyAvi2?v#h6=*g3JSghyMq)wnr=_g z?M>N1fAWp<>Gl+s&Nc6Mm^GG{Hq$+owt&PIP>2W{o6n&M%BMZe;d3c9sc`-PsFF=9ma5{$*Z$hRJ7{e2xhSp=3A4{yeX~ zz~qZeewE3uG5HN9zr*BrnS7avSh7Fl)mNGP5t3|uvr4&GF7}kl+j@G-+sdV$ zojnJ7cHsFF<-O(o0`2gVEso#B54LbA>DmY;+M; zKVD_RGkAHJK5YU<;Z5@wt7Ib@Kifn1Aa=>^-{f@($*~theJre1aVfvdVjP#FxRvs= zvpAK8ACaM`*gZ@biZKT?C_?7NV2<9rXT&CLc4T)mAuO{iOuokClT2P_f{$S?864~f z>v+wZegG@Us$7ipt>-zM@RlXw`__i{D92%T;LWBNWAisZ3}?VWHe4Xp_{&;yfma-s zwoG{$$4lrEzp3*|Kl{6cq|}A2_yS)H#w#?XQgLs2Z!!Mg$&GsX-&raiDV92S|4jW% bRk(G(n=cXLh2UM*A*<6mf|FC7v7r4Ajweyf literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/ntpath.pyc b/PythonHome/Lib/ntpath.pyc new file mode 100644 index 0000000000000000000000000000000000000000..7035f690b1ae1a49c510cb46ea5d4b7780469c9c GIT binary patch literal 12974 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 literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/nturl2path.pyc b/PythonHome/Lib/nturl2path.pyc new file mode 100644 index 0000000000000000000000000000000000000000..131a797a316750a843fb7dbe1920e83b44fb9639 GIT binary patch literal 1800 zcmb7_-EJF26vxl3KQ?h4QrfD<5|j~0t+^nTf>5P^5F&7agi^EyMXHRHTs1{WzhQkHYV# z_}rT?DbW*HMZch-C=H|$P}-vLsLfsw_0c!Fiv7HZ7e@OM12dZ&{cZG> zj*C>E*~Dmgx_B?)G+X#M$RR#=j1eS4ikxVTM$=Zb4roP`Nz$}U7Xhu|+2+BMkm_gL zNIRs{E}aBakEI{d+wdw#mbNI}q6J+9^R@9uMQq^e)gD&!&uO}R}my!iA5zsH!(dK?h-)?>xxqbuRKD{CLYo%bK& zrgr#%e}Z{De&1Clu``?KL~hO5ve2`-T;Q^5lgHkkH5XRSw4WROfN$`DcFEi=J9Ix$z$26!$M5e^J+EEkTx51$DDnu`~Ch_45&TBm(kA z94X?sz6XO7sLBF?o#f)KL@}@8r8Ul2CYhBH){q$Y7Fve~ldsSHye#$~O|YX$;gMpW z9rvnp--pMh&yaCyCyT>3f?KK|+-&ct-Qcd;Rqv^u>Z?1jx7Cj7s(Zmb{3d*Yd`evJ zA+NrRk$-UqNE))92uW>_)e*8jWXweGugC(UU4aISf(tMTWeR0bCSD;6PNG!chg~<+ zfi))U*Ow#E?hx*f{0Zd$8^b1vz#>w%H(*H$1Yq|JiAiz`$yhqfu9U-Qc4#2bb%_ZJ z8p2Rri|Xe>WC+4GF_C@%P*0!pdkkL3BR=hGU?YFyuCUM$aup`w=D&ctE;bP=AtA&u zCX-2nNW>lCM96TgKZb?na-bcn17wZ(zD1xBQzL2=7$TN&#Dqo6RK)ugXTh*)mhAG( zO*XHyxy9x-%>UNy<{!g81biO>+&eH7_BX0ktlAN)HW)&)uQjSwMbKslYJWip*c hcQ6nQU@mKr)-?d)9e=zi(`9ZxVH6y5&<(cV{Rf=OaoYd@ literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/numbers.pyc b/PythonHome/Lib/numbers.pyc new file mode 100644 index 0000000000000000000000000000000000000000..3bdebde90e92a7b2bfb507ab9d6fd4c4427face8 GIT binary patch literal 13082 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 literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/opcode.pyc b/PythonHome/Lib/opcode.pyc new file mode 100644 index 0000000000000000000000000000000000000000..5fbfe3807686f656f5aac47047bb70ea09ee1a13 GIT binary patch literal 6124 zcmb_g2Y4LC6@GWJWm}eP(?dT(90UXh+jL~Z>Tb_Iv{$^hC&`jwIqR*ZG1A>xx5O3! zLNGO<1W50__a4%F@4fflLwbMz?C$6!^nLIpSl`Xg|GzhH-n@C!+;v}H&%Gm;S0^a` z*DK$P<=5V^f{2O6q)ZW~iMxoG5ick1CSF0jl6Vzy5AkZ^UYhKsF;QES8cWlpwCd93 zGF>j$Ww$O@=yIhlSCJA;v2Zj^O50=T@Uhi&U_AxB00&c)yYwg;>mxpvf zn+CLq_Zcut+%_O2zS4ll5brnO0P&mwR}nwffUAkGG2mL_#~E-P@#77+p7@{vHxS=w zz)i$A8*mHptp+@S_=yJGMtr*gcM#ucz>|pYGT?6FdklCo@ly7I}Es&_?-s4i}>9USVR0C z;`bWxKH~RBpo{h%ra?-!2yy2F#2++jA0qy+0Usg$r~w}%{k%ryDR=^%4Prqv9CMyTr3({q{j zRDCw!%zS6go9OMC4FcUqv!zWf7p-P%rrrwsq_*7}wtdUpRx8>iFT`cT z9`)=}&dz}iB|0?FPNUqSKU<>DNn5mNtLCTFAw1jN06=85- zB9OsLaAxY^#8lWN+@O^UD*n8+Py2vf(@-X z9WoB~$g~_QdfG2a^`!3a*9jtqQ`#>iuK2Y#4JVP(9o}Ii?%^oliteD^Y6T6B{5}+t z!=!l7E+RuPH1Y97sm4C`Jv2UQZ;yaGI;#JhcSub(av_$PLYynY2&<52nsCdW?~Rm|o=Y^+#CF%V6+)+Va^zGQE+G`|`=8b$i0vZt_e^@5J5Y`HXS zyPm=l*Q+|B3lWQzsM*0n+~J7rDx_WrQOp)=j#sESI~7t^+l~df!f-)CgXnkC#d5CZ zl+}@-;d!iW<#OsMa2=+rwL#CdvYx`4?zAC-YSvX)nIZg%ZRDMD+4bXokAV>B7z;hO zW+yT%)e!y`N)^Y-+Wvx;$3Y6SiL|rn@xr$;(^aRCwNF1&VO@6+8eQv^P3p9z=*{YM&`6S;?bzPD@l8we8`b6|`AzDqCHc+j zY~hpS7vGCkMV$i*$(Fd}NQE>|;&$mY_uF5auM6al}frG(FuVjxng_5ndFQlO=TaPM$ zM&K7{Lvjfuo#Bl`FtnJDW8i>aFs~AX;$jj}D1pRCk|7IMPPjqWwuXFJniW+6hY1@g zc-#G~V_T(KMeP8Kew?zE6UD6MRF#{ky0%wyOa8Fs)NEBvR13vQ+4cOYXSvD)i8-)G z?W|BmPt_8=odw&;#f^s(J#5m0($A0@N%Z6{ytKq3m4)QS~3G~E%)&8Y@hZ19>bVrme*MNghaV}}{T97d5S_O&Iu;t3NzN)TIXjzhupRbj&UZGr42NSwz4awP= z&^LgFZ8$_6lg`%Mmbvq=;iG>nrbHZ7 z8>Wj}rHhNCi+7icruyBZUqB%Qv-QSgpx+eHy90MK7nd;?7cUo4(U)i!^UyE9j^Y8H zN7!-(qQ~-9bk*J<-gT$frq-r<cXO^y|yC1CP;`Zsjq-FAjMrVD#Ma1eBh(=%fzn!wfng9R* literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/optparse.pyc b/PythonHome/Lib/optparse.pyc new file mode 100644 index 0000000000000000000000000000000000000000..0d62681bc3cb9d7777f20a271b2b0a74128bd6e0 GIT binary patch literal 53424 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 %wE}>NDIKo*i*hW7{y$x;G$Lm)dLM# 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 literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/pickle.pyc b/PythonHome/Lib/pickle.pyc new file mode 100644 index 0000000000000000000000000000000000000000..0590bda40eeed54069d2e939aa4875cd44adcb74 GIT binary patch literal 36909 zcmd6Q3v^u9b={pA5CkCb{{cZ#;)o(eP$DUiltg_fN+bwMkVuev00n78dNi2#Kn@Aa zfb#|t5L>n*%5f4a|CQ#`x`~sxX=*#4=F@zd)=Apfb&{r8X_~}w635BPYO|7b)phGO zS&6#$KJNz*BtXkqtK`hZedpeH-?`_WbM86k-utHTKUa1A{MaiaRTus1#NVgz4gad( zobOx-Y0i~$&d)o);3o5Kl({xHS#VQruGHpoyk4Q}6|S_xO|`pHyPI0+N-M3b-A#75 zQiobVzSEUD<9wGZb;bERT~{Vt=dX7D8g~gd;&QDk0kY2d>z%*B z`5Otjga@O}CRbYHf(~~Dbx>iY3)Z^{V7}SC>D+baUMk^+4i{_?v?qb0jm{XlC4p{o zesA2u)&#oQ&7nGayvOHP4=yg}ST=PT@|AMWA*K_X0IXrJ$Tw}Xx z_;HPGs^M>Ur8}K}rz_p%{JUIfhx2#1QqlQESGwEzce~O~=kIi-dz^odEA4XrE?3&^ z{N1i}uk-J9r9IBy<4S$b?{lTS&fn`w_c{MQSGwQ%_q)Oz?B|w z{sXSm@BDsOI_Ug^u5`%xhg|8f^AEeygU)}@l^$~bL$36&^B;DlBhEkKN{=}I5m$QD z`H#BNW6pofl^%Eg8$h5y3#r4pL3<>o&UTmdCvD-X~YEsE;!?YVHccrm%y8&F6eew&bv#_ z1uu{RPF@6k$6RoSyYiy*al@Fqo_Edvo=4_gd3Wu%^4D`N_wpFIZvu=znhg6(&OgtK zQpwejzU=%Lba{bX%Bo{Y)r-!5QJ|L+(7R$DFT2t!&M)cKit}GqW;|x83vRONrhHfO z$uM^(EcJZ_a141475umYnG0;@UvzImJ_E=6yOf`BepwA)a{epItaW}xnaeJyIe*+; zMX&!`A-GJUyiu`zxnsJ6lbU0owVP@HP`Gq|&Qu2#K@zY~pSu~O`tnyFsi zTb!tbt)N+~O-)Y*Q*l!V=H1qqo+~$lOVNE(LG^N_UJIvm4S0m?}=| zDNQ^)^K1jQ8jZ=Y7&c~_RYN0~Z3XqP_9~ETO!4tVd0?^Q(hRs^-s3P4`*1_Z25LD*+C zbyHN^R4LK$QYAQ9~o*vhyTp22x48Jkuc zu1NRRiYOBbL~;wnOc)aXLkIfx_h9n(V03*b`g^#RM?DII{*fdn@C`|j0J4t>1!>-S zBO+AzFyP0VPqdnK2TYfJt;*QbFwJ^o6 zh>K>W7DDP@yBySum3nc;gh5Kd7?hQ!DLa0#)hME;Vm?X6-r`gM&EP}4C{*gKMyD)aQ?h}V5U>_>Q>1G4MG8OlcLxmnk;;kNp&|bv~ z>xMyfrdeyv6<@72CZ!3ZP7XJqH(Qr0t!UKK!7ff!=8Bccuu&WjVzT;Z1doZRitN5( ztzMm+@sTx}jnA}-^#;B{H3&m!fyuezWNoSj5d*#V7LT`}TTm&G(CjM?o;?-ihNh^# z?Luu;>V9#k?gz7iy~9BvUk)aN($Suil$A$Xjp-X%ZXGHng2Op9k)0|fE&dL$Jt~6t z>W?Rq88!U1^~7lG4jcYf7&uom6^JX+x>? z<(l$MrJ>T6(!EM&ls+vn9qK>W6=nLnLXP13m42<#Hw{0T_(K;&7hau;+(GX*11)UjY z+Fh{HU4hHdrkd~r>~e)J;e@oSnmiNMhX>Lj2%HeKpL{yqo3J=n%Q{>``;nE`x&R;e zBkf2fgFr=kU+mM} zF2Dz6J5dHF44#TyE;=jnvf!@-_@KtUcrYB6ZSHEPYyM0wg6?rg`6T&X^kjO~>|Ph( zgPZO{v%uB{2Ci71&P{+1%J!i_%k58c2a?ybkhCE@L;Xb?pxOCW+ zg49@nEJ1zN=Ab0e2I}y#UC$}Fs{rD1rJjI{SaGC}{2V^g7ENHS%GH1q4^7AYleMd` zDr9aKX;{C8sYugRWCs`hN~=PvGpI~OdY%*TC~Xm09+gSXcCALWFr6SW6_xGKPG3{sdEHaHcX2YZ{&AL@g*=UOt zftAmejb`Y0PzRPZz+k&3n845qFwN7isrW(xU8-`fotT-NoWt|SX!^{A5q)D^F4r!> za!8uNv+L~16ov^6fB>W;2a7nT&mOPUE6q7NN5Q`0I1EEsR!K85Dn z(k0Y5$d;!XcvLVkQLEN8ghV4DNdMz${t#*>kGbVt2QwTqG96TF6LZ%0dT^YiN?5pZYAqgeiePp#2ZFQ-J8?}*ZE+J$e3ieg>n-{5E&JujUS!5pYrh=(PtAN{pii$Ltf`I8&g>Jvu zTXZ1}1PPI877u-Ddo5&)@HJ-0!B*W}jZs_akv9bjGBYS6G( z@X0CO0aZRC3o_h+iUX5Dr8!UW?FoxJ*`J*mYLZh3i*!(;VrQx?6L+vi6VZ&RaX99X z>Ka@H8?5;{%f_M!4g(8Kl2zv*KS6yTLKMbe;bkaLzlhNXzt6zS2P?)cp(J4wYY9qg z4izWh#?%qupem!k0H6$I2^kfIJTW2<*@9}DuXmcke$#Lfc8rLSrTK4Il=4VPjcb+U zlD+G37;imb;u+mhCh>lY!y&`FGqLfCcJurl8751oVJ{0K?xQ2+!}TxaceqrZMkhw0-JM*xtGvy2o*>Om~}_k zadH{*_t0(w^49mB5we=hIRf&oX9TPUa$@A88t@x>M*7(7aE*#a41KgFAEnFqj!{^SAdS`e|@9^~5;it<66a%49e8Z?}sv5mRtj{M*!zQ{lA-qvk`x|^ivXPTQ zT%F&T|No}{PY*8Ae*o2g7GiG@%FZ4Lbp` zp|>%lNMMYeoDfqpf>0^|9bw%9wM#PUlp`=k!8I?dCCCx#K+5D<_C^xLd%>B}Lrey- z8ih<7CGK_b5cJxInc{Y1Fg*~_%(NETZgeialUpX!j;29lSQ+f~Fx)sujtD;8iIjeaE{Rm927u@Uis0VU<6#BD9SmJ3J^YByM=@Tc8jJsE@1x z(ZxT7oy&+-(=J3zJBhzWkaD;cwFWBnJ*{Z^DDG}Xdhju1!@E$t8?!5I#%2IZpdOon zn7&&xSl`ezQj;@x7?no}i>hLh$21+^E|atM8m6HJEJV!tFsijWA=TJNgGcC2Gw_e) zk9w;NZTlp_wB0xbm02bQ>>+sOyyux{+G=C9xoNYt;-J1qD@ikSEevPI6||NL9z{)l z)i5)r!KuLXm`jt5@yeuBFeI>o5TwnJnk%XL)u`FEX*=vWue=e~NE$OzYfxlR*i4`a zqGlnhS?_V)L2M_aRqYl{IL%k3C((hb_aG|VT4{L0sIrP0gRwhKwcVI%+X`C{Dc_2} z-MRJ15wZq<*Axn{D_7;ZA{fio=b3ir+jAQV>vL;Sb3Jn1ut0HNL6bJM4{?>|A>qYz zgjf_)W0o2THoPdkxvulZQF?}Gvu&489>do47#b*Kcg$z^DifOq5#X;V;0lkR;8Ra)qwj1;I3$Q?!>c$>PRnt*baVq@u1l@`)clBSJHiPfs9B=J^+NaX0nk95)L!9-^?3o58JD&pvo`!vYie5&pQ zp%CUYbe@SduO=Xw&FG|+`6`2+H>(*`dW40p zCYE3$Io?|gFE?f;q1u9C#Z+Jvd#_d|C(GsV9^5s7h1Bd_nR{4^%S+OmS}nrBV|>XE zSR@NxgB6N6zF_1N!O-me$P<~D`!8C{X=S?Pp&YJyqZrrkUrv46xvw=FTxaHro?PWV z`o@vgtkuI-1#Xu&37ALqC#4AAPD+v5Mp9$y5z^^WgEt1a4kOHa&eBrQD zh$k_L*xkJHYgpN4TT(|Ed8b%cC*fG&-%X7%ZwjR^QI3zY-U|5P(4cD|&z*%m+qz(o z7ocgkDeZzj?aHmn>u;B zO^Lj8tQdTudr6K4D~x*Q2PHMgpE`beWKe@BC@l$rzQUf4V>`r;vZv%ahmqNCu0k8G z2olYI8yV|u^QWX&t+f zmLX}Q!3OACM`ICRJ}9|ifzhAvh4d$Ee6AJPg62|T2O^^pAOgR^A>edCIpPp>=kChi zg<(jXZ#FK%4THr3;D{A^CV>hT2j(6oL(RUMtVJ5$w>bo8yXqp!^4E!q|qad}ddklvt9 z5X1GLtKx@i?~Y4N%#9<-Pf>-`hMgzo5j&E`F^}0yL77`DP$RYy(ddsD8*y$OdFHG) z${5Yas5b=0QS6456OhC^DrN9OQ?&v@3wX=>$0+T?_vSNa>Id2K!RJX|&iWR~Aw%7r z-)0O&8YguAZd^nRHAtDFj$KrYO*lbk@EV9YUpVV0bgve}A(4>V*QE|%BuB=uK@thK z2g$eZK@ANV(SQY;nVrdj!y$2;U%um-DShZS(QvEJ+Kc|Ia&y+Ac_KI3EE+r{4t6_bH9qD z6R3l=j+{)c^HlN`*6(iO5AK&QNA(+N=2()p<+2Ky!6!W9yW(3gVi>1Hdo*8|3ksa?a0p$YNV9ZQ z%3J0ItokT<8CJR>;`$Zw69r5YZ!L_5&}Q}@0zBm_@B4X4`S(7`H(~VvB=fo5#mBzl}yoWrCk9` zWL7G0sI4@#@xII^Xz#(5{<53h!a+TGajpDqFrAb|?%Mm^STg&=Q@x51=kEzQxywmW zFSHoLsr1o-g#w-%;T8)M>V5$4Agi-d?D(dt$1rEn&G6{R-GIk?)XvTEfY^*vmJokS zFxi}Fqpa3q+HDBHX~65S^Tk9K-TOY44LaAUuq^YhcOA14W2nS`cirH z{JGQS37k3ZJ*SynAoJF!UM%9r*q`jqb7#+)yQoNHh^3N4)T-uMQm3LqnQckRGR#X0 z*HGXLmbNc-8pS0QV!Smk%S)D`6apK;sOBJIm7){wUN?hg`PI2LI*Pe12>z^w;=D7r z2`~iV+TbP<(s3v1t;=uDwH2auF>*Y=?DO&*MDOFMdV4Mt4LczpU|aEASzS2IF7U}N zU7+I_3K51|7l>VRhuFk|JCR_?vP&jT2#9g7Nf;<>*JNSxQndY1GvEn4K#EF)HKsT{ z1WV)-C@@o(SBxBZ?~g(7>a$BrGW*!j5<^FYqTVx3aF*TXtOu)vLAw0v{Hk2-zoO@f z@}c?@6?QGEeAqkqb0^*GPE!wCBiV`nufSZLWH?%_A|T>1>85b zBX@-=b7R*Ut_>QW=W{-;l@ip+xpM%& zi0>HnjG|{$JJ^5)-Pq=ue@n#%Z4;}Lc2jGzrJ{zfeb$Y!QnxBydx3X1k)mUW&*dX6 zm3Hn0hdSz?8S)A#)ks+d)zZL=jWelw{M@<0VGFg+HY;^R+-dKWPaGc|cxGg%G-x5E zHo)rG*(3|eVntdm;EvoOuz)rx+uSB@;nZX;kEGHsonm32VU(LHYB2XG66uuI)U=i- zmtiM~2VWuUaPDJtSImPb4@I7PH5hAWWN01!wrlBDaaRCDQgYS!sJ8 zr0snsZL$gwS7%V&q-~RwKqPH_Z1?2F;;nmd?a$^(-vnE0BE?=xh~9ELKjE%T+=fh2 zaz+M6heij_ct4N4_X|v(Wb%tl{xy?-!$gjyq>bu3y2sWZZL<9&YbBDV6|SpFUzNal zzr=EG23U@?ksH5-{6ix%mbML$r-ky?Gf&!B!{lwP>L%PqGesKxB)LsKOV*q;jZQ@i zEsdq*6>)$M(;3!IUeYaKG%0F&C$>7l2@V&~^;iY2Lr2;wG^|az4Ur|*{2?+an0A5c zmD3Vil-Du%xG!2Sd0dufq@w55`JT0XUbbEl^JrlQ=&e^DG?i0F51U0+h8pK# z1P11@dI1W%E}M}zAnU!(gv2)$EEWNd&if3L#4apf4T9-1PUgKD$Of=UqkuYGOyJ`b z#?Wya*_KpWn5(#K0tB=efCUH^%|A#Yml)@cppwdE?+uivD+{(l@b!Q##PChPG)bUW zY9W4x=9REDGcmDTtAi^m|B}r7FxoV$gVP7YY+YC?XwP?HI*FzV*dnWQ#r&##0gR3R zv`|o1W&f!*DX^qv__JhWjI`MY$iU4Im-#R&FmK-{o&`f{7dQ==7vsgvzAvTC%S3CT%Z^~hG!OBsC5-8KUD5CCNK}#pRi~A?A zaf1-}W^n3`=O|n2$iK$S=70^VigsQ!8>|9vA14CszNh%7GY#xRMA!&+aKJx=g{8&Q z#H9quSh|V0_26&>Wm11*frN{dI(B{J+F_j>QD|>;*vl;7tCodhWDFnSs{l(<{&A~_I!BAN%99@ zj8`To2e>*EgCCTQ`1I+sCyt-Cpcthjb^lb4#}O4CPWz&r+~?q>n*PIf8Keu=fH2Op)Gz?Ry3M?}3ZRzndZUn_wTZP7l62^F3JH*qR&e z>qirr6NRGrM#7$BqFzbkkx+=QVy~`sX_UoulWp=HXRgX*ib=ra8l)#%`#MPsra7|(1GMMRt5z5K0;_7o?_%&pdZAQhcy-F{Rj)m73VF~sp6kx z$t07XV)C;{tV#G_svuM2{Ve#|l(q6ANhyc>kF-C^bXTDz(Z?q{c54Yz#sl-=w<=1S+w+mn9`4`{r{F*ILY@3mS;p$Spnb8j1*LnON*C};D9zM9 z%A@tLN~2BU+ibDf9F zaTvxnmIvHH&eJJ4jm~rRQvn2|h%=8kp9JK65UPsP`_`F=AW+Ucr+MIjVKZ!QlD4PG zWd1Bh%z`s=HV1f#uO*AJ*sr0qvj7$&ueq)QHW#e2eNkkCgcW`W7i0o0+hfM$JdOz# zL2Aspm`Qgs&*e!n1R|0TGlR?Ck=cthWe{6u1Oifa@swN<+>gl|(;n`J#o)VZr*zs2 z6C7GVpzxHQXQqRmht^p06oL(>SbGc=ZH?O=brh4MZ6^*t1#C~%E^+W1IQPrJF?CDk zvSGn#rsyRE#YUB<10r4egg2|?We#m7p6RRXOB2!~2>BThNugIa3=vV*1T zc%+n|^#Iwy(hWRPO3+4taHJGBZsK85f;Iz$!=wQ9@E9pUTL8i_Qh@N18+-uT3J?yE z0))es_yDvWARHY9=uVy%CFm}Ia8MMW9Xt$5P!S+IC2A)@0m4bp;2w8n7vItICQjh) zb^$&pzyZ+c)aV`;-~&(}K%3N}o%jTZCqC^6Db9A{0}u{+Mu$oFy8s`6aLzM2Gx~rF z@ByeFAUi#J&;|GabO<25zXxx)3Ge~vL4daDi4VB|AAlYPXuCj1T!0Tij{tP1K##fr zAAlYM=q`aCcL6>C9R+BIKu@>;AApVlR21k*7vKZXQvls9&~X>w1JDV8b_z7WH~WyH zCtZLK$_7!kOQ2IOzz3kG0opClGcLdfpdo&=G;IxBwr3t^)LkK$9-O2cRi{9u=tW z0(<~!0Q8tZ(=NaVplbjP12_y80FbX1_03-AGGM#qnzfM!X|6q+gn_=dZY!0LcP z#1sKzlzCYxBpN>eWti?2$*z>?mgD4B04}z2W3?deD-)-tB-| zxUWbX3-8F8cjz*CR@C=8rm$9U3HB5s4LZGy`{?xP-pN{h;i1iDaBZfB_ZGo~N!p5U z4RJ>91drlID8!plqnWJ|?daD@IvnIo`jIqb2APg}YSXKZ{YJp(=r2!cM?=FN+Sd4? zvym;gFKr4vy8R=c90mR}yGpYzA4WRJVc~^hHJJslXTW_+OrRT4<%t3~mF|=4=6YQf zrm(E5#KM{d02bDD>QHnIMX;k-pW|&-4+kMSPfP1Y z4zt~_ahR$!uSTIToa?e^@&6L`Ox7`3kHoAW#Q~F2MF_42a~fQj^3x2EEir!d{myXw zHY4M(N06ISxYA0ex*INabXc|xrHNL08W$WZt&cH-k-^G0Mnn#Ha^3?&B( zW-kos6N>Rz;kDh0%E$X$$uef}{~zSMFEe2TGqYnVE%-DG@V&X|Z&3(P5(l2yIrdU< z1f0g$;IL-I=f&RvEQ;`!k0^Y!pvoE|X8gvSWgltf$ntek<)AUqAO@tJ%XyRp zJ)GBoo0cC$1`jt%8mE)lfs06L?~~XkefF zQ_sAG!Cto(>vkMc@s5>d-^4#=CQ7-w#(RhDEo3B|_a!Fu3>7TToOmJ%8N?AnTncf9SPXHVoAT#~ zIT_x8U2Yt$y(loe!S_HtLK_G}5)^O+&I#J&pYrnDk}bpw%?)e)8A z)3B~!3u77CVc%>WU$XPf?CJ^ty>DV}C37d4JB~zikv33M#L^{e!TIVKF*05sumqhF zMF?Z;TS%sjXbwBpAX%OK<_k!1pet3$iPf+R6^(F4FXo~1)GaO$B>Y5j4{Hgu#&I-c zr5R|HOp#SX>9l2!ZlVw%WkCGH3&xj( zV(~M~AsZ%r35#aNpIuIe-exfJn-7aJI<%0Ao7VKb??v$va+YXBcIDtF*cVyksRhTr zB;=;PM}H!&kf8xw$q~!%6C2EmojR7ViOnk;FedM`HxK?~+MC|k9;GNHy}26~i!+an z)8Yn%Gz6tZhZb&+a}sjv-k&3al9=>VSR#gd66Bzy7Z4nb4MEf{Ri9=jdlaABu!BYb zL>2!#_~tR8>ARkg;)r>n^*})G`!83p~?vmP3Yz%bI09aymQxj96n=7Z6bli zcRUT7K(rw#ktlMvnS-MI&OK)9(v5-J!=bjjWkGnWMCyKYuvTeik%M4 zR`^=2b=fvgaO&b|Nb%d z5p}uVbTUsc--Uw3Mf9fnT~t}*pofr`G<*z=-k#hh6KJ&K{|*}F`~mRTo7)=&?%9b)A?ncY-Y^X85=l0IZ}!cj)Gn>2Z_||s^JXw z0FsI35?b~oW`&25lJ_si`B;m3qGD#(`JWRTw&zmm1IUJb8#0Cq5b4FQ9V8b=Gn7i+ z@NJ}7E;flm6IBlW#jOxwx07cxh<61O47Oq7wJ_26X~MDbBl^R&zXw|B%g5gdYKQ)M z5!4cCKXen+A|x?QBb0O_l9KV--x0~L9;S!CxCo{k+yQ*$LK#-zEW}b1&f1d-s( zg4qPB18D(xjpZ|k);G{K<4rqZK~h$DMrpN&z87aom-9k+QX>AjSr zjt^MyRrZl$%v6rvekPw}LRsgvSL1(`gUJUb zR_I^iBAKhuC6NdO0hJ=M<=tUWikmHX(D8a|hk|(APXS1>$s(^BbK5xskV#}#f?#;X zE*eG~W7n=Dtb$#OSVwpt!z#Fb5y3;yJNyI2U|@#gIdAFSv1@;T${niwyI6E+cR5^H zJQhbFVNYViB5>vFuCRj(JBsm4Sg^fs6dZ0Ka4vLwy$q0F$0Rh5ZB;1R^ z)dp@(!y*wEigt$x+lDrXj0t-8;69s5d|v)F6Y`w)kCg{`JW0E`v~5`1xxATrt2Slt zZSpR&z8ZR!Ic~L37qW_jW^)Pt z;JtW8a`OhV$h`nM?BwHnl~!U`-&!n3a9IL-{|YMsW7vpiL+&$C!!4;cIE@Q(2y{~7 zzRbVQ2p;_q+iZh705|4>%;E0n9b}Oqq3MwiN?nGDTHUu-w0MU}e@c?cl%(eKto+AJ zNUkNwkcbIMaUW^Wft%Rm_@mBx>`!n&PMLuiZ7%>20*kcX@t)mWTyn2Z@mIajp z@3&0mZDdsA2CIdXG459nz6O_>ad?xZU(bXGZk8B_#GJAB2=VRO(MYU;e-@3zyuNTa zl97Nii5D_b{MzoF7OQ$alqF8^haParuLt*KE9SL>R=|)fa7WhPZ4L5 z+##GLULw8(2;T$90AFBA1e0KvZz0Y_@#ejmaHqF6VfoZ4dz3If$aX#7CenwVOOd{F z5v1>19O;`8x{xAF+>P2_EnFWwm*NWNoqgsk%x8+gA4KMo>=lq11m;Ybs7+}XF7G}R z^M}k9@dsuAtIlp=D#lcbEt7}^sg3yDf=Lf1R#L;q70Xu7J`ChhDBt(#l(s7D4l zPs(ZS9Fq~Z58_O+CZ-KYv2l=3oJY%O+^LQs_i$uQWB0P4;Y1)mFq`=>G@dEM~ zMn4lE}SrgiT zH29>`2(W~#%CP`^A)f4^@%H>UnPFUFspu*Lk$%(?gPX8AVr9Vm4Ps7I7oQ4`pkR@y za9Q}1xS43Bbt0W�VTWdr8!7bs`B^adnDOKlJ2-X-^gl7^loZ_O!v6#~?T87cqx) ziLm_2m;)~ye~XB*dl_LS#o21O1amN!MJzK6Vt5j{Xk(7_4OMJr6);8nopA`z|JIbQ ziy2GH;1C#2i+6%l$Z&{7<OqAyoWj6noDAr6qbr4_#AT z^nTHguv=XKTDMlmR{65+hNzRU93mS6+7vz#(gOBJFPNIyvvi0S+6^2Xg`zY>3^6UY zGtrw-e`J1Vl2Kx3_|+&~MP?bJH2YYzw25Ksp*g3i14=;=yzR1&FlI78khW zwWkoZ%Zz3L&x_OryKe)R45`OAgjtAA(xq+$ z+}6BUmhMOT3!}_r(0+{U=`jJ0wyA+!5cbE7)gy2d1%=EASp*^-r=A1AKTC z-%Omo@x`9=0hYHRVSGxl!5AkU6%8jF_O1X66Mq^Nz5jq@32CGj5f6^zEUEtsXg{P% zkM$*Aq}~OOsy%nNyeb9(3s_*@g10FL5#-vQm+Y)Kf*Vx{c zNkb*LY$GxWOVG^z0r*h7o{!Gj>8FuA3b-Pbc8K}!c=4>;iv2#s%irMT!_56Ub4QqaFLRGD z_eab<#@rt;_c(K(W9}$(f5;qT3KsJ_#@zb|dy=^yW9}*DeuBB<$SGiP^87jP1i|kj zc!0SJ%$;QJB6EYxy~Nxp=Ej(Nnzg zpJ47q=FTFQGN^KkMf5y!>Eqz_@XwLKQSG&zy`3wg1Kw>o4rm){P2cjK#a z?*Ir?MR)ZNc{@AWflPoCb2-f6MmZ{x^c@Aup(b1Yt62Zw=Z@Jpl{Y1S0N?O#v?~)q|is)W2CYm}+^# zgHwFFdkRxDj;f*r>t8#1;3!}FasJe=0eW#{6%#v7sq$4LKc3?|KIYY|cjTaCfa)EK zAoH2qN2ZOhhyq$ifFP{}T-@O{(gFcB@RG$gckIaP32hLOJdm>v8y1E{w32u8&ZB$y zXuDhU>vA9+j?Ur|z%3j3!qk`)z+f>_IFUkc6Ux-YeF?prze)2Rg*a`?y>az~Zn#JW zg5EmP*{x+CrP_N7`R*Lk{ z^@4#SPTb*bDg2#H`;i&^rgW=?UlzrlxEg-x3tl|mG+_I8>}b<)^265sr+LP&V&|an zOQO|Eh##}G({eg`STAauL3F!*-ji<PjqlnnMklBA%5FQg#XGSO${**94h|kW zcC46r+jn38>Ah-T&mR3*SbXTAhvEtsW+x^t%=Y&$Uh(juBM%>$U-ihu;#Kz_dg$S_ zW`92$zDZ5C`pEpckK6=-{Rav7FX0;L& zDP5{0Nt(p)Mv-wzOi1x~egjH_QDo*W9go6#->K9D$zWYmm_ zNShxQqr^J0Y2{A|&*eO}8@E+5j5ng8u70sD6f^LRLim}!OZv$= zd)t|)MCK7v@Y(UZxs$er`e%f)8!$?UaT%{j#7|FYXFE1n;Y|kdgYb4cSn;N#S>^)D`=i1)XIXx?T<&jW6}i{n#@shBksl8RjvUD!VD2MK zzMshtGx;bJ`G0RPCl~csnEPcWatGyEUf|_#Fp*O!4_L18uM_qX6M2?$Du0!ia=t&# z+^3j)n8`OW`DP}knY@>YeBsYA_lHbgV&C8!;fF_JZ7Oh2oBi)x(Y~THzqxJm%FU}b zuPEd;Vr9MyzcbjuzwPY^czsp>;|)jcZ8vE#zrOHLuCQXm+wN`mO6Nwn>)Vn4$qg&; ZlLIF@?=svr=DQ2sd5XIppf{{eI^vl0LR literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/pickletools.pyc b/PythonHome/Lib/pickletools.pyc new file mode 100644 index 0000000000000000000000000000000000000000..3fea1a3dc8bbee630463442b14a91c3eb39392cc GIT binary patch literal 56630 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 plVGAk%YaXJ+EcN*SF9(Lpevqu;{M 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 CO6ZCJ literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/pipes.pyc b/PythonHome/Lib/pipes.pyc new file mode 100644 index 0000000000000000000000000000000000000000..2800889415ca8949329c0cfb406683776de23f7c GIT binary patch literal 9068 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 hE(iJW+n8dhlhdes{~28BBzOP- literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/pkgutil.pyc b/PythonHome/Lib/pkgutil.pyc new file mode 100644 index 0000000000000000000000000000000000000000..5ccc5ac6b83f9e19fa26d41e10789e2ee1071ed1 GIT binary patch literal 18768 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%0D;+rpSX$x&KzDRnQyc znzYnoaM!odgqR;7Hqc9b=++38gZitPoN5H7?QI*1UYIoXhMu|$7Aiw5F*K2A=2?F$ z>y7M(GDxLUJB9**V)EDO_KVC+m5ZM6;4X5%eQ?3~Wk&rYKR-&bbnq*+spxop=t>9? zh6LqpJpy(o78CqbloEZH(5mF4S4Q51?PZomYcdecl*vX)^bZcAF!aCqRnCRtZ8#=%Z!xdgYr)x2}-z2xfkWQ8YVbkl~k zU%mCt?VI1ce$Ae*Hm~1(_xjSEo41yp!719bsT|0`aeAMXA`n@U{WOk%^y9fv?4tb` z*=1lr3Y+vmT3ExFN1^vxB>?WiUDeKE4e!7ZaCZi~|C@BRDN0r;7MQWrD@usEfr(#H zTCFEfc%6LIFuzH=Gx5eh_1L&3}3 zXjiric{0@|+3k7x6Qlzq(Hh`9V8?z516*A>u_X<+-~M{@+Rfzp)pu_t-}+~7Vw#yc zMRm%2T)Pmx0y{9d)x(g0|CNVNhTci~pY5&HAn0Hb-9+kxb709y+uq@5nb(e6hpKYT zjaPpEOX>||V69a5XvX~WrW)@mH*#&FL*aAr9?cLOffX_QD-xf`D47yX^QRdFvaL&>%O|lw@`_&YJD7K(X_Pc9VhtG*UuU*X_VcK# zInMEn0qAI_c=TQ6nxxuYxgO!pcOnPZPd>%H2ZvSrenYTo`QYqW z=T0Jcm0uxF{$zIaf(E_A%#3T){4E>7IUeuutnfDW_nNdY4O@*4CQL#NW2>Ear@|fR zy-z0}1%hXEvdOa1Y*_wN#Ve*H5~KUN2ATsZc6r9N<7Z+IG+s!IVMVhE>XS#Y6l8yVE54G3`G`sthV+c!9{2jvz z9am2hMNQYHCZ~>0)u)c|-^9%EnNw4BKcN>szunoYl5wVi>gG`&apGv<=Xua>Galg5ekCdMJH@8 znbgxxoeDYw&AxF|?-cqotHtnT82%$Yw(EdmaTA?#Z&G!NCjow>_uQ)^tyjvwVGxhQ ze`KkK;k+;%PX7O>px^|WVjCYS5bW5PcudyxR8)e>iNuluGh%y1{Y$zjSEt=qKjImH zBjGHSCcg5L7Ln$?(>MZt%i=5voF&W)5v1AlbR2b3V$3pZeVx0;92fI{hC~~jqN&Ma zbC@x0w$j$RTSFb>alC3)^g*^)B=2cHORCqoBdqr*U*1SDNb^CV1JUFc)k~_)+)?o(*>L9x3Wd4X9qgc!;La>C>==()r7>)tq{FI3nOY zyq7&9@7*GY%9*l~-Km#8tW%*-o?CIot>frS({tEetwvRZ9WqeW#EEu)hm&l9yOI{v z(s?IaYZI>Sa6rDN@fFOA@w=)*D667uW|c7jcfnz%_S75nZMf#Fmh|0Gm!Ok>hL80w z29!fyDj^nj3=weyByJ%eI;`#tE-B7Yg+{B(Svjk0roA1`!~u;m09!843iY9Tb>h$z zDp*UnQUyrL*@kspGF6cL3|u&nZ=?A78DyJh`gXSG`8`Rib+Q>fGcCJg{&0~E+SzKl z(;XzzFlOpZW%#sE-VUHfO`7Du!e}RVFm8FOJ6pFhGnJmrkcXaC5-vJhQ`%1FyJb12 ztcg@Xi(m1#Tx2n-bAc2HIH`Yf~PmeZ+?Cr1)beUewI&lgKi7Rz{^f zLR+N(#19o>B~w$_6B(h>fm)3*E{5$p)M3De)r4i4ig8srQbirrY!oFiK7Z6HRKb(& z4aZk<;h>3Oho@2tHd)2P$SUIb;|~LeGD_`}s*5;3w0a(^aIu-R0c{nTv2tn`KekuG zt}QaED!7qwdTDh#M$4oW-L}0vCtF=52X6A%d)R;A#Vd5LihW8EM#P5{*vwiaCOX9? zHD1}`+M;1|nF^x*BWV<`#Jm(&$8~_}n;)?0G_Uj{!d@w&ssKq2r?dz~P88Fqlm=DY z?YFq;_q?n{=ZaDw6b_Hh2UUGT>8Ta+lt-ZL_{|&dUQdQvW0CT&d{cv*5&#ADhI8*9 z`quRux036_v7B+{Xv3aW_EaRaEzyR(09ko|lY+Ap43yPBn|Na_DGEpYo_tT zj+d>qJK&zv)E3H9YH&S$*dYQp?qr*)1hZA(%(No2=})WRH}X4`nSQJqj-u*#1r8m; zZoIpLEwUlj;%sxLYXot&x5_cii12J;F|Zm1 z)T*kd^u|tqJ6_7=TsT_hnMs%#%2$RCfQky>)qb~IVplazmE}l{eceyH7t5Y(FHd$%ewnTU1Y41ujuk6U4B{@GeL?ThRVYahvaX$Es`OyWS{w!)Khwg zD{B6EE(bS5@|b@|X6Sit!Z{^XW@^t{EOwzbZ)X60F4WTMGCulULIcNtzhT0s`d0aXet&nkUUX1X4^w-Rt|Z6snuX!NZpH%*|6ogg?hD z^402E`x8zVn55-NryMtt@G$-OVcM}_ik+y!GE=ff!=U{? z(#aV`b)i;}2h-f~vm6x`!8DeDf@%JhWvujy+|K@2VkvX}{q0#4`dQq4qKv9xf(AQj zd=cZYdn-bx6O3HDe=Q=ZB?!2ZRvnIRJ$gb*pq?6jdm!K%%Q|$u>d}ONd#ZGn|5X2~e1q^qDs@jP$#mqbj#B zQ$9YKCcAN&+`_C?@pPi-$$uxOQr!re$W?uylV_4I`pi09^bw?!k5YJQCS0 z6*ZzI0jwM=RhCfqDGe=+kM^~iI%Cn1qov~;^Tx+!8B3~_rR)+^^MA|F5=(iFwM)x1Cl1vSlPS?KOb2}NgVn{;i$<&w zAAhDkMP)G21NhH_4(U9`dTl1)R)mq+F8YjAibLV(tBatO&odMltq@xEdNPEMEdTQ= zArv1>@G&E74`CISaAvV7#Q6)Q z8v!1TNMI188STljG0M)cTmXb@i-y2pL+s#8ps=~b;q+{K zM*%Ew`XXbAI_qz1Xk}rgvD53AQUMKLxxAtTpnpxJtrH4YA66MHU@03sCM8Cw^79;4 ze6O4h#`QRH2%AA_;kHe|%zgWQh-zfS+EO6me2EP5n38a{(A)yZq2B;z@>DsV)I-rZst=;J z;|+e(1=cuBTRr~Een9)%G!Qa*g`yoMc(6B&A2LH}KT zkb>;+`MLT;?YY`>WLuB(#ms#4G6x-}>!+g^qj|0;EZ-_m>4cR@p5d)}wnQ`GW*Geb zIS)hky7Z+!X9`M@yTjIt5 zs&v2tT0s`<;ukMgj=CvxL@LcwzMiP|VxK-#3Te+Fzqq(~(Pjfh9(R+cQbtl4H@+lv zMVa^c-jiqTwXxr1l9K-7#qpz(p$76Kf%NPO9~N?A<05UjH9o*(L2XWflnRB*Oqsz_ z2FR>fVW%YK4FD>Ak;21e`czmN8op`;GLopjGLf*tCwZf6f-PeTvjhXCSX+;=2OX?B z@W=zRPEvwxJiba#f&x2?*TC!11q0;LHD6Td~ zR^ej40uq(-sJ@acjdSIBjdCfL^<~?j!uXbnM5cjkgOI(SsSObSV0HL~O7)MaRQ#^A z2BhfuH^v}jnBK9`R-j-iuG*ey_%C+QB4h`38f{^|*Wg^&qcpkaAdu3)I$r6Zq@gQw zJD3~U1Jkc1W|KeE;ALH;N&R0}FrDiE_KQJMp)OHenfwYDSK>Onwvw)@gL&i!4?MNb z0{YU^6=!Dn5^N&+ysn4l_{`!&G@7dMoR)r7mz%oSo{w>7n<;5+P}yg#mVU8U%_g28 z|44u=UGkbPRxV;`QK`1%O)Td^r8YkYEJ3n)1rhf9q$)-;H=4&%AoWkNv R)Tb`YT$(yRH9z%@{|ofF0B`^R literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/platform.pyc b/PythonHome/Lib/platform.pyc new file mode 100644 index 0000000000000000000000000000000000000000..c237dbae2b5e1d92690ba7b1ba269c6eb802bbdc GIT binary patch literal 36867 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 F{~L_cVdMY+ literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/plistlib.pyc b/PythonHome/Lib/plistlib.pyc new file mode 100644 index 0000000000000000000000000000000000000000..a5bed6ef825bc5508ccefe16c6ce1f9be1b41acf GIT binary patch literal 18384 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 ebVcv_XrNugmn^{xFiwKlJ$Q(%hZwp literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/posixfile.pyc b/PythonHome/Lib/posixfile.pyc new file mode 100644 index 0000000000000000000000000000000000000000..338c6f17c0243103eb2551216d15a7cddd93c987 GIT binary patch literal 7472 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 Q5Capn7ykrr8e`P_56Q?{0ssI2 literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/posixpath.pyc b/PythonHome/Lib/posixpath.pyc new file mode 100644 index 0000000000000000000000000000000000000000..91dd759c7b85ad2c7dd5d2174289d7d7c5160934 GIT binary patch literal 11495 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 Bsm=fZ literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/pprint.pyc b/PythonHome/Lib/pprint.pyc new file mode 100644 index 0000000000000000000000000000000000000000..ca4e051f2df5f8ebf0f3a035d47fc334e000b24d GIT binary patch literal 9909 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 Sl=*LB?(d6ti(}=fvh#l&%XY2+ literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/profile.pyc b/PythonHome/Lib/profile.pyc new file mode 100644 index 0000000000000000000000000000000000000000..451009b310b64aa071b48d4db37645d9584d7a74 GIT binary patch literal 15873 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 literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/pstats.pyc b/PythonHome/Lib/pstats.pyc new file mode 100644 index 0000000000000000000000000000000000000000..93f23e577798bb3ac7bb340fb6fb678942f3ee45 GIT binary patch literal 24113 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 F{s*`%O27aB literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/pyclbr.pyc b/PythonHome/Lib/pyclbr.pyc new file mode 100644 index 0000000000000000000000000000000000000000..752714b27b0256a7412a13f60dbf7355f26f71e3 GIT binary patch literal 9456 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 literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/pydoc.pyc b/PythonHome/Lib/pydoc.pyc new file mode 100644 index 0000000000000000000000000000000000000000..ab75de1a744cd522e468f0759af309bad49e293d GIT binary patch literal 88903 zcmdqKd3+sLcHemm06_xW_eGTWNO1ur5!6bl)f8J2K`ku_WEZHW#3ltjq8`Xc0uR8e z2NCEdy)@O9yd;j-_7>aYIAeDlJKo|>yiF!!f6|lgaqJ%3`Am{_+RNCTcs`lWq@C4v zJm25%)>}Y=kksiv<})N-)vc;qcRBamv)yxUb$@wv|1baQkBy9l;@>jPPx8wj>j@zX z;Vj1_oJ~U370z~rtUH|T4p~n)+Y_>7A?pnj%feX_G2I)^_BPYY!`bD{^onqHMKj$O z&h|Ca{o!nXGrcmLUD-^p3TIa})2qYT)lM%D6Klfc+HiJlNL1g7FtIL7t`BF|hsh1$ z?1nJ8F`V5PCO3t%o5JMgaCUQ;+!D@i36opH*{xx6TR6KdzS$Qhwui|b;p~o(%x`kx z{bAycFu60F-5HWIwF9B2a%Z^GAL_dk{$(pe<*qOe5LSgZL%0#btK_RC;gxK)Zk*i} zvNcYWLble4-631&#Ga6?cjE4lZE#|5$Tm8$FH}~9%lkvN$%zBu1~487*=9dI7_u!+ z+!L~`PTU)^ZBE=5Du?u!Z4Ynq%3#QL`2OKA-ybUXhqDiaGqv~8hX>t<|KvX05h@S4 z4?C6DeRv>bcZRbM>zLgY-ejB~3AKInDvsunaP~;390`{nRd({J%3VditmG;m3)yZb z-WRexPCOo};LP35_WqFV4V9y=c3-R7CqlO0S&xP6fO8MHA0G(W!7$Ft_q4J;8M1pr zWvvUiuXXpSkkS7qeRr^R_vw%wZsxteb@zD49%$x$uyuDRWDn`0d?I8ID{=OjkUiqW zvmra;#B(8g)QRUq_LvhN4B7jfcp+quJMp4=kiFlXeJNCi45;BydD@ASA*1hf=m}*u z$WMjJheG9)E^Ywt)bAhj`y(L(0u=Y8p>eu-`IIkT_M@kr^TQ!K?!g%Hqcb5p;cA{~ zRr5-yyy7Oj8nS2o?77ynvmtxlw?5dq^^uUhpo_ETnwa&XOFkd6mwf-VkPSOA8nTm4 zydEm$kev!wxwMxC*sFY64H!e-pO4-!d>|~|Z zC^xEHRcoc^PQUbGX{ugoROT9`aT3*9gEz(+)i)}o*}O8?-~W8A)VS0t!Oy4b6>{B2 zaiu-u^{L6y^gJb(s*}@G^+xGZWny|ysWDZWu1~#D%_^m-+C;Th>DT?iQt5bkg3F7} zHqf|4@*p`%`1x}R4rY0xLwXCEnN>j6q+%=9D zr9Ix?pU&1wdtw8R*2iBF85KYzYD@{&ivlEs3O4H@BE9HwMfMJ<}8;wdL9EttUY#yCE|v1iMU87It4vfUs|-$Q zpfY%Iu#{8fC4u+lT6ONe{tL9Sb?Z#EmQ7vF50c{?yz+iQlR+%M zQLavuFHBU5?&mkvFkLz-)GCT^l)_oTS)YnCqT0Br+gA%DG{#=7Gp@pL!_gCWVIMSo zo0!z^k<(ZiYqQdxh|YtT8j}-ysOBZ(t!6-8w4>eveyL0vR0Y*CVeW+rqu1YG;@_o4 zWBT#KhxOXvv}wxVRQ=-NiRy)VxjuimzyI_l#&(Rs;iV}Cre4i5#^l001J!6~-U|y( zy?Xk&lfy$NkB^ipwKuBushY9(jdHyzEQqbos^gwMjnd0$BvQi0IHFm#4w0Cu&o^g6 zv*Z_JOZwB+)O)F1n*|4o(am>28(%0NI;9t0tyDlPQcq5dUsXqr|RGAxt zJZVls1~1mjlas1(qFlQ;3!V-3pN4MDm!6)j*MJLjLtvSzS1(p;GO-|K-{M1 z2m4QzXD3Rh>Xm$KDl6(>-U!&tyDLKfNM%iA`_t;!rE)zh9lunbyilo6Kq}%(s%5-d z&zbR)(-W08FQ6vz00wrjzxr4F8y-mLUZaOYTA8j7tk6|IhsxYEnB6E}$o+5}Tz2B} z6ud$5>%`R6O5Le^S_rRud81yPcB<|ddbvj{xEZU71vkWbMjIF6J-wGzW@am?o{sVJ zKQ-%Ve))P16__S+VK7hZ3h9Vn9aA3ty7(REm#^kGZ zk+P4DrfN*PWTzG>-o5?+SzT^#VgRUND*w3des_JI zrHjkm;aXRiMoM+h+xL5PA6Q%`1Aj@lvOLtcG~ZfQJmro6*IQgB85mY(QXh5!}x`Hp=e{ zRiNCet+?49n?;7jZ>w6peS()v9YR-c(wnSHwj~>qyOPz(ro=d?#;QRcu9GC<_y8}U zH+_dMy98eiL!#aS-k2s)e?g7Dj5Yv@Gn|0kPj7UG>0#X&F|Or@DEQe*`q~p<1&OjU}O)?&4*Ots1q^byu>g4MDZm5c~!bG#UJeAQMJ+ z8E^p6paCe7h#%2q)*ZHIJz*R;(bVGkvT$V?l&1hS*|!7kRop0E0N_e33%g?BdYeLu z+pbTy2Gq>_7>5zjxROM^7T^nfUm)s~2C86wZT=t!m?~r#s5Az1p?ZH+N7JJ8PNjr4 z1Hzls2i0XL!%ht4R3ML_R!ZZfj25Yu1hbLXRGD|q@JhalL+IKJ+OA3NPVPv?RJRJ% z`8dD)ehz>e(h2EM0_a04xo5D*(CriGTpVj>t7;<%d zUV^72U@{a^uX6yXT4k(~=kVXbR1Dc&O+|szwYpUM(!Csvj=Zb)JinD#8UlU1=H@8t z>s;i*+tAgQtZmL(jYg~cuX3?q)}C1~Yp3HS6F1K3cnK19UP4PdFPX=_Tot*M(dhW4 z%Gi~Xaio}~lF3CaOO5$yMAu7bJxCH4kdNj|la(^Ef3HLoK;A_^Bz#*s@Zp5qW=m~TZ2g6Ax6F~!Xd4e6zUDh!3_(v*v&a$RZ; z-_@SO!p~>*?EM_(9u^AKkF+PV=3K&D^gQ*fWL|?yp2fQ$jWgW^n-MX{4|5n2PeJ;x zRt%?$6ToJIS%v66X2FKrQmrC29Q5>x6V2002hStVu{fDjwxl4>rs*;Se(7$DW;QD% z*}|j}lgSfF1?qQPPcLu)lj7KG3iX8gYa(X!TpjHS+aOsxMA0Djowu1%+jQGl#zhH= zw3Tw&rFDmGyS9#SYs7RTSA{201mUP~Vxv*P6+F8tS(NN2%U6)?(fs*EJ+wSmot&L4 zL1`{FE)_uQrZCf_T&cmq!8jlHt3SFkS)Mb8O&``B4L)}y`s$%<1p>h|OnYf)D%ThY zNv}dKkuP*@NVf9-t|Z^imGu7m=RR`(q4$*!ji3M6k^3Gva(&>~y$AP>X~OEK`i}Fn z6i+dbD#4b?)}l!w*=c1G)x<>jQf023RmQ55piVU_*_hGNcneDeBMhykJ2n#xS{ys~ zK*Sia$I*IaRKT6CX6fBr$4MhtEZtvWPw^h8UWkv~t8(PnU_v3-Aqy3(P};_+sJ4v=i{yB#tE*;-9q!XRUym* zdGwxkyWzkL!qE9G;hgasT#jfDIv<_c9?s0|)j%Pv4xQf~uA2*AhVMc;d(>(El9?yS zc0h9l3G@aOKslKz%k?JZPyx?e;6QoQn-aoGg*;tl&4Q|Y3evSdI1SC zM_?BY&rUYiVNs2pwO{9%sncA44pq*z%fElLJ|EN_w9_KSGO7ORG>A^#dSu`k-s0nybexLIy|G-D) ztV_>{GQsS|+m#N?9X#L8Sh^)+ZA!edXrVG6bg6M-ZlzCg#N0)Xd@HkuY#zx>K&BXF znOkzO%sodfQ;n(z-^v?S8^Q{y1gjBb*LAH=#xz=*BP;kFR~}6wRx1jk-W{&=O8d(C zg2*_-lJyJe>yLR_K**YxtcEmmta6UCQrQ@}Y_(=U9s9C!@Wz^Or7zT{Jv(4GScZ#| z{obk(GK>sJzRDlsFa#OISbOyn$csS@m2GhwX&GxrG}8<=Bt0@~W~&nj6`DArX``bE zm!#Fx(NWo;S{KrrP=G~JEY20vE}xic=xtNe(ZcFEI%<~fksz&+@Ng8Bj8`iYSw8G( zZ7H_19eGDP%$1w%C@x|<%w*bndGSng;pk{CafwrGS$>X4aKh#mftIQT?S0cU8pZ;u0NBgmkl713RLJi_(=+w*G!xKz z;h+Uc1ou%VM%B6ez9_)=?sDHzm$`!9nk(9td4skqJv9 zGB%N?FK}LZ!mBIp?$42kG9T*G+N7^A{ivkL@^s`io48mEY_X|(d747Bm##6@MEDtg z*4t54mc_Y+(L_S}7*G69BmFc#x2a;w7zQytinX;BDBo)x7O`@q5TNjn`4z?|v#@eL zR;`--2%l7&FvN{wG@Eh=w~G26CRNM|+KEYGNw}uF$^Ps73Oib>BEi!Y$<85sSa0EMB$ zw7_X~LWNq?O(#gbbDus-uBZ}$BwONy6!2R8I>^O>e(fsy)$Wn(51ySxpVCQHElfLH29gP;jaV`W%uQjGe^ zF!#7@CKfrMCh>81GvT(QvM@|r86I)9?UL+9B=^yLKwTJA#D|`pMfGp7Aw&&$1_B04 z0W7gd=PUR_2?JbQ0~m~Y$@IKY5zFjYGci>#p=zz#7#)q)GJ%~u%`EM_wu7Y`d7MgU zPDN9V1=U zq)3xN{vSvP(LsPHS0mq9vnfS$SAL%+1h;_fs``lqdASRvJTE(D@d`HlF2ld3WuXbZB!Zbw#QSW>x6Ud(=&eYun28zi1WnN(9x!i?+W{jF4l^Y>;Ek@-XtsHSD2Z zurh|B8GESY&@Y7fl60cWxCc?cizFYovg-y+dpSj|Xcw?NTwWQb{})k!%ZQe=wl{1S zLth;(uTcR{)L2$nt8&y32tjYSyiOStDI7M@(o>p!RH!EwuSt>*a*+K{)>6c$LmHkE zYiyHRnA1Y2?HYyYP=gp(4ldYMQOx{CWpcWZ9;0oQGQ)6W48sHB44&~GewaYRujP%= z$wn2GPbh+tmkM7ZKbNc~-OK&R zrm2l7pe+nDZuipYt@@gH{bi+%*VtmV@qca74Mwl-T9#}{pdS2|CEK}P1(t72%xVpR zp;@g#Ja3PXF$(cNalNPc4n%EX~M2*sK;ZRWiF-wouSXjhVWvMizm_=Y^QFzn?@}0UZQ8WE6 z4oi+l3Rws%0bS%17Bu@1Hpc`_$s%fnJM;<4G zR$Fp1MD+TSy^b=8>}sQ<8`OD$FVOAHkkKgktWmjEB~L3QFs0wepZ#G=iHD=+}4kTw2Dh+97Gx0VU3YJE=k zTFWQ@auYo!^JUXkisLm=%6Mm`(2YBy^Ss|{9@$al{5}`A%E;)}KuI-@*lfB(lQQE% znIzC&N^h(Qm)ELJn*4DXJ1&!Ic5KEqsJ{teew3cZsak3oKReugij~A^CLAVGO}pr5 zQ)OXM(pew*)njZ>Z$xWcgxsEd7LT2}{L^Q&AJs#Z#}29zXfgspnrjG2|Dx z9y$4Pdi+HC&17i{Vy1mEnwj=#h)g^Yw9>bgQG;nBntnH_Xy>yyCK4K304T8f>R@EN zSE)H2zKw&i#D_&t#l$+&7WI6akVXn-fa0xXy=)Z=NByXOkuvUsI&SCM5{M~|uw6)I zjQURAp8o;iN&QFx3)9poQ}3`JTa4nGc(^RK~MM_u~72CPZ)Jf6+oIEk;diW z`igM9FI?|m*y2AHLn%rOVLLc=4GWdgZ03UrxW%xE=qyjjcg^^HbB2Crcpw2AuJsA; zC4OXa)m9VffkfVndOZST*+NX7J1z->XHn}z`q(veelT2L8Rj<%^Ch;dRFfq7%)FNL zAc9Er`DXj$Qt~U@JVUM#leGL-7@gKEh`jjyrAwGML3kXQrt10o(L-#&lr={dNl7M! z{87zo2joIITgwWA=kp7m-&4)+iH}Pc9e>6Ce)f(KI#p4@U;EKRwkEU+BFJcLse;?MzH%%Ufw z%c3z4U`NuLxSn=4$15^fHNR3Cn5|7nGc=IOrEDH@P#psljY>^^SqI}skw{tY`z9VYHgPEImrVy9k(oR_r>82R4NKFPNN!%%)0G@X=2;h-^9V&Y zubUBz;!TmlC_joErO$EzH$!*|<5?9%^ zQ?B$om3l!3i4p1F;NWap^;?pxr9Vp6dqvC!NrV;M%Qh!#mmf|xVXEGQfY;r%Jz3ke z6Y{n>+27sMy*=51sJAg$4coM^GX&1+P5l#Fw^%142bGmamgS^3aj_=BAMzdPo>1ut zJ;W>Y5U0>Xd_oU#2|dIkC=4M=ek&#UiC44?<^r3bmVbc*q!VJs0tLixD-5pCqf~MMR(A%`B(gElX=%K`Z2Ole5_ZY9`V&1eg=JOKU>j!_CtQw z*L-%SwjK=&x(1o~Inh#aT#+~AF*GA++Hd*=$W|;&je=6e3!7{5ed_PxUaI!+Ym2c`mnXx=au2j^+Y) z3I~GpQ(W5ilo*Rh4XKGtPdBhe_{yy6TkZ7^v2=S3wqW_v9 zC{E0bBX$j_u&3at_uL}3kowW-0;SL?VygDL6cbM5F zsu$Z$rud9#Ael2I=F{*y3Mp-5U?%{}@8OU}VL@C{Udxfy*MlVud)Vf9s2?iCjNB_|nB4~}L>5#m zS~ukKX7^d~S})QS-O7c>`|`sD`XBbSoz-mv^rd@XNVR*A{u=Mu1V}SnAjTne!Ed+= z#_8AvXT+N{{fyoc)oZmsDnh!oRFeyfk!h|#3B|<;Rf<9S%UniNk^otFwWl|9SJXMW z8rjsN300Y^jE%DD%sP^1Dh{)fVWKg=HPY$0=hPxiOn-`O=hdA5uu-7!Ul9Tv7ZuMWV8#RS7!&CK+tWRDyZC%y*WD3IUS@N%s1(&zJp@MKqdN zS)qaUVHBa4OerV4G7EGA5DT!ziiF^QeEL;-|K3ucxanXE$ z8%M)anFsPl!tYBU=PL4Swbu-$J!p%K7rh9dY>rm|i`L0RCCN}fmFN!dBtcdPC_RP! zN;WhH0Pr_tj}W+r%>ws(3hysZPQTyRM{W1tKhcPn$KvJ1#{1(cml%6oitz+_SeN{6 zKM6$1SfwscSN^8jt!9RHi(5mqj@z_YEYIzR;x|`1^-6^FFOlk~e6KF~-L~>nFZ^&v zwW>~|DKcn4y-9*c>G{4GIJGax{+_CTn%M}HeN zxCPO#RYe{`bC*K`|=MAoICfCbLYwz#%uM)8|Mz} zIe(2C_&uH<93(a8<1Budg9qt~`c5{`#0LQ=N_RY8{=$IIe7A`KM#{B48X}Z#a%hC`~orXZO(oYKpE4Ulz z`9Xeh`gp3`WW#pDeufrPEz zy?x#MU*5N}x2vz$96_vXs6)3GJ${;Bev%g}9n7@?-g9Y{9>Bv>(e1%}@zl7Q!}bH7 zJ8z=-!&&20xHUp&jV-o;k_BR)oMSeB}AU_J>CYQf;!Bg_+ zMYaW?ciWoV0&Fkx=n?w^urb4q<{fqkpo&;sJhD*$8Fo4Ydj-&*J0)A}6krcs z)*f-Yv%+mZs#_yG;~JJ`Ob@@~dU-1ch#C-&q+Nt~zD5KC_fDvE?0%zugp z{YQ5XojiW})l(-3?3^UN@a3mpeExW8&!NMI&pdSe@Zq7;Ls7PQc<}zx={hk7RVgv$ ziNl9a4DUJCe^hTBJ9-Ii;MmbdmC)8>QR2}$(b2>4PXAHpdATI-8>|yg?3rzhA9_qL zACB)`n97K-zStyQTp<2@YVz3r8WD2uKYF1~_D&8#_R=^} z5-M-vjYYUiq@s5Vj?1Pca`Waw_Gplr>R4+9aR>k9YTfu^28QVr(2SMhT zjltH}V$0(QYB-{a<4dGG*yBPMr;Iq(QZWSA%kMDgqGkmMKd*6@1Q+_M8t9H{$NIRI zIMG6Yk8;7122@H*8oPxI3_WWqo3>^$L@w7-N@igoVu+SfSu|mBp?*e-8xTEV4@N{U zhTz7yWh>9Io#-L=;=>hQgVht=Cb#kx-Vi0)(88`9&nIRgxa9Du7M=-_k2V^|I(lO< z8VGaqvwAu$-1+ZD#G(PWMMTC2tgb!r&_X=vK(BX?l8azW#1skNw@w5hYMqS@RQ-d; zOo%e|Ig^02@UF2>B?!BlS&c)@n+xYyQCMeYk#85iU|KiJT7cd$q&lkdLa#Pbr+=!; z|4WB|!@-#C^30R56HLq!Z>e`MZ#YD}TDHmOB7Ua(xV<#36WSL8_64E6_nK8RCy6(%9%8!BPSzY(G8mn|1lU|sm#9H8VfSTX!v*7POidrN8KpfgP5PM~Gu|vp zJ6rr&t=R)HsYe3PW^K_ru%D_uxsj!?%WEv61f!9$iAFM zBGsiQ#Y##rC?X{On{dK&A1mHAY<(M0mNz)K$a7!wSwGJawXK-@O-1TfP4j*C>;E2i zHfox@)oBTNSeL%1!|mj-i}lKUKQ-sd8=aJs#Wb;rS9uS=u*hg zmbL+-HCZQlNWU&q6GwX=>C)DPE=(Dk#mv2ElE7Bf#BYJZU^VtcuBLd? zTRR(Z`4kBnd=5uGuRbyE za$UrYcVCl7M-vGHTxXBBI6;a<&E8P+T03LDCDQWxM?}tjjTj5YP$<(1G$Oq`PALzK zL$_}S6#0lX9Za;qiHG|HJ7?L6g=1Ek8}yLu%LnfeDl^F3eTc2aH@aBX!U4BhM~4 zv<$~8j`iWnq+rPaD$bhVaIl~8uVecm5=H#`kJ;#_X5*?c?39E^0 z8EnmmfRoQpUO*a<`@qE1lo{Ee)gT4Sp1>Qtm06reW*WTYVPyCg#2xkQ*QD18b-KiK z^>qyK&xdHtxeEgWT8_Oo-k3hfCST`9?)}KQtB22DOP@LZkwc~P9~d~7-FxubsS~F< zt_HMC(z(HdJiL1E!Go4c_CzUnW_GIa{@YDio4ty~->X-z4%WxV4zX}aXu9^{I?Sbh z`?A5tT(snLShEka~08pbtEOW&eJ z*1OpBMn13U8@i$SoO@$Ci(=9vQ(NEk;38fz)44@<%V&t8X#!F5s_%fvK@<}t4%y~z zSwY(X#z1nju1cOh&vREDx6Fxx1fDZ7G7U#Obd9*l7UsgSOD@F`sIC>Cz4UdJ;I(i?YuHOJt)d|l*>SHm<-5kd$drDFBiuhgq%vO z+`(~OQfeN%w%4{I3U2A^PO& zf}Ttn#c5GpkW@@G8UJ6QiEIlh&y^62Vv{+F;QNN)QCELd&B<8#PABmCf~7 zX3)+}gRJU1hcXP{5h=^1eWi|Ojlx8CJHubPf?=@Gfj=n8aL_&-7-0(|ASL+D(F}8n z#9*C^I}^nn&JmexwEHBbq+OKdnGyr&H1dUlqc-ZYtpcgpmivstcrhZRNA*YLaZ#Ul z)8c+d7w~n6^C#xa(-+CLBr>NvY0axb;}Tf|40|;wtKgL__I6mE-0A(hbZ=Wk)xG3f z!B28({wp9Y7>dXU8=q%fNrSn|7Pvtjwi^_V)60V0pcrx%LSO{OTF?T-o%^7KbqVMW ziju|+vJ9PnP(lEB3D1TTBd`da!8%Z`6pM&Awl~@8%sHaz{0a|1&RtuJnxfIM560Xd z=07Z!EB`&n=+?6oHE1GR<4H}%jm`j_KgGW)mfbhi%kt`_Tvq{VwGZvNG*^4*$({8yENd7cI zT4KdWKxBn!yrjgiTjMyl8R0S8WZwl8phq-TFnCT8>8am%F&D#>L zV=-m{&8^6PtV_l04A<a>;pSiaOX)6n0Uxt|TZHFW;(w5y-{e&xA*7kB?gxK3xcS()Uxi$2go zVtYZWQnC@ktnJ;&pX~Gkiyq#h0?=FPr-4UMO)$ULmo;WfB&%Fga^LW_= zZvog}>%JMVul8KK<5s}ZVE}uLw}GpQMLF{@)j!-5?{3#g(Ef1G%&R>!zt+v4+J61c zF!x+XqxZ)aKiqEd%`JGN=h~gOv|#3q9{#j9^x*PfP|ZvQQ1Y&D?XEEO zuX@XY}xprjA$d2bEdPI;=Xbg9j)ZT;8uu(KU^Dx<_qQb81h7 zYa2uTmzOCAZ$cv=OzeeD=WcqLT5o=t3BM`SM|vCVyzbr7xzuZSyTS(za{_7Z7P;j< z7|W5M8X7fsBu<3E_9)OQO(z<{c4nSOyih>aGC(r(7j(AO8;YetdrfHQ5G^kHM6>P) z^?;iKR4$G*l zhA~F{pkDVv$daoeaZSV`KKn&K^x*J9vy+@oA8%XQY+UK^AeQNObhL0QC4@!S7M=Dw zXL~baUl#e~eJ)Xl9eju(X7?LOU8RA2`N2Xi^wOBtliS@Nh+d=zF^#?y9h-3=NvyDhVQt_!4T&+b$i=wN)`%tc4XnE7?aEPOl z9$C=TCCi%Whq;84@~XV{PQ@)2O6*5#e}Gthx%|i@V`F28fVOpaa~{zf>p6&=akMs~ zeL)Muw?{oLPIV(b+O7vhXXBX4{HXV`N?+n?Nx{=_Jvza5%vt%^uS)>sji~EIu;pWt zx%E@i+$0S}(U=7-;dbE%A-94ht4-DHf4ZQ$DH}RkX z*z7N*gsdJ9%Ix>cdd(JS4Mn;aK*b#*Yy{Y^%imI=Qh&Yac%J?{WqewPLpls{FzC>_ zBC$v>=>BmXY~cPTrC@Y1?kmR82yv=;5p(8NvcE_H`}85@-J!a7DfJ&XSY^lb$iAHu z?u8Z{i&(YXC?5?H>^hMCrC!2kJEVW6)FmBua_RRvb;H!|+J}_$FoyvtInhMn)V*BV zWI(rEKW-mW3|=%ZXgCyMmYX=qB$}sxp*J)gby;a|$g1Vv=m0N6L;8>!BfJ**QdY;T zrN6rJ$pK6p{hW12 zTYhXHo=!P*wHC9;7V@oS-K`fxiJq@R2POVIS>Lspm7hKM-rvDH8_Bs5Gm6&ec01<% zUP{r^y?(le@TNO>Zx>fPx^|OuO_yriL+SnG@1q`-yFn>x*g&3*MD_F~+I|Fs^@8-B z+?R*{U4E}PciEJ!1s;u;CT4zDPY7@0WQm-D;Db#Y*#(FF1G~aEU=cz6Rwyw_VF=$C9hn^?M7dC0{!mV(7F+SmaJyxf)L##8x1!eH zww6o2WDfarCF0B7(oc1JS$G@8*;=YviOHxiJI!dlhqrpd zTg%kOw^-~z(_XG-q5$hDkK+9vX}`L^X32N^oCnRfUuCM({kj7&EV_rVxlSzV8`-7t zy0llVsh>j*UoY+OIyxj`3);CXOsk^e*z-1ar}g0|x}l=4=&J2U^o_hR;Bd90uYN>2 zxC{>SXvdp_UfUFoo|!pCP56`@7} zsNSn%G&VOR(X9(_;hsd7)~HKVf6kpj<9nM7>!sLBYa8rB;h~c=pG#_kdPH+||9F=+ zJKP#-=yB_cfr?Lyfs$s6aH5U)b4@oes+_6qMkkAX`Qa}5QslAM zrcgq?$8dq>O;KCa2Yof&0VC46A6I;xl3oU4zL6Nyk!)(daat_J@YCK}?rS7a$T*|70PFX=pTn?SzBjiUnX1?8u`~u0$U++GHLXE!DpmKn31sL6q zTA0mD820AbTHvQHw}rQp@HUUS!woi}Krh@8rv9oM#f8Kcu9XRJQ6_rEetW7N(6bwg zq(3M+A;$QQ;&rrS7SgptqMzgY7av7fBi4*>>Woo{|3Pmp6WL@}X}TZ-ayE`(A`2xG zp(LTk_|z)*7%X9-D5Vt_av@D2P{1OZ@)Wm=?>{UjRjX8p)hu?sUZqEVuEQd(3*K?$ z&%_N>XNViJsAgSmw3qf~VXPoNHY^99O_lBb)a z(#`FsXY)&L+#>BV)8w;77b^czjqBwd1#zuTV${VNE~9jUT|J~PsRm_<)x6leT%_Ri zgFO7Q%7hQ#K;G9CcZJ^1)zJ(`U@XKhdF$H}>lgaQgIpBt!}>VZ;s(}Y^+NXJmibt% z;~942F+pJkzkYrO-#;cn8{6ShquYd6cAO}A6_XQLVDqRJ$l%h zB_i#tu#!WO^cK1J#ZgZOLk0*p4Du ze$gY$Vi21b5A%$U@lA{?aXp6#5=Ea&tSPoOv=m%ZNmNl>(hHa3H(K}#2GZ3NdbC%W zgaDQVmqf3eg|UfVM$A5f3cKk=?&v4*#xaE5cd|6TF)6maRpsiq2X%tPZ3p#|W(fv$ z52~k#2Nm0k2KC;X2NkIRDy4;+IAXjQN30Y4^oI?(a1#XD~?xHJI8XnQs%sGyyvyR*JqpLVFP*Lun%w-4;q~6Ny8& zp#B#kls)-1bC{`j^zK9$Smt}Aq z4rC#ZgjoA8Tl(_qShU1HUGO55qgayWReyWNh_A3bLCsp8=qrRb_!-yDbq&p>D6e%6 zrT{ct*eLk2m(;}5+_JvkBtfPv5ESnaD`L}WG1x%vcE(m#z#aNyNKSipewv$}qESt> zvN@)ER!SFYX>lRzT_RIdVGdAK#KG3YOpRbKx3KJ8&PY*^h-zr+yM<$Vu@lGcLb_j@ zY(^7UB~62LKY9uCQytf@ho3QT6A59Sxz%`D@9Xi2gufB+@fHv#O-hyjhGZL_^Mv~>cx`n z7;d)1Y$+ocyT-;1T5h*Bs9Gb5vR!-@U|()l`nU}rR!3XFQ)5Q>*@3TUZnL4>?r3QG z5r7@rtp|%SS@q&vvt?r{T0f1CtJqAUJwEV8rmnu5v7kPUsF}ssrs8aGDtF^IAMj`r9EsI!pw3?Gz&qCuJ|ve9+!y8YhA%H&d8#dH+& zo*Q+k)u^4#MrnsChmx~JRI%mJS1^Ef=X=l1VgH|k(%2E=9@=!YY{#eQ%o{Oc5uYF# zqPYt;eFF~90?^K!HeX!O(7;Inn_T_!u`l6NuVsh?jC|~){tifrbG;cU2BrNY{nCt?!(xJ;gC%^wsPLo zEw}KSf7H>nmVE5VN(j$7%8)}#iSqYyX94pN3Rzf(KV3F+R{~uM$uDjx7&%COkc`hb zl0^}t&3)P+3gdi&(qVsms81h>Rg8-n?-OP*sr+vpS{^T@>KU0LGIO;U6pen-AIK{y zU#A%>hKJ{~aAgZW%@jBPSsu_{nlC4rXn$mLLgatky!PtIqiGf=;fh$$$e~a=uCO>l zzhznEZL+)1_1|`3+{c1K0dLy9CHi-K#?mPOLPq5&T7}B$4>O+$wIRQT6UHXHg8Zz5 z`(jo~M}9^_^b7L5VdrDSSb@5uBt1|+XnWjkn6FDf|OT7IQGT>O5|;%~CL9;hMA3-rdy6CG|%O)S75q!gG!GxK&_7 z{d0*fu|pbA=g^~@4#RQ@;1MukKWA)etm03lw zRWVP1F4_$W1F8jfuFYZULAmIV*upg?MBe2>KpkP=Mg~Nf?a}^@hN|Y`j9lEK@X-8@ zqE|Rmw!14<9YvDkH>4a3+{!%;H{fr1%4R=92fDZQHd~XL%G>aOl)A_$t)m^| z(u}4$8Mkq;4`N)$njDq)Yt-QWQ29h$$mc;8AXxjxAc9``7@+Zr7ED$f)XBe6Tr(1@ z;*J3rDc?e_I3U9H4h->mWqD4A3U#G8nndFs`*c;@{`^XH8dFg8ajZ^SS}{Lsu~9Ff zwf1}C!#rx2%|oQGTy?&Ja>r7dJ&~Nkr$Z(>m?C!;qtM>P=}nPkX~vPyX{k#KTH;!( zlAZ7@Ei-LlyU10luMZYZv#eR6xXS1$Z;V^?q2Mi#4j;d#9*IPr-IHASO9 z6_L!(k+=wrXHGj%NzpA3B}~l_U309a!ylvt7M7tI;*(c4Ex>7#_w2MH(tvFaYabMt zSD~`KEnh+1fJ$Sv!ww;nhy9b{=ktd1-87+zZi~zY<6nP)#|sP$#@2poiX^c@MDKF- zFA8v{l^WGyA;MU+8gM>yPTQco-f4T&I$?;7P6v2*fL}Z;CYZ>$^@|!X%?o`KNCUCn z!>}HKVN8=&KLP$YKl|tlSa4S}N3kz$S3@~*C%Yz%^ez!#k z_Ttu^HDXj?$=Xk`B4G-?$k0PK7VW4dUbT7R($X6fc$2ixs>AAOU?#oC zL3)6XikJH|@=UBOSNe4JnYLmVzLoiPw%M~th1-mC?|twv<$ zi*2b463C1kI{%oR37h77&`}$?#>wxgOhHINg-fC4HGgbyJu`^2KAD-y;C-C_Tq}WO zV5`5R4m>NI{ zRd6129N-TcfmWyXoCLMBk3=Q1uuEZD^;?i^(YnSZMn{+$jcW>Ny9)5(8O z%8n>j2pk4uwX|D}?$yDRZ>Lf}tISfQA|w5Ir9?d9hJl~frSL0dz&iTsUN1)Z{)D{$ z6It`eNWh{9PvL)8U;nC=-N}Z{earfKSFPfDdEbh@p1!r4?_ITV?X}I{)7R6RY<{F~ z^@g6c%Qol>DIuIjyGa+_Wl%*|nyZkDe!BwHdXo(7h{V1~NVz?}T&~qg(L{%KM0=JT z4R6{_(0Uc?XGHS1zB&5;mCXdx|DEQizpcaX=I-L=L`big{*iD|Aa3mv z$PM!%0p~cs{9_y%{F&E75TNnQ-uhQ_^E>PYh<*$;m_-fzi89z_q;t=^^k31GxZPd9 zQm^UoNgdSao431rzwSMu!!PMz$cUgv=I|k1_3I1 zq4pb2x82o_FGDW6s~z_(YC)UX)s9FfWFegWK0Y{{BFfsAZDU`+6aFeZ5`QbVSzh&mH5L|EZf#^Yhj~omB1C z?cIRhn@~0A8C)C+$0la13`W|9!jDG`44RGI*!m1>3zz({y&IRr?8ZwrdE?TXys0Ss zapHZB?D@tHX=wg&&$rfn5^Vm)BP6}nO?H9fjyHd6-{k3<@Fo;@g9xqG3@jx^Qx;~> zB6Ln9*CDkF#Mr?xNt*ig@H?)T<)9piQ0%$zik{mOp%5xH2(kQ9x%kewBHjtp%}NC2 z@sa7ec0klNvF*)YRmq4d&;T)MDP3Dhvdxp8#EG^d4m3j<7x%}av&U@*UG#SqEzfx& zMDbLGMIv>HREJ6KVO{dO?bNe_iTcp55>-yamn*fFapIQoL(UTY@k&1M4Rq& z5uqeP#FT5I3zP)_N({t(|5Kr)cL?-Gz?zv@wIdVPi^#khZO@HUBjn0@mI(8U~Fm7$;WRMy+ z`iqT=zFr-1H!1j*4V>OlR`n{v7WFM6oRQc{kT{^qb*KJ-1ZakyH}^Y2w4w9=o3wjj zot*_pKy+wir?nTQK$J^N!)SjX(*f^tN3a3SdVFYLdY?iS@0V!Tp z6foI}ZH}I%uPI0l=_>XGD3x!D|80JfMbu`g5a1T_Yn)AdWXV!XBX(%jRzq6sP<9{5 zNHIzp)t}HMzuQs_Pk_A|JmoU2=v)I+$^9(~5=-*bupp(%;v`Yy?5^I93Qq4-1Mbm- zyOi>D*{920x^(k)E2RaVrQ5iZ96QxUX;tmWU+r?fnFSNY0rz2$vN>uSIodc!TR}A@ z5(+Em(VW)l7qIncOk1Q;&;;3E%vQfZk@TFnQ&9rcWlI2;+Hn(Sk`yx9z%% zn;M4wrdY}{N6d`XpUmIs%y!$crz?mQs|BfyrCVj`;#Sj;FRTSwOSX^wYhzw~0bI1K zs}~{y*Z*6`V=LJpc=1@;dw-alb=$luphkK#i=p$cd5Srl7@UrE&e5{+Rnvtn9bIHsO{hd+mtHa#aEUcZtU&X~eSF!0qeJJ9+bq&_ z6_@ifPQi|+P81dSOI?b1rUR_Vu=)ewlbKJn?-kc)l!>@pSx8z4#CPg&^hJb<8-Fht z`AuQ&<%O^>Vv>(_zYmwzUoz2{Z~Mv3 z?IARs_TUSDQ+q&^`j#HzU*k@|TmmgE_)s}tfM#Tf7G=GMEomZ?i}9OV!rc8@QF53n zFGOtJ;ui5{$%}k67OsGhBDj5q*0rF+DA5{L@@{SoyXRc(5q`!BR=aGQolQIH zty)5128^;$wEs1i0xdKTKlRcHZ}-T@GOf9H1Y}AsdxmcvI{59SlS41Rc%sDS%OhR@ zA38B|JbnJu>E}-lJEF@kmj+tG;Xv(ck3^4RhoyR%YUJgo zW3eM+a5_8nNt80T7cXOqz@D}@{lt_fGEAk?100v;pArzJn>^lYjZ8PhvKOBk896Z$ zLkM3UKCV8Dq%x9KpW$G*3_W%FDF@g&3^msQHm3n}pI${g&(!I~>@XI>< zmJXJ@29-LZ%omi}s>5L&9@V{vNZG}NJ*}fvsBPK(aPt`(Ij6SpTC&j+MEs)5C8c(% zn4>y47Vp!#C;6!(5>YU4*JF^Lq>{zf8EohE7kdpb`5VVLy4Upr<6gwp+0FEWx_m(g zd*)(`8g(^6wI?oH_!@rGFg)n^YS^y-^+ShD+)?cIuh z+k;=Le9^h46m8IU2j!P2L&lKK)PC+YWAgag9d9;&mI1X$jpXNbjC?;M_%@4;ka|R? z=y`&t0p77*fkcW@0^a8j-NooQBzY0clad697l=z3P`0f|bx454Em#g*Uq&}+5D0#F zcYK%EFp-bqs)gM_P>&gBNpoJ(MD?H)PYPXsD)uBvby7>k)Acg!P7r~Q>F1sc8jt$gd=Hx>ddMn1|bu03Y)twk> zhHO;aZ^rBCm9>6ly#nHh)Kg{abO$sp`Uacd0NYQHhU$OZMK9`~PdM_)FEsG zv@^+Wup)5ZErO)FLgMxM*bsjfj78q!iaZPaIU#zXKZZSt9KUp%aHp2GYdePB8^_4* zf6XrDB`zz?m83UGd==x_(wid3RI_RHVm4#o8~$D!8e{6Dej0?0{Ni#uf-=6F#Q#~4 zfT(S1PI)h}vJ99pX106{N2e$W0G1SNT)4SOs=+P|w{4ePT7O3E>LsgU*w%k_V%UC4 zW%6?jn=NN6xR5mC-u^ujLOCn*Ok64XDBWD5tp0@huZ0#G1mT0b3JP=cdN_2xc60De z5qD-=07Wetch+rQ;3XJ{>)Td}RVaZkuTX_18xzv@A|8sovA`XlpMm1i&ZhN7aO#M1 zdRCXi05Ptqw&KX%bizDO5BQjpS85w1{!bD@` zDj%2pDz8-AOY0bSjAS5|Bny^#;K)R8NBr|rDVT>v3oPacB0>Q&IDfP~b$7`EdNWpP zY=_fVgn^Hdv_@c$v#7j8KkSqzF&xsXs}{&bEThbB?*a?Q!shtKyA88Cpf|oU9G27h zZ!Lzyk{H(_OK!%+dW=jalw^#fwTXmAE9zPj{J!eZQ(si8s3!WHwwfTWVuTS=74=g& zQb|+eQ;q?C#cI7Hk<;v^7qoJOhpwp&rJKTr z($}f<=BD!2?KzlQ`JY;?+(6doU{UziekG0g?++RJFRcb?U~UN+de307EQAwrJM!o~ z!|2ajO_F-ENYK!GZ*CdZznzc|obFQd)tDyjrs(-K$Hlh1g;Mk!I&0 z9aiwb-s+2~{;6CHqx-OzLG*dIn<8GKj*fx^>sB2fRBEy4noD{haV>V$vczfKTZH#7 z85Hw31Uv*2Yx)XgS(HR$*R$;1E|t-7pMz)aU2>$mmYu~yV|u}~Pc zFX-;SeFzLCuUKS{|MfHhKtgAbToIFiXR*xw-lAMm5nSAgRBiCw zi`5I~{FP(Ab!@-374V>9U2{zANbQoed0g-OJIbbQwD2a=0xid`01rWEWZ9`5xAIfY z?`0r3aXs_uWslc*enc!8D-e1b@+hoYM%S4i3AJN>2fdlyQ}C7kR`G4+qud1%D=Y`$ zNsF%AQHDPhK*r8+m1x`eoMG#wQDDnzQ|&nk2lc=7YA14QzoS*SbQ%*!Gg{>@rB7CQ`Ur;PdYM%f_cx+wql0aig5x#ss3}; z+gF1|vKF{8)BjkGMcQ8m#hoW;<5OQsv||n}U=7MU)T(Pd+d2aLM+QVP7sQ_2*3|qC zu_q!VQ9Jrd!%nQ8MVmE_&9{bwi29Ub+{Y~;A0Te%Uo`q6oe z4s$xp>+n$>EE$sH_7cU<^Kg~s?bFJJ$#NA$rXBOJ-En$bh-FaB!v@DZ^r6S3|iwTBnGrU7s-HhdkWK?$uWs7rSIBwNrS5^ydo)o5IOstUB z$=ut}jh2RGX-c4NP+EN=TwJ=H+p-s#@{_G&@9jkj&+*HT=U zq&?zfZEzn`oa1Kst$k+?0_W*2(yfTCHgoo&SDO z6T($o->HA8@XvK$ScP<>;fA`zmzEF=k&c5O^pqH)EnPOJ|Tg!)GEf;<##QblNr z{X$5J%{l^wOgY86dz#+O_>Ku(^aJVR z`h>j6;;2KXXd&D=I)Zg<%94H`uh=l|RaU-KIIaCpJ5W)d{z*NjKSz1*7Achv@jaS@ zy!LzgMEa5w+3e&6x4kl19&2yg@|8AQCduh4ACS?+N`HWQzp~a&G+TQsAU8!o0>wB5 zpaZvnu$w&T4}ZnA*P69^<$fxEu+<6`Ji^bRke$OxE6}2vzS+WyNjAbQ9gRBR_p2#_ z#(NpDdaD&GE}zf!3_BmKaxA$cR4 znr)=tqw5tMo?(ieo}Z52&1GBYYAs@~tjwMoyuhscURBYWdg+6@ghCar8b89NOKVPA zd!0;P(V$JI-`uPVN)czXhIF>3u!r16+~h29=Tkt=8rH zIHZ+H0u>yzpvZj@MSY82L~*=6H5n!e0- zE4EZlDNH?D3Ok614TG59EwT_u7!k07X$9ngAi>6fkOZ>$JUY4;$tJu} zw(|3-F?_E*WI|)iR=h}NbaO5-VfivajC<2ofivts+Jl=5vIE<5k!43&(C zE9Vm0fAoC`W~s||Q^AskOA1(X%h3w~_WtZyqZ&6bCf8cH4vg&O*~KlAuntL~2d z?5xcyEbsnNICF+60PO33Zn}b34y1;mz`X@yNw?jaULi{%Q|<#DZk+=Kw)3sVsF9Q> z22tyIH--<%`b`pBSksqR!>o`SZ{r zLg*2t4jp1ng)rmehfD)kmsJn~$miVy2e z!8-j1YTr+)H7bJuJOnC)hy!hsRG0fc6)(DYS))F*dtaY_az%}yBwo1t3@qx`5-r1 zI7YKzg$2>XWMn2UqKQGLNi-8Mu;AIpcz1-aHB2bZk56f`SyCaCuotJSJAB11u zz&@aly(6+9x?mN!z*k@5%o~nI%l6Q=S&2vA1FzwJw-U^c(aV1%kQEY4v(qhE>x0~h zor`^~pH`=%>;fs3nth*UTfE5{f{j~|G}WIGqi8-6LGqhht+A7|J3Zu~UTfOKpxFwy z6caaxum4SP1HEPrQzR_$(FC@O+~Vx;o0$D`T5Wm9?C_(Q{g0cgD$ROXX^Bs;*|1Pj zG*>NRF(y9Qk-$4zPgqd#?Z~6#FUiM%T|Vn1G?DH!vv4)yPqKOw#-_!zT*~>*Ory0y zrMDL!N3^SyqE9~NAwq3URlT9%p=zzzr=t}8>Q^w_&CgWlLe|2I-}+bUmDZ|@W5t+Y zOwU%O#1F@hShFFll>f=f}SDk@7>j`Ys+#cpI$kkUWo zh9`mPl7YA+@vuS^JA9$?Ynl<7?g2yPhGZoqWF;FJa^%OZ8w<{U>SvoFAY+@cfXK0&}O#R8E$C^iZb^&1i=isxO3V2a^SXp@#! zBEMAaGsow7wehe%Sae@0ez?ZMbzZ7f#?bH)s0ZU0$tWl?)oA97J2b~l1;oW7AKI_f zkLn->k&0YLz9&`{Gs^&x{v92DQil&H%eRp-)2-S0zXs`z^Tpl@OQVQ}RG&?1RDNFw zQsOdn4Zt@xCwvBbik)VO z^4F6n1bCJR_uH*e{qBs{870G{%^z$v=U=0jBeZ1s%_ z+EWWNzzFmzkRj@-1;X%|aOje#Ux7gKnc-_&#-c&*YaMvzvJ_uJW z?W=nkp-^>eRPMEn^fN+$AJ?V%q{JCpFw{8L*W$bZi>X=Yhgp)ENv3Q7<#9@ka?;NulShH3H ziv{lJRHg}vyoi@fR3`Q79<|7iU-#r^+#nPvJ3S^k$ipl#5hAc()S>tH_TC@T$ZT+#X@DGd9f1uqVbK0iEi z`l;dLCq_@ddg_E(Rr~8}F(6BfFg43F`u=@gKCFWso?Why_Dj0A5OdRSS0hB{md0T% zl=3lZV)6BDj^#km(<`vcH`o^vQP~Y`))LB#43Ev$^~Lg1*4!s<&>!{jH!N-Q zvV3*5&ia->FBoM!Ij!}l$Oeu`2fxUu9f26AyMl)OTy*QUA*K?~d^eLtS{ zUbQj`J_^e8n%mX##Ff!P^3T(M#_hPk@8vtelg|N)!Fn+C5vZG@AD2XUEAdTO<_`&& zA{ZDI*=lbef-ZDAgy$*~)0O&|9_XK}Fi-Q#f0yP~EYVbV$?G0)9Ep;{k!(P_lOD+q zCTMm?vU{|}^O5XcX;nwE`x2H(k7S3m$MO;FgS3v*V8Y_(5zJy3<&I>B6PAH}wVBiX z32|meh|_i| z53SW!El7&rYa`MV@dWX z_t>oZMNUs9RCOeKD#>2r^mLM)<#asBKEi1z$zJ2N?og#`Z2fkOd#{J={hZ1nyTEBI zWErPQ$i_Kc4A~`4)sS80^k~SgaGD6&Bqwy{DNfTNo8eRsSsqUfPO~9Tt+TB-zKP`k4rmXOryfxOy(hKF;a+Bzu$72b1hA zPA??cH*tC~$^IIrmkgS0ILW@9tM3TecXB$J@M*Ur*{LM^UQQoMvLE1-CfN^h!b#wV zhKMPO=~4^x-7?6sI#u_7j|5NeCP?s{ACUSCj0gIsJ6-pmF*c zuFfXe&vE)llKldwa|uiHN3!!t_Dh^zOR`_(G@4}pGpE-RK7GfiCE2fYx{zd_;WUNps)g=2DoGvHXzv6TyVTc*# zB>N(#Zx7k;bDB)DKjKtNvOnQ8m1KX+373KI;53tDf6A$zfDA{nJjwn&r$&DK z``et}NV5OL>1qPH9m(b*Zq6s!pL6xmB>PKFAB!k@Eu!!Bgeh`_iJEmMN3yTMa?j~& zBQoPUv7D;|7*9CegN>ULGq9f%c)gO-*8w_CU!P<RnE-jl(Yblw`YIojx1r`}%C46FVRUPB2o)oBLeyPCf(Zn{3O$%>%x9mv&+M zgvhU`>(eJszIfuPVdy^IKDD?ocC`w*l?qnQO&`nt)P(ts`J^qXUWLAT3CpXr72mg| z!`t&7k9!Z4MoyhL{`^xfzI1}U0ft6wofzXgg4Nn=+()}bRKzpQmjmF#o9GjrzPBTJgu)Vx~E^$x;XTb`X4N-uY;#J-6I}QnMvEpwJ5! z5EXhCpe0t{yErj*p*&$dTiZyCu-yZ@Du|7oPTBL|!%w~V@(I^eZ1P~pVI0-g5F;l( z^zsQr$?rt zsVoU%#0N-1CPDfDG$~m!asgbDmjrOZdjNq@Tsw*EM0VSFCho*Zn>KzZjxtT1I-SYG z&h#-(W^5;M8Yj~@b~8!p&cw1)+mobr<44u+|JOP9T!0`%Iq`HV@gAJB-+S$~)?Rz< zwbu?HhbeFJP7RFugg)ERz;+d%GYo=(Y{jeJ8kHLTS3?HQ9vZNZ3Yq^%9_DuCY&%q4 zOYb6ZNuO)y%0=_N%(MH7vm+-C49TcwxLg!kUZ_>kX|JY~c%zM_9kxy0v15nV4~_UU z7ookqv3nR%z5X-TYak7eB!fdoWn5J%z1oLS{kq#}cJEF;MY!Mh?Q_I-fAshJ&;I?% zXNh;jTl{>ppKne6gy7_JdEWjrrTKmGeH6r5zqa$w|SB2{mxbb9DO^0@Q7 zI#Tt;pWX3iU;Nn~f9{PxZ;3x|e#C(2r%nyq{{8WHH(B+)Z{H(qd6h~BP9HsibC7|< zIOP~TI;8iYzrm3+gTn*v#zj9LbGVS?_`q4CYqPE8BPWv+2S!GKpqqW_AK8Q`zf#Wfh51Ac6!Erp>6+h~2ohN<8^{Hg= zjR)|KA_B74R+riux`bCGk5j9W`ylRB-f;RPEqAFu*xKJ_Ps@i696vsstOKo*J9*ei zWIzM=E8)XsxSaRG1-;47r;?9Sk!@4#MnA*P^68<$LnjXpl!s2AI4Ek!DS5bj;=rj> z21QHd8N172Dt9u&h`_#@z$2w4@~{V1ekZ5Tr#2+vy;)IFK{O#_87)Izb|Kc%L?M0I zAv!M*@`ksdh^&zo6=s1OCdi&l)(k_q$dW!pmg@9)T^1NA+dDO0t1X>hRNPf7~;lqlR8^aSQ4U`^)bEiI{R1EE9G&g6vAU6gyOb(*+w_l?BEqQAt=nn zHV4cI-lU5`##yE2Xky)|tH>w2=#^+CutHjYC&-6W`=GHqp+xyyTA)yd8nHFP7Ta{6 zMyW4!jj33qMW_YMB9zQc%9^Ne6_90fkB=k}a~=@WAv2?> zb=Wttjk#qqmdlFuJT`Q4Xu#JqM06EXx|y_==1By(oJw07rw!h`aWT50FgHUqR;x^E zlQ!kDYqE#TQ7}B;84>VYERU31`A_m3Y{MnSSkx!D>NxJF&m24rd;1DYqef-6-snr` zrly2cAEeIg9FEq&Xm6Riwf@B#I+Lz&4V6#%<%7ZS%frV8kBE^Ipvk9|mdw^+3<@r~ zQC^0T1=}kx;{L6eSZ-mS8pDCJr;-6CAUr{t^7%S6a99$GX)D7Zzvm+>?95nY94j#{?o+kUq;_u5@Xr4Z&r0n}O8Pm<9GXgLnEgnGgv+=ofwmwyR z22N0)_FTu^iscKH^n#tW%l+??xy9osgsF|q%~ty=O?aPU zC(W4);k$hJaXtnQ9T_+2-GkGjp35IO)JBPPD&(jb!Lmh$;U}*Hyf-?%CRm%Bk83GlNo}0 zAWt2=6KLDlFtZ8nJd}A_3)gLjP7Wl8Ot6Y&%_85`!gTwm!+xIS)VW$d$zG~1%yX}I znge(c;vN}1GKdJ{^ex|>G;0%m=8SYsTE+~$T2l$d;CEAftyO8f95{&vwo#c((__jV zvV9BFX^KzgP`SkDNwoRVXU=!$O2?CM%}u%FGN{WuRT%fkeBap5>Zxhy`>z zTIq=`6X9A0)Er3nO9acxfZ5D+E6pjG7CyDP4i~$=u)=b>c7A#a>Isk(tFlhT&Yh10ZfDLU{DI5>MM3OJmkhvwhVrk$6Q@p6 z192H4;{XxLJ#gF^C6ei8Irm8F@=%^EUY8pb$4>@35kO}fbF&vbtFdB_9CpCau#|BX zFea*FbLWwqtwNZY7;`HR4;(yw^eF8zF-Yx!y+GeoWm;!Of~zfA{CjIm%U7vg4)HT^ z*)m}7fDLDD_wdptrFib)NGUzqqnPv0&AKC_Y!>hy)_$fPbt&SdsK}yuyXJ0)ZzlP& z6!+4C$ko(1v}LOU{dL>KqG-=Wv?Mr$_5M`eD)k|mqitcR^8$HxDxc3Si*T-8vC@52 z6)V*%uk`6=rLtapC6#{ds!E%qpjjOGD=f>|j?gvWo7qFtxvuSk!L!;^W0MSZUv@u; z?K*vTt=GFhU^QOc+83@6V)sL3?{cDOQbo|nFHs5$YIw~GEI{Me@h6uF8 zF5_A(6ur-=t~9%Il#f6v#!j2~_y~6Iv^m8d)bu_6W)G1<6vIwz_GW{5AfRN%LKQlc z-Uh6@9c{o`&CWdHCdvh4WC3DTrM{?G0w;4O((GxKn`V-mbxOUY@JX2EY_#-sK=o zJq1V;ofzPd10uQVn+N{zXhSr5p-$s=*oGvLJitsdft37fmEeouZ_ zpM+nVuf2^FYXH0Fp%R8ZofrdR@>5#J=JIOUOO%$Q)yF6^#wR$ec9%Im%YLyT<=bCP zlo{ldmTxxUGK%Hfd;Y@=Zg!4%uR2hza59*4!s`DX&IJpt8PK3*+U4^~1bQmsjTx2;WLX5pP(;)nftgSd z5q@5tbA-1<^BkPfC&&985zx&;><&$q5T;aAOr6 z?qfR5l(CV@h@~0bZF<_dTy*1n8&aqGY@h9_5^F9v6G34<)p$br)YWNR$h4+a&2fgt z-c5t?i?s{|4T=^_Ecr6Xw3RMQacNHMvdq?JYU640F7nibNuHoG$I0b50wLM$m}UzY zJucF$#LldvWdD?y{@$vZRI`=}&DxaJYlo~xp^m_BQx>JaKKLwRIvd96e68D!c`Q5~%4vm|TIg}q&xqjRSN%+(E6*G*>x!9-$WkEs{n z&T;n>`qbJqOID`o@e9@QOJyX`E(rm%bEx!CBWlp~ZQct%)?|8Nc6R2WefzM+N%0#c zo6WuT#`%5Q(|viaeKco4bE@-(sqi_ZjfKn{W=}aokv%dY_JFFtG7{B1qDp0?0_W?> zq>=2XUTTr0wL7_ijZRwB%bHUH3N9xDjxu$HoTF;gA5Z5Y-Rvn}L}Qi-A}XMl)>D>R zQ-KQ;hp~H;<>nPO`;Zo$;5Fo#45NGZboJ)M(CcKqf%=wlboo;x#8N1&v;R6(P0QMB zre0=%K96#yR_&q<_8dV6C+gMoVfDm~Q+KlZNKsF#<;YT_Fs*GkPE2`m>_EDZu5^xy z5t(|^naUK+TGZsS1NU}WLbm(hIJ(%REz3o-bL<(!g!5@o_d3PlL|mdzq$Yf4?Q&yH zFSS!V>~=^buAhnMMPA^6cgIu#Ej>#XY~xsL-Ikfon$7aP2^zcI;as=$%OW={>L9Sg zPrYB}^H-j8kVU1#Pdy{+c$vYkF5QYDoxQ_gV;2@+ScxIZ4V!vRv9y4LgPsh+bY4{{ z&F>XyplbeMwW_!%D9dyEtv;=I`S(hfhxPA_xI%COM0ZUvk7n|eIe;0iH{dcZD~=M5 z`R~=+*Y#+QM4Y-3(+ydbqo{Fp_IQ1AZfZJBzN#n{Ou&5dO?`FnXw>JEZ}B(zHjkAj z{cn(Be<2&KMOM|JZahX|D<(VAo7(O#_#dMiL${lkR{p1+>f6iY=s$z0&a1>p(3GbWIek`@T&F5)OzV9q~$QcuJW5ih~qM7{A`k{sdfdXe^BH1D`z zpotEo?O6K{)#EFaca0v;%uSEa&RK}V#a~<8;^k^Ri#Ue_2$Q5j7M5mw@Z?6X%#~+ul^O=y z&`o03REX3@aO0=sMM*$fuOr&o`;BtY2nXeO9&AGQMc_0CFNVIl0fCp(fGiBrHB*8r z^Xc)XSAYVr6oQ{2-(q0kP^bBgq{|^69`@#4*KobjSYRHMENlTI=P8Id#nBG2CGBJu zC^%Lfui&>y0!3Fgk@s4MG%5#Pd$XyYNm!zmvX03%43+2JF8iV4%*)~$92tjQ(ymZU zNw(~YDM5C)NtK;l&Rbc$i3%Pn+fZju*|Tcb_Oxr~t)%qQ`Ks20ZFX}C2{9TVXMFKv zdb3pjZt&bohu2pZVx4WPd+|UA58G^G@TA4^Frh%+v*3OhBL~|?H{1p;hn^V47-1gv zWWdDHE)k1Mf=-{VOwLtziiE6(3=u=4;qpYpqgPPyr~WMZkMfu z2;H$4Ns^ST?b1d?qE?5cxFrI0Hd{UY95Kny>hT1D$@`U%muqW8eu5M~TJSizzIBII zkx4&wD%DXGgrml`t7dwMU$Fq5zSt5OY_4YWdpZy6dV5>xoxWv7m!hmH{g@dgA`18j z8+s0E^|^^>Gj7QTF!K@~sy72AAz94@LX@D@h!Q7xE;F%W;WDmsx4F2yX!6Ji_*%0^ zI;b*Fp+1G+=PO9z6^hY*iRNW2O9sp5F|}dIQ;06I|1Y>jCZl6P*41TcHwWb~C8sBN z2%J0ggb!|ET9Do%|1JZsO^Cwquu!guvjauc9!PY9K2UAlldh&Umoq48-+1Yzmuxk( zcN7g$ZFY3j3Y_A~t|f;vLn;CRvLiLx1x+N+#Q~&uDT3cMk;f#hJuw|`|K~!YbxPjW z!<85ut;v_l>buMUZ6BbKruTkwxF|+aDYIKXeWXv{Zb-E7=W{IfzVTvL#@2GMfNC`A zjh|5y)SXgW@*)1FZ|5~zoE8hxIL>;N&`>U)Y%IGzl0=nOD~<6BUD~-?y!^@!Slj#} zUx7)C)#@u-b)kUP_!Ppt+gxFpJ5x`+3wgo@H^bwVX*v>e``mPhut&%lM@K~J$zytG zVBEnN9YaenS_VAHKO_9d1(!R>WbdXhxApCkZ1I<{dP92;@_lEA<#J2C2%EIQ6Osdy z&r$wjgXakUyuy1ZG&j;(Y@ZQ{{@XP&|0&@ub^Mt=|C~qU`oi+LJn6|Wq9x}Sl~i-! z;=RNm)F|!CD*UgSh5v;<|7Y{_MSXrH|1|pGf9q?_05R7vaWW8^MrBd<*Ol9zYK3<` zSY;#SA}smeO7eGkdC50u6VS=4IXz0F-;i8-^Sj^rhk^n@PT)-vc8TQMhXdH7-@=A@nQq(hHYdb|<~=Afll zl!Gd=cB;1U;GnSYfxUAaV^!fR_BckOlXOX!nxqUy9_eS&?~yTXRJw_}zH0;AXy}b< zt!2WOvBHfSH>;bg^KK??z(W-A-P_tmxp%22GSFVZx;9eYt&|d>Pz8oLZG@K<-bHv} zKN}IfijX~x3>TUfvk|vVaodTzE_2z)vm(Q&MRtqk6ZL`&6AAML_U#rb(QAlzhNsG@Ggx@Mq8w86d zkwsRjt|WP_$`I3zI%WUx|EpPQbm#$fs3!+v@*r>j&+JU2MGvb9Wev&87?T!5P#9-j zk40(Z6C08AcpVm`MTVwvXK>10lyTiAqeXL@rF>T=qStKACR%e1)6vKymh$&87Ii7f z0gaD1&~=%GMxH~;vzt8EZwDGp7J)4_25q5XanCUElnA_{)n}CFQD0>GnH;5U(aJ&I zl4H%!$JA(X_*@&jjA>_-s%8}SoGtBB^Ou@%wnS?{zIVo)(W#T_h0JG{7;Hw%)xf~z z!bUTBLlXqU$}E^Iw#JN-M~F;L=V>h-PoPM-w)JIHsdZj9e_yu=X5^HhU6A^BX@?nY zKclwq&)c3nuFs~_op3O_lze|P_Q}PcPc8m@^Wx7RT>Lq<_;Z}k6%8w+c`V6eb+f!x zWhBDprj)GZ5uX?I`DpWVnzt1V9-S*@!RxkkjG8X1rbb@VvZjrRmIXsQw=iNYF8RH? zE|eS1b{bF=$f&v+d-0Z$(Cx8JJe69Hl=Sa zZ}%t`HBKq++LP@~BFhq+?RbAMmblt)eFp}2-~InxtCYW#l@Ncs+E*^Kt9>)N!CTM=-pr*dq;2Pal@QODZw*^1{+~s; z|Bw9F%Dpsv>Gultb#-i5g&Uam&NW;ev%a&tv$OM-&YL&f*txcIUFX{Fa_4I6CNfRL zxWKOefNSX>KMMs_dxb!W1C64*LdSwT1jt1%t4f@&?oi6xc^qJ0289NScDca72~?aO z+S}BKG034Y)ijPS>~8cz;M935h%m7Qc@)AEbr&zxqdi15C;Vwx0o|6P|(4ZJ|q>2$|}i(FSo>1ovZjA z;+KAu2aUYQ>k+?TrN_0a-}1|?E)h{cfh2zgvq2KTQ}{x208D*;;$ z$L~f@h5t{$FF!`TZBd_Q#_%pUqBjjyq5_I4{I=Y%{#%kguX?26(Je}yYmyfT8|Tyi zsT&9RU5)j&0bqQD{vEAY{{YDkaQaO<*0Nr#ap0nyj$5zC))59Zp-IGCBhx{r3)A%( zPQ>i>ojvM~kje<9H31ZW9~-*G3!?=xFkUh{Fj>^lqGJW|{>BuVo(Vs?B(CmjtQh6n`{`s&Ae4{O}(@B2-*EnJIJJ+ zJ=_=59<_>cQA~3u&ucCC*%K?v00Zw-+2j1sPmp_jc3FCN6J5SL(gHMs+ zgmlQfZFF=BqaXDBVu}`Q!<+=v0CPpu<-W3&#okb3`)oADVr;x>Dz_P*!t6yDE9>Mm zIpSi+RlFthdi)58*y8NdtUy?rd`J%y9w|zR{2C?yg@>*Eur`|*4J;4;pzl>NZ&kuy z)7!7>@ti*2smD4qbM)=&PVKCyJ0!qT$|S0wvBrtd(DpYEjFZm!8>6cI9qGy zMoI3FyoFSoxMFQ+S^i|usiy1TPvS+tsRpUH@Tc~1dguMPPX3xhXzwegVCIyVg5eNQ zDbo$;^6poc+VlZ2fj;p1=6;)SjjT)sBH*^RGa&98&hp6o@ExGwQ}%MKeJ$;0G;P#! zzU33ZvO6Ag~G$3x0 zLWZJ1y~dUmFEPB!m9K57uc&;%gaHwT?U@+RYqY6a>XW z4|$MhF5_@)8b3z4iD^hRuH5HeAjKEeCM}}5RB%;iyWDMi_=IX|;~{?OpYmYr==!9$ zZ?ku%C7Z)3+%_g)B0L_EM0>p*5)7X$l^%!93*l^eq6pt4;0Qc$*;OU(trW4gnFHe% zk~4p;D~*zZse>2KQoN6@D?RhN(!wSMg3O=|Q&C)EfWN{!Y|p~JI&%(^jtpBqF2fd` zj5tF}!LY_>jsC$_&k{Clp(m_GEC-)J7tcAdar*85G-wC;dBdri%fX^RTp6`X_EieA zVnc5gU-}tq&hes2&Y)Aj=qjg}@;?@JMVC+{Q>Ri|tcGrR9|dv|VoFvBU?GHQiVo;4 zb1JBAsLqh(e6CW&i74DRiyMa&lZd{i=3T6|8HsYqG?m0l9tDs&zD711WnPIr{HvE4QtW zV~A>t_>rOc0yPU-P!ymsIpy=pz4^RC%(R&UjHnF%k)6dMM|PC9G$R`?ItV!yY3s$( zLQiHR3|}H2Mk!3IXQp2ZPYG7?zRde6m9sX(=--BXaC6CN9#(jfZ5z&t(fn>kyppgz zd`b`3g67S&l=$-V8O^IBmbMiqQ$Hf7Kjtbd)s$DbAT9ABcmCcI~b#cn5Kzy>@sBwu}`gQO#t_dF@Sh~hPCX}Aslv#?7{z~}*%Fsu+lg$0<-M^js zD*FTRRnB#Iq!!!s4je}TE^QGFh(neN`9q&>i+B{RpgEvx){f*?iEgRy4Wx-rUY4~C zks4*Is&N8!w0~y5Rfz}ZkS%meK?b^jOtt#J1C>hp!%oO42E>*}8nyEmX7_jXpM%L@ z`#4!|Jkq=E!SB=mytbdiVEd1JPyczUH{d)BNizeWzr! z^*HLHdnacf);Z5dC(q66(8;~$XCLn0r<$UbO9wb^AGNUe3A&cNhlVDf1}cd;)aUit z(8DgCe?xCJf&7Zz#*{;Qpvlkc@f|(>Ru66IBv4{FsW0pnL#ljKv9H&|rTjj%S`Rc_f;BV624YXO=3RXn63?QwZIj}be}IlD zBX0^wtCO7fE;JAkSRcPsolSlNNLdmM&~WNL4rHqjfyAE!lPqF3Cj4i<;Xlq!dw@-**WtC{FKEl7YOG-B)6LmkbegTREGXR3}laujGPMEG{R4DA@VFg~Vl@dZ7a4M@aR z67{6$@G^akEd&kz*P%)q-<8_#>Db)4dGF?p8hITS@4)uEr)^z37(lPgNQ88U_@#9o zA{Es|WJPMw(gJtSHP1!2m!7#pm=Q9ecn}L%h=;MuE`Ni#^mR6*eWX{G zu@{@tzSQ;_>U4m|(MDy4Lqi+|k){@W>p(;oz~&L;|p6wcxAm#HP_JE`dZm&J6xNtAMZRQB2(w3J1?#Xm{{AuG0bfa55Ivmbw`gX&eX% zah7gmS~Sr#ss}}d(mJA$#bZHEHwZ!SZR=1Cou|bxXq1XDyj>Cn@?`7!o4zbI`5o^LH;h<8l`xx0Q|Cc;CeZ0$10V= zc0*6;B2Jg%R_oJdVz-qp;&+*KgD%QOi_&CuIAO-CbH?hZ5ns$K2YB%<+|JALA@btv znYwPHgmy=un2!jy$s933t+x~1;b^q$d7aBeb6#rsV!3QGFIH{MV6swCH|9B(wh&m} zNqd;qH!p_Do7(YHKlA2xoP#4EXo_Pv?h^9gFPk+Hj>_>_|7=^kAQ}!lUgdEKFE2!C zTmVyqmJPBk&C%kUlD6XMIv*s`ZOzN;b!tMk;Q`z4y`_uycwm;I(DoKY-EI`RCohrO zqIs;9o5&n#cm|5@$kXg}HTULlT7JNG=FuG6T4p@y?JfgT{pR0peF#3UcHxBV$wT@a z!U*rpLO}9(-;@E(5&qcT5;MBb8Kb~`B}4!FT*rN47^>_wPC;d_#X)#W>OQaPS}^(k zMUnYHiIvZO2cW+}z*oo7X_^Ze#Do5iFv zCr0fYY+&@v;LzcdXFPZ0g`pmrOe9>poJqW!TYRftnW5QU_FGzLE)MOGqNcVwgI0OY zaG|OdX3evlV*3x`UJIXr_wBcz)&9fvIlA4~40R^F8KCYoT$u8-_MEi1vVg0%`lMVg z2zZtN&f_9L$2%lyX3)Dpr}3Vda)D!NRmJv+E88cMpOXyXrBT0HsTReo={r6A9mD1U z%JzKyKEf5msOk;ABi!R0I?+fxdag0$h~qxbCLO?RZFaIcI*BSkbwtm6>xw%hR2Utb zo%W`jLp0h7u`Cta%Pv*m%05+?q?7?>`-RqY0+R+BhjkN4mzE!Ym1C6f!WDT{tP9AU zQn!^@v*)@w!!lcE-S5FX#|g@G6a}JteH?A?SpAA?3uunwhr~je3p!6uXB+mQjDh-U z;=U?V^#>{{~R5@2WpS)WQQP;9E1wX{ol8Q4F)Ey0>L-pcL946Gel8o88`sjRZ z0$0h(hkwlYkbobNfpeKOJDq(=#E59t8d;dKpi82NEI?5|ElL#9U0 zS28w~*Wl zjEdud$+v~MmXcr6+c)&k5_Lsk*sISGI+V^(uGA0w&pF6jyz9AvT~B^^2D+1zUQ$ME z#j2=>-O?WRK)3M!=Jt(xqJY?n=|&I#cXPCGGdVVpLqAfn&xG>6<6ah`n<>A{Q)ew% zl+s3T8)`Hy$DQD%DaVPaB1Iz*F-yW}ZCtY{pX^a^T2?~>&4bXNw+2m!0}Eb5!F;#y znw_=JmC)I7{7h(`?Fv>aie$5Hsxley{f=PS0W6aqJ-mQlt+zFTuR0N{QKefM+`Gx} zGXl48Tj17Rwi{y;PA%2XfOs!2%r1EQ6BG;x*4a1-%Vs05xiz7CIidON%yb3Cbu1o! zQi}&rh3y0YCuR7U>^@LNPdL5LPG5dc9_FRH!X)8vNnJAn@c_MuN++@Q)C^LAC!5qX zhqy0Zf|SvW_NHZ`@hbywoZ*J$MszJXs46oJGZC1ddv6PP_~&!*~<6EI?u2c zgiZb|X|f41ZlrpFvO|F2y@6*uS z%1g=WH(C0v2a9h7%d@*0bBy&M?IK|e4|)#($!s>5mX< z(rrPbK4Fy_;m0ydSkDT-q_%1(ghm^RWM=@%fA+#^iRT{9kIAcy;oB^k$rRL2tVhCPR|su*&|7 z8e+D;%2nwhWQp^lFVE~X^?yWYBiEPmRVc47n?P~>-H7`)F=d&%aI9A~(wLBcfTagwi2o^f^`#pr{e~ zvOEWI(MzCY(0=KZyUi+Jaiv^0z&BZ~Y7li(|L{(ow#cSjO>;qBqOBl95mwOR-{?)t z2U9>0mS&V7Qc+yoR48}_X^5PHuuNhmyQbtCw6~8W*Q-huL48_qmFiS{RAjKl4&j=z z3B|?8YmX>KUifX1q}gR98Y*~8;H7C>T;LV)cIh+!tJ=h0+T?bu;!Qsj;uE|y+wpAh zb!PZC+9OubpC@^mC?{9^)0;G3M8b-LS6VoLHaCfQ)sGx)RZm!zcmgf9apOp?iA^Fg z7f!~4O0FtA{nD1~;>hMC-a?DQa?7?wuH9tV$?w_|-7RGL69I!Cz|gh5Y;;FRDE|mS;TKees*f}*_A|*S z%MsI39%)u*K!dw#keD-WECeSnG(EF~A>=lql1+LDb(7ol5R^lrzf*5p^>~#Yy?WfE z$6b2dt;cpA*NO3746%}%tYD4&X98?UJDoU0l{J_pbwIqi0CJPRJl_OzV+oLh7(gTo z5TW%mz!d>oAwp6^M1Z<2Mk4Ejp10g6x1;$q58y2re+m?BNAOGxKJ@p-UUgDAu`)pGDP=i5IjU49Sui} zPWk!=#&v&51EOO)up$OzGyiXi!4NOdPpvi+kUfGxWTQJ{c#EW|RB^tGjRMT+_X}b6s~w_nOWdIy)_yWj31TMOp(} z>>s%l3INQfC+q0IgwBW%?1wBQpibs>L)9c+H~)KOq-~}1bG4#<%Qfv`QoTV-S_#n;K!wgg`ME*=N=s!6e)txN~OL zK>K3h<5psD7o@Lgbj9|X7OZ2qu&$G~s2rvjJvIB$k!a%whzNq7WNzUdB4ww6eV)v~ z(=<){;i0;5^ld(tfUJRu5P_B=H1BA+ft7Nk!!KAZdzXnDtT;AEBU(a6>`g$+^mO63 zjnRgZ3S5WC=>^4;`BpQ@btHmgFCEw~eb`>l2!dfy4)O}~;U7q4`Yc^!!W&lb4G#XY zCLviY(SSS#U%q5G+J=KSR-F-voz$7>O{}QN#&%qp1+~s7{3we%t%KQ?0y^w!-RKui zC$K)d^aB`NR4rbE>qS7stKDf1qXe;io?7vkc56_Wj#McIj5XnEACr4+{3~_3W#tmMSa(<(yT_+(TL1%kb152o8 z2pc>BnwRDjq4-t9h^3!drW^Xfa_P4ij_@Rw+4M&d=e3svtGt*~E z+Gx7iBgGAqrJ(q)Fhb8;xoHWyFsIN8YN5|q5zxl`Uxb`nt6m%U45-b3(np1~q2~?P zsx6zMQ2V8{tg|=^>0UgFJuMaR1g;g)``YcQKI^;o2J0}BI9QoDy~q++jPxKsiyu|* zi?R<%K*ml*INotDD9>-pv5Wn1fg5weTN8&kOyJ?JNmY3{fBw=#GY`$1Jp0bapG)y) zW?YH%6YY8$5Lbp+VM5 zR<=Pk#e_thTC%7KVvLKLAZ_zZm5merTk=?@QuFF8%kHA?0LHwX63ITbyuD%nx%S6b zy@EnI{S{gp75DjA!?IdG*)MeAT(8_OJFfj@Z^V?#5;xmVBZO#7bjMYyM&Uy-*bI~rym!rA5Eey`A(S#~L0Nb~Hq zke7{oJI_E#k(W}IZ(&UMwV^cK0b{M}CZ-Vs|j$cq8Aj$A!?i9nm^f zS+TQYsa=2>@WTt6Vav_x_()-bq3#&x+meqKZW&M0qtfA)v zT=khSy*R&&y@s?*IyR-QvqR--^u9%A=;Q7 zIT9+;q7?sWW(%8nT2?__hP)QqUfX+aRE*`fT0^y2a2IEHaw(dht|s?&z>+1JB|7ku ztcS;0ll(?Gq#Tg{IPaq*kC4Rqf@36e6rOxg57{v#e@MRM_w_)I$*fHOQg825Y(JS} z@%E@{5^Im8tu<3Xz)hp|srM4y=*;~&lbKxE%=#~0GGoielJpO#7)8^kFgN{(I5YwA zSdK+1`S@h*2C>ICDO^MUf)ZpEa_rq+Yv0Yr&ieM7dA}JCa+_}t^W!n9iSvMc0?@sB+@r@nJ*{ql`;l zs&Y)2Xae$wER~ zvwFNwkAJDhztQ6t^!RN(KB33`%KK@(eNqo?J|(}Sw@>NuyL#+UmbFWFO*ZAFb_o ztii9r8ax}U<%wT|+qiP4v!k;MKLJ=ngJ_XlIq!iJ9@u-90@UIyY{3 z&BoXD?CyD~^ipYiPno}uQ^r8=ZzcQ)cI@FHr!qMzgFBKgh=)+ME1gK7Ms?@<;d>?M?nDAAf9b^2ho36MK_?gpWVDH~CY1{OP^P zpW)-r?oIw2AOGmyxu=Hs2c$-8{Kw>SAKeEi1VSh`6(Za`7=KL+TP^ne0;JudCCXi{uUpR`8WCa+k2CLi;sVMZ}RW(@ptwn|1KZ@-rnTj=i@)v zoBW4-{6~9}|Co>eWN-4H^6{VTP5yH}{)@fIf62#xwKw^%_kQ>{_x2|L&E6*m|E;Lz zZ~uY4z0uPb)8Y7dyj)HftK;Kgxf-vgm(#1&=G`r$~@o>GEpD)Ijk4B?m$e*7tSC^~d z(W7^V{dj(Vn7+JTOqWYu9G>kz=>Pt7@*3V3;k3>F?dl zJ|ABQ#MRtW&d!GC&kf-7=Z^#f|MA_`eAT`EXjqJA%jpm+2Z|3Di}@mEp1xd7uO`#U z-E+V3pd0GVEl5Vc3?y&t2IZh3=*|0v3ux11?pI={Ts5-(;~Q$Gg{J^bl?z!m8ytkCXcI-F0h zri<}vz8I#Lv(*wJ@b@FA3M?gcHoAY!)B~7i^6S~fbOdx$W_&VVBS9j2;iF=N+F{{AzI&Lx|%L7LHs0erG>%w(*@kj{|c3h)$(Yx`a{U0;PvHy{}+%-P-BA9 z(7oI(l6ttihb@zCmdwmj4i?kL3BrWcdv zZ7=Uj>hy0)1WEeEcf)}MUi|z1p~c^)?F~H}|LKj{gw30s&0w4Ib$os`>>rdt61@BS z+s{1Pc;?gXXDW`64_gB)Z%&q{iy6!~zuNxsVs?rS7>y1-nL^*7QsVsZXN%b-LS?!< zEOb6BZ;=@rWSBP`i4um`+E_+sl*r#qtPw_t?z2MKQxv+l)eko}s*k za)bfHKoytM%M(dCxM{R{0mYue=Wxt;SOO}0-n}CsAcnpiKU_}XBF2?eS*}8|U4R+z z?%lPj8&)@{r2D2ZXdCDPj2sz#c5|`PlR;Oa%IWy@1r!G;2m#ZQCqUkvE#{ZQ#q>;i zYgo+AU#!*`Hkb``0n%cMP+QJEpI+R8!fTY1CkY`T1zEU1W*8l44amb^NRW=pyx^ip zitz>q3HH@CqId;tQ zdL9gvQ@n0hlDiWE@VCy6Ut?c{bMR0_`EVeub>C{I?xDUKCUdA$mg@YJz1QN$XzlZh z`N{aAx8)NpEO1yicup?nr=LACc03?c!(!Hn{<2WPx?QJXcoCz_>hwCShhaDzehQl` zzJN7;*)fLz+7PY}Di$fQEv5k-j4kU18W>+JrsK(NKy7wr2@(gVV|2gPpk0+ED*=V{ zzCog-IaQbmTjcW@+>QuZTfAqLw3Sq5m@lV``2!CudCJgb0G^SNH66ogr`8IR7!p$x zY|zEcsVvF^1I;im0DFFgUWnH~BR1R)UJ@Cs@i;5Ez}mLGhiFDNzL+l4RJj_KzjqU? zaDp}W*%ULS=i^_3!2ofa#a_!`T5V-8hS<$wUz5Qql{YSeBdW$}8yai8wgqw9>*|@z z4{cG~d+=GzfeDoI@oHGUnBQDX!XE2{s{~J7fkjcBd5Kvq8Om7vpEyr*oQ{|1zT@Mk z2yi=w@ZN065TPYZmPpOQOqN_MXZe|hYNE;`6|9wKQ{)yUQ{gZeumIMIfY_}$ad=k& zf?xrGO*0%MCp)M=5 zZ4(&9qDmY9v*AE4k#jb(g~(XGwf>wn$rB69;pe~kNw>QX7>1C=(M#|wdrb-*0H*94 zwj5tHP|8ANjEDpA=*o}6N&R{H5*uiVt(J?azod!qV*p5EEHitD#}`C8mKd|xDIvBi z7RuO&3?zsRJ@!K|6qoM^5T3rc!MfApS6|EnITlsMNttRg-`b?!J7*Z{$O`nMV*0G( zE%pKOll2grR$mcL1%(!BcxCqh>K7GX9kxRG7KDT^DRfq+EnFm&jVa^(3w$Oi4gdFY zcz1ZK{Nc~Pn9mi@F`m^v@hC4J*h4}r@y(H5&wqSpc!T%<;_$@+$rA*~&j9y*Eama% zlG3~#U%e#?ek#U=-inLT6lmEK(f|1Rn*Rk!VSP0sWL6U0^$^yoAFYb#wF!EV= z=ZyFl|ijL~MYDzlfx zFoZR*dK6MPpDrZTZ5c4b6@iKsmU(?Yk#KJbZCstRNdjY{xE(t^TOC0GS2vgV zwzCB>sTqvSYf_NHW<`ZCqb~wiASO7++JNDub&}5(Q)m#=ax9C(YD7GwiGqY;qKK8I zFC*Cf;{%78B1Udu%McrHrqa?Y6$=*jF}f$5PNblB8BN6je~ox)!UX_WUSr=KcG8wy z*=Aiv$(VwhW3^&(^-Za=-kOrQ{zpLVLFzHL@ozQ z!qgY{i)?T_{4A-2QPOkSkW7`~s?69Wmw3HNri4H%IlY*H1xv7t8L&-PUreF<*DVFZ z5LeH@x66k(ZK}09QYT+%*TO z&+Mk*pDEU*IqLK4yjVsJn}smVDH7P}rR|r}XsfRj%P7bVI9NO35orKe=72bF*q*_KV?PZp*1QKcd8CwILuvFtu4m>u59_#2g0$Q^x z*n5UJjzB28u$U_L%wA7!7RCMSa~2AvUgKIK`{nxb$jHhmAm_cc?0~{Szj*xfCm%og ztB;1q7cBYaT*(}Hu|y~wbCovfRE01iL&r*J{`quqA+cFVE)ajVddN-ywu5!)1~{hD ze-Gi_TaM4B_l5%&Pf}y-)E&m|gW&}0?gShtdhrDl*eWh|;gUFFnRz&rIGkM_3hL1* zL9UD^SE#3xhhV$DYu1;mqp80I*@Ji4k;*5q9*pCLn)I-u5~$j_tpR1 zF#vQS#1m^Hx#8TGSQ|Z;L8v+bcw;k1dWuX__*SAAZI&FUYPh!qN@h6<+|S!HE#EP| zIZyuLU-Rp)o$P4u+5YeTXFZ8AeAS!|>|g$@3R=+fXQmVwAt306s{eE%`8)6K^Zfq9 z_&AJ@@8(B-emj5USM6T=j~Cy2FMfRIo%sB<`1qap_=-3FA*D6S2K1X$)J|-FZoz@A znFr()FJ_++GjrN>)V8f{EgnpocT&Muyg>->GYCI&6(Xr7kw%f>$Ph!!xJ5_HYXbCV zv(sWWNpG*qj}iN&f$inWw?~VHc^nYNz@g>JD04)Ilv6sIM^5zTY9amk6>eHV1r{2N zj97aNIq$?-s~|9bj*njs-+@&#h5#lOQ#q0(^Fj4UKfgQhh@U`^5Cfb|ZJknTFuNEN znJB>%B-rUnun>Z~7^bMPQ~ZgKubjqdz#ubKz@SKxA{Te80CBt|%&4sP=z0!gVgQG3 zW)h9xxR()fTaYVWQkfr>Y{VRL-;q$;f=fix z5%Gl3sWLPTt?kEAm3NG`B+z;_QF>e>*ko2w3K};H3fg;^YM;cOVg`+>nZ33Q4N|tF z!!_C*pJi6!RKXadwnc4!?tocG%ayWQ` zb+f#`D`9UA?UEag2il}zM(Lsz#ve$5LKy?Yu}c<@4*N+&MfgQu%omf)9be!MDJ{_% zF?y(`nt=*J9O*ldtF&n3oF{WiOHj{Np^{rnEsE_P6n)F5^!~_n1H_sw0PNrl3Vr04 z)p7K+7vy-w5x9M%uI4c$T>b{F*Vv;Nfj^; zl~Mm3%OcVy)V`ck`f@JgH8Q+wxg|riBA^rT;Ec`^J}(i%4wolW#BnM7QM8h3lR4z) zI-MoiGE9*duV#*3v`PaI!I`HG!#eBTVlsPY5j?d$d(dff9 z`K0)-R}e`sF>TTDNtRLFV0-Q$fO(+GO@&(@#IDu9JgL@tJ?Fd3*kfu^0*7GEzwg&D z)+mN{94ooc|MoV@FuleNd+FkkkR1@1GHs&9G8Gn*rV_Vlk>TE`;!iW)FN;$srqd$B z;g54OEd8n2kaI8X`j~RLM2Lh@$^J{6%q~my3h~2;P^SHgRv-`p`BOn6ADu`}(8=mn zTwpI8+JzX#fNI*#3YHtGx1XdPG-{f|xt|J0wMV+J-$4c+#dP|56!O53NX+te@nOxS z2$eBafF;1vp1yBv&riTWn5&*7&AiRGyu7-9VN=ESjh27B@JNAs`F|Y3An#MyF{d!o z+O%ZEGGSMl=5WVQ|zZ%on#`qV<#F~Q9M4^)3{HoWwy>PKE+^79b z+B}&O&-Kd24NYm?!mhC#4O3Rcbfmc-E?2iWqvjE6**hL5x35*K@%V$t-@Jy^J24|N z3ya=1Q6aq`#vT``b~kA{nIB0fOP9S3-U@V=_Z7-S%C}rCC0XL%!`*ECU^w(B-}i>KfS1*m@h{FzX!sBePH+%n>~XzBrCkeyR40U$^xxNJoXqz$cewhioI7p3^Q z6HFkZz@-&Q^y@Z)0HU-}GACl|33gRmuOeyJE7T{^i(AAWRR3cI8MkRcF)_{DF@904 zTA|q8>7PyqgD~?$?vlfLkYBa;p}?8Q4p?NIrf!C&g@z1uo!wk`T46GQC+hwaaZ7_F z#ihX8+MU-$;QRReUABoKSNz1)BU@ASLM07{BERmi9`I~bd>V==My*)cS{D`qD-%u% zDOE*askY%0;kBs3MNX6v*-6z9sNsG_RXau>>_CZRC~eLNkBiliB@3#@faAZ0!J+rt9tT&K@n36jD4$3CD7liT!RK?* zZnG;V!4wjtpk!y>%AlBi`HUlFP-C^7b~ zrc*`CU%}OP)0BA{@Sb1=s1%^C!`AhL~BKmhMO2j^ib zX2@Pr6Le^Q!PV!ggOyAE`3x762-FQnl1er+h!oqZoGCkl&h@n7u&DXNPn1ol)8S>> zVqRlgp(@MEI5+}ljXo}$A(%hN8n5}{?$p}X;NoJv7lx8;Yk) z`NQOq!&X9e7;j-86QCFqAA_Q(89AJP!I`uCaX8TE?VTu!ku0p`CKhmd1vfLmX!=5I zWjaj=d#xtyDRi!Vf^?&Pcqz;3W1DOx4NFv02GoOLUo%w_+=ms&&a>rN7gJ~x52u^} zltk7`s#Qrul`^;jmKPgv-?P{V6}ql-pyO(670lzLY0+y27ogan>)|XDcM}Z<##38M zV>1`N0c!6_8FDP-c?DSI!q>&d9wvh>=|?s=`D|6t=wMy+TEXSfwT!rJoZb1 zBS1Rxvur{jT9&>}E+NLQGB|xfn4%X2+SeMK>&Qfr=>5!Q5ay0-)IO8~vj=ashtmMk z34{|B3aOZ4F{22Qn96OH?kPe#F$5d0=G0g`s=B_I2x$P8KXGUsrLOpuPb{ZF`pml} zVUcRYQTr0ek$kG_BgE)@z;cW-PG_XU1t@)LIqC8(mJ*BJusd_H;4K6NWxG?#R+%TD zi|lNbV=g+X5FlNfTs_(-7Aa-f!sB?9>WSb3h=a$&C$>ed2dkTK@8vxzNNiPIfh2`g z561Vme^*dIzUl1hCR9s{bjbD(BFEUnjIN`|+Ip$8!+Hbsj?D@7V}Fy1Ikp*#C3Kg- zr8EYu9;VV7T}85oF;Z2)h=fO@UK+&Z#>E%U~6A(uuc36u7-g9R$19Dk%m(&hWG3GO% z#uV?ki0OkF=v+BSDRE^eY|RoB68%MZNN4y!ugzHIwlzcumGvr(Ht`r2jt2#X1YQSu zPzy3cQsZSrOA!=f$pi_y(1*j1A`>e(5ELoN#IqLS8J7thnoy!(tMDLjb(tj%LP8*H z6v6$7sdsW(0|#mjRt&h_w_p9Wfbs@wBOd!G$~q_&4#8AFdA!c<6$okc2gBol;FBAw z1~$;*jk9j=0xJkq0w#L8$Q9E;L1F%O@FTnbVDSFYrKxa<{dvmSG2Z4|fbc?|Kj&YU zi}~~CND~pEXsSsZErXTv8>x`#WJYEdM=sb>Qs?;iNBkz@;XMHpmP$t2IRX1 zfkH7mWVa?r;$h{m3V-%`u%uPH(F0b|5;WzpL}fA}}o|{1aB0`VcriP)@L|CTb*X3DrsJwC(j+EQJDbh^#76#Wnq# zBR{B4-o0x-5YLLt6U`_4w2h;ZFdMC#dS!DJ=q_qJ6Kr@q#gIUNs3hhzIKrYs{C#|E zdC|VTKa#4f(GXM)hS4ry#7C#(Rb{4V(<&GU$SbHf5MoSKWF$NCs^b>yw#&5%i+w(u zs2;8jLIh=eN`oJODK=qh<4Ao*VR>X0+FLeDvqH=ZOSQayh-)Z83h~UwQrY_T{XZJr zy-Wqs>f%IF1yqR+w?jgnuWkWi1VdfSSIg(mTX1qT`jMJC*ud)X$GfI<73pb@wt|mA z$Kz4s<_&XMsRe>G1%B4uU-iK0*eYo&$ZMWs)zN5Zho9Pm0x2g3l_VMQCRHmuWd zktIBhwGz_)4LVH#M+C1_vM-ya93GI#UFZhuximr&zICL8<`K(~6w@mwCj$e(;I^vOQoQwNDQY!diN4d_%>7#8#fW#exOq4s*PrA^7Ht z>G(6^TF;+H8Q|JBfj=I4VhR_vyZ6|eM{n}I+y$G{K4;N`u2WdJFp}2jSHw5;7>;GE z)5ecZ>UGNv%ca4`v`wu8x!sA_H%H-9TWH%Nf#d>Vg87upH6$`hqjRBMsHsi~gq4XC z#qe1YU=v6XWFDmuSwV9zYM>brUQaf1iuyg#?- zWcL^ail`gQ#KCsxNr46}`_sQ~|2M!tmz4eIN#nNzs7|+B$`_7peavg6?G(|ap@I1Y8 zivm-AD{F}rGe9M!sD3Dg`ZAg}wy0lb;a&z3FC*Ay|mxwbgr zo>g11KGAi#NnuQ0Slpm#jJ-IralIFyXHWHK6X+`SxIIP90}L zjCz5BqsH}uQ)DZ+O@QTKTWlvKECruRfjAi@ZeNqAJpqWsE;uqE30I;GB5-ELrjar1 z_+@H6Bd0@65yP;9CAwXVUhXnXWLE_(iNKbs?H519iJwRkIZ!26Kv78Th+xqY@J|mV zWFm=t$dM^b%6eXSt;!pCFaY?ypD}cH7YGPMmn~wJN(i}J?UBS$iyg$E;EV#zsz)lNi&UWj=Z6^zB!rfI=Iv*5BPgle#7*T}GW?i@z=%q-I69aZcMB`bhQ z_6xEe#@W{WmIYN53VSbGOB^4oz*lh{d0_;2Wauye;Vhk@aR}{jc+Bp~(F(Cujkdaq zu7aoInxo+-Bq6a)+$xDdO<*W=G3MI?LDGyEuOq2tf#Y;hph~ZI(+J_o%dLP`W)N&* z`-<$KISqJ>BN<BhU&?GM-0?H#k)rjX~vYT}?Q zlV|;cEC=~Ncvgl4Pm0r4&C;p`;@La$VUYN8Oi$(!=1p{zY-*|%i}z)(ad2(>X-OJ+ zg_JkT;c_##5QBV+i8&8{FHXzknawf^n$bn%RZd@|4K{M*B(3WDR9TXATs|D3J?SOM_2|@Y_$rbRU&NfVTe`?XlY~J8G!8uifz|hRS2+ z_?NXdffKa}2+Ed{AB6|UzYE%r~CifP~YyK7`HidDjI*pcl+PjFVna09+vN76OWG%@sAGr zWzVmu?aPIgvyH~44K+suaWlzVWyu71e+she-{DlJ2VgG*_b5{nwq}Lv^7N>-iBsS= z4rm@kXF7I6eq3v;5!t8uLJdA0sq#w@vVj~5MN^iLMoEZh%W?1tWMtF<-#rR6ifJl4 zl2fp8pisRTR&$b##3NW;j-KV*F?tPr(b);svCP4l25klcS5V25Ywajj;Kt1}sn>no&BYex>^lK{! z7t?8q!aDVP^TpY0L1Xc|QN`i$3vplWP2I8rOGAPfM{j)p+uu9-b8U< z-4Wu4MyV1%;n`+$d4+e%k!KZL(K+Yc;o#+WZ|@)8g0+K}-@aAlj)YLKQ$LgL-hf6u zzO^L8m6Oy;p{`?yolCz8V%j~q{Dib3t(8md*x|?u1^WKU`7eO6l z-DsU?ilFyCu-gBLZ=~=mJKcXXJam_# zXK!gskkln!D|EDc+T>c)p>zh2C*( zU$E9Gf#@qJHj`8BcS6@=2&Gk>5J(ZZVSTdBD&@b!GY5rScFTFnFQl3jRj+!|Th*+e zS6MrvRU1G>y}L9+*l`$E+R*DX!nDQDosD|JVEH$*eUd5GdHOy>m7-SQ+;ZW%R(PN`CyBJU9+d=y;SCL>>(RLL#txTV$u~mvC@6fV%tV^?pa!{zw;W1 z{`yaU?(|hOQ5}Bzb7;#f)`+JEP{k5!{=h2%e3j{1Q1;bp0E{X=b$GoGblccNTeKcD3;MOQ!O`@6$LSL{yjDw!Lw){IH`S(>R{?mw7uTl9Zekxi=)`io;88WXGc2+Ht znrKrMS>X=sUoWROlleo7TU~&r>i~6r+=URSPOQ^PG7X8FM+^~VlUqwa%IM54BYWEQ z_X1F9%K#nnq^$*njJian{oM zT=Q#IKVW6(MvCk$n-_z&seMqNFakAeGEA*>*)*LTwH?T{TFMQ_L2rWpd5>M#629~# zrqh-IPt6r*#D)mtK@$iGqp~}wJs%K#D(%x>n>4g*lOh75gWsIuwZXt{kSO`nB2C@5 z^-#-tn7CU0^!Guf8t=mknkg?aP=0D^T_e^M%VItrNR05WLa}T}Tmh+mq%savHVX~- zvZupOqDkqJ8=WwLSEH=tP(e;TSsUU{x*(K}z^4y)HkMSdVOrpe>FHQSl3&HR1#pnb z+0$w&>u06;KXxTT>ukC929ssE8tMa888slP{_}>LI!>mewYQIsj+B-Lw}MXw4?|)c zJmUurIDzUvS5aMnF6jQh_{G?Ma>IG@-I(6Oa?dJ-5|n|`aUC;ecd$Gw;K$rT$mN8_ zcPR_{CGmX)gqhxpzCOaWlK)>H&+#+}`BN1k8nqzfFPrp~R}Dn0n*pFfKgDj_nMm;` zCQ%iE8i>WOKENWvd5k+?>ZN{PHV8CCrL8VU*%UPJS3xDq(z9Z;N_&z}jXKjZ7In(q z(9=b;RxS*&kz*~vQP{;GU9~87vZy(0TwCchMvK+jnDccW>cZ+atxD<2r+mljxreWM z?>!S)<7fR+aJu}ve^7?je9j3bkWsya9qjD-PRtc*IahJtqU;#|Wpl;<+Mh4NzR_Q@ zZ|XDZDh#8S7wY%>{A<7dqF3rudPTCG&7=K~+7a_p_iPCPO3|pd9wx>1O2RuaXX0_9 zXKG*DFolau(jaQsgXi-_ld^eEruEe_p9J0&2Z)O~C$tUba#8MA73%Y%RaK${MZ*u- zxXvLQz|_`yBLh0e1JiwEY-z60ovP634j6<|5KQh18^r=N#g6Gevml4=`7^D@osK1z{TIm}!Qa>pw(nW&0WKvq9 znyGZmn(MygG*^$yowd}B^q!WaxDok)AVs;cw$`kr8`riF0J*>hd?|zw(YK;ym&4)9 zLm!jjvkj}+LfGlMA}ZJF;tp^9d>JSTMkGZdmL#oh434@1c0-29{~CY^=~5y8kl;Fa zQqwJYN(iihGccy!XPjwMwG?Y}e9Sh5muI|Mim>+EdR9vJ+?I_I=F3h-d*^JPoN7f# zqs)(@Ta75wr`r3nDZwBAwwaw>(3d7V2SpDXNk*P2b@tX`qwE@j9o~nGbfBoK zjnw;5RcP*t$VH!Bx-cPr-_51#tj_qw6A7WO~ znNJ-@5R0IJjwn)L2Q7g=bf)_5V)!tzPx8981AmarxNhyh`^T%2Wox2(%z7~nb}7Ee zptfW*L|AK4Jp^$@mCY50HKn0A`poTrV%C^#`5AYA=uZ))uD@3EI#xtVQYH$Mp$WP} z-_ddq`$e-LvFl1SoM^Jnn*qy2aS)mxDk>$?^P|tEQ!Z$bw4+Imt|Lqe%TCD+x$Y{% zQ>l^irXoQ=m%V-y<80`dRZyoX)YpXw3hce@9|U=J4+HM#@(XS7E@{y?sw4yjdRG_+ zdtTS_|B)s7A-OUvb&#lyw)>d&)?MTTO?9o|^cH$V=PI9}`4;C(*}!XEB&?$aK`EFO z!25bpeyhVag+|)lf^p_ewgV4mfKi&~ z>cl8pxE+=3pze5+o1aZvp*B2yX_kk|i{u~do^b$9i%@>X15{ftYoef>s#>#NQb zat{p*qvtT|r^9|+b-g}7zUOJ+tKgsK<(Z}L*)HwH+t=$;*13mxTnX|fl0W@>9AkYD zQNi|qUu}c76NKGwS8%`HRO`#yIZyfW>khc~oPdN{w)a4r)9@J=p|`*9AL_;I0N=Jq z$kL1D2a5DB{eVnOdsLn7`D$dA`4>gr~-5NK#AX zwkF#iIej%5Xu`sItEybbzBj@z(z$__inCKyoJ-#oKG-hO-R4N7{^DWEj2bw>imnb< z;Z(lMv$bN%`g01vJiw72@cOf%$cjMYH_4q+)3WiS@)?&1NS%$8S6L*;+u#%@Pn7|# zLQgSQQ(xrI%cG^p)-tMC{)JJyt%(V$X;!p>gs+B@c}w(5(#SnHf2JlEGP#K5$)w3_ z({T7vi4`_go%ahc6t~X%ZhBDW=+Xs!>Nzh8Ce_7D#m?F^6m0IcWOdh-BZ+gQo_6I#?v=rhXidQ20g!yO#wwvjXl(&G4v0}+)z#whIJEqdh@vY z;XJ2TV)+_E?BR%>RBD+mni!BJVL(!d5f2KC=pDU{Z6y+jR)Ce3fwfanL?+z@| zj&HR>k|JY*t4+)RcJM(w9XP4-;8aGK4(sU#AEiwIQ^=}=u;dhI%E;@!+%Y9r5$?|j zSc~+F1?33U7{YCk8SJwTtUG4lb1k{DBEn$Atg#->)~I4V_C%vcl7>LsI^-HUE?g4UWG=s!C^t_t1eTCt z78;|Nl5x$E@&|ij^~1SZBM1riHLl7d8o80ik*0(IY1}X!RfSWwSq+BN9judnm5158 zI3VgXKn^MDsulX*1%rerz2}fPCpwKYiUwhoC}{rdV@L%5qjjV-&S{4Am4n%)(zU!F+?5 z?zJUrwmC{1c-N{^4N`j9WO6tosp9Zv1Q19nrHr5;2JB?Bx_XhM)MSnUmO!C|pr%n> z8=&l3@<{bkaAmj`@pe!HIB;`gk^-bjuT$E6r$sgGu-?_^ttfQSNq!+?azi%k+h|229Mz(1< z;27Qg+^Y_v%?+assW*IcN7ATTr@W>Wp**T%N?TPuRhZH8O2OB)hqn!BWEB>iLIAM( zhtbv-gDY+##hNO=nhm)_!Ff+`Qsj>bt`y>k^LE&9Z>O|M9^Lf_LEbmGzzx@)mKZOe z@K51;9r|)phyp~S$x@gz9NxBfZ-2tOMNCmE!&OS0IOP<$-mp1rH~lBy>8-xHsR}l? zu?)w?;HUs%0~qgFha(|drVDeTzf}}5v4;PY9_WKn>>EJ=xlJ5TRt5dm?mG;LD5=)V za2TVci1+C0iG4WL1*1sUzoNmb>VL%i_lI-Br&$4B58@(qw@^CV z8{ccNtwH?;mzQSR_~t5ZAkhde0^7!Phvus%qOUCVS(m@ltgpXKA8 z(iZcpGsF-1F?q%g2P1W9j|X8 zC9DO(D%~g6@YUnGsV?c=Mn1>C2&ivxw;3M6BF&Z!)3-M70fjfOH~M^A;F=X6`>qJ~ zI}|t@Etct(`ly}SE9T)2(G`B6g}pU}7F*?sixuQ>ezajx?1V@~d$Ktd-K=wu%G{gS zjtq0uOcPq>?5)@-hk%@lGa1sd+%S1_Wn-~IXz)YYYTt^KNK+rW><+oRMzc)NFdD29 zhDdj!eZetkUUyVT%|V01U=E!$PHve`2N zr!dOsDXX*rw5%U7r+Bs%UmKzE_>h;BF&#l0LOD3Oh+ z5vQtmEiRvm15`wGaxq8HNs4Ins+)nJ#O_&8t03Yb$)>sqA_m~saN)wEY0^OKhIcOw z`~*g&>e5zQ5jw;&>J1k=GR-=<=J3ZOQ$`+tPQ#;g3rD z{f|of{kRSdK((OKfg`Fux&UFBSR#sZ0?{_mutn%EJaPl`*lm|epfCsuFCasNEnVHc zT_4_9Q{!Xp{7#b7f`unJ#gT((F1yfgH`cZZ52~apE4cY80uF^BYEaD^%ZQJJ5e-qH zqdX8pB{nWdvb?-wEp=mJ;Wj=apkWfJX&TA9SawLWxJfwu%-ZU`M7(Tyg3Wlt{o-Tw z)L|;mr9YO-Pr0gf^uBu2$e78i-PbFPGEa)g*?278uyYnaWw6C%Z8co_6k;i5K(3Uwf2hMTPXTGOBURE-wnHo+9 z)f|rp_K2HteA}y=3xp6XBWv|&Wl?zhV+Gd~oGl?`Z#Q}J29HR}hGaUuyybdr=M&Q2 z*?hjF`^%_lk{h%{Ff1Jiw;WFM!=Yb_2cxevT#ypcPg3w@gcV|`a#ePsTOj5)urn2} zLizeGKH0kQ_7K-Cl$+m2)0BuZ!kkpIupABgiV0Zn>&{}>`oz(2@LNk?FdN2I>}`6Z z;zb58Vx=cj#mSn46^80MMaoM~_24jS^H`RAgrZMmKE^89;mK@yI_8cS^26j?^pF=2 zc0=}Aq;!EUJx9Z{?|;h4v_O7t1|z`z^jS^YuPOYkoh=HkH7FAEq$d)c95<&fuhhES zR{TVrvQ=I{W1Gx zB5Gyfx5+Rvf&-q?$jI7LO{x?=UJIobVd+}IdE&2%P=dfYsc8c0f)f>vr74(cw#YRF zo>gGVtzO1KyJ(9#KYj~vgyk|J_Dxxjpz2yqb(PUtysLCa``zfr$GBJ;3t+Z}L$IM0 zVW)KrY@F~jkPc$k(o1g)dq+Xd(eS=;+Ca>8%e+C^HEfEHUti zw1`SsEyJnuL5F`y3Lz)sz+Tt{X@YYt-1?1ohpMwH8eb>HHA?Z@7$|6e8zb2Rv>iOD zkmY;6`5J1x*o{%+N(C zS0w_%^e!w`-$G_cUPtax6e3bDYE@4cpvsVGP+4(#9UKC>$cc_Y*$r>DNCNJA z_zeGNz7p3hhflGcpS|&^IlP|UmH5UVxE^!pnsry(tzH3ue!`G$&Ea52DOFyRvAJ0_ zlL>^l6B#i^-IneThq$AVtIq2X2B2V0sNGfl9y)+7!_3iHN$moofCFlgRxF8Aq{I7B z{iBA?66q>B-B;DAeCJ4eQ5>%vy1TuFkYeC;jBVF+GlG6?M-}VgJvT#IbugNS>oKTv zQgqQ6Xw^ndg#+GO66aB73cV@9caf1onUS!Y=E}5S=~^W5sFQMM)_ETr`U$j%zwlG6?@hvg28j_0+wxO^W)DtfQ| zX8ZY_eN~UY=l^||`V{>UAMfNx{PwMP_e}|s5o`bP!fc5h?F#fydB6N?e|AM-WVeag zkRgjOBXr=3{HK)pf);RFt2ZIt{>{{EzOMyoHeRp^objDWQj}uQmtgmHc<0^WOU5G3 zz8xM1!T*$4o(MJv`xP!gQ*@(0sp6Gv0`JV{g-|EjV>1>F0>FG)fIho@E3^Xn(^a7QGC98k?j3mps_Q|S2y1j(Djsb(5(A?PQGJM}Z@!u;)VOk zzx^VE_{9fkLkni3(=8esz-x#Vk{nwTZo$HnT8G`HGGuIsVz)YBFMB}SM~+P)8JM&! z5CdcNg=!MOpm*5#gCzyYCWX9L7OC^_m^6%fL2HtW5m)B9**f2&=WNp=E~cy1t#<0E z#5=pCjem!OBcA8@_*?JlpW2&>vbSw;!Ni;aBl62F&5j|wuiTLzw`x|g5Y+;2qgiEa zwV!m(50gX2iZ39}>7gze_|N=&$Di8ege~w*=$dKMP*iZ~3rb$%SY~<|`4{>h2*eyk-i2i(Pm~@t z*^*PJ>$?tw`ELohvpWrQ{1gBdZq!?9%0vy#a?}Lq!H9TrAEMO=nS(2~XspZ7Sdymo zZJn6Pb*DrMa_l+gnV}Do~>V)ZgNH`Yqu+}65Fr@#(V3nx=J_*zy ziJwC{>6)IT*zJ5bPFVx=FnLBy60 zhbPhB#iWrmBRVNY0H#K?oBhNsB;ZECsLx$YU();nfB2fy(0a7XkCY=$O+u*6urKIL zcOYS`L{qFl&7(dnT!#ng+duW zo`3nEbh-)p-HFs%UBVC$pdyGKNhSQ4v;{xXy=5igp&ZCJ?I09TpAPRZjKO>BQz#Au z9k%w)bl-C83m9U$yuZG0k^h!YCt@?aU`V3DS8N=RXDip-Cta=WDY3F2d^-H}X2rMQ zJse61gp`x^MGf+l!SN}xIpx1T0~op$i5+1K{j8nz%kGI`N#{V^4^7)YQ7$jWZnC8n zD~FseaHX#3++*vdey3uP2(O>MnCrAQnjG|_4isUq_z~u> zix~%rWWzF#j++(3*#5uH=4rF@3?aqqeyPaYZnVQCHmYQbt=_gpNCXWYTEY_~Lzsx8 zT^xE4o(>pBz~F`pyFrbW_z2o!T)NalkS?$p9LZ?|C=q8GNk^wph92ug0s$t=C}T@Q5hbxavMhU*5D{2!izeBxzS#Sn(3Rr}Sj&zyv(`#E9loDbMUwKH{7qqK!72#K}c@o;nO!IZdx4E^QSS zb$k7#wCg$ny$Xyd2u^5rKoW;*$~}O3K=Ho-^Dg3d^;u-#BT!%;khO3F+mL|+1aB3F6hQWE&4EkWOFpuy&scOIY{>@sCPQAkd^JwC1cCuY0jPIv z=?*Gm^_=CuRzjpBry@56@ElCb7g5HfKVn-WPJMj*u_VscaSQT^#%~JVj9>(s^Bjgm z_1D8_2@@0_8}x^A3u;V@L^`1wq&h0?YHexLQm_F=rKxu*aH(OTktZCW;LobSi!$SG zV_LA@M*l>pqbgGIp(2j}!7A~Z8U!yy7#bp|BAVF$ye7-pIezmdB1 zOG+VVQEMg=aUP`%Hr|(%G}k(}hWZ?xPp=f_S2E)AdJ`lf-nB!n^de`q6_3sslE!id z3$i3-OglMf3a&)*5s=w2U`bS^6vN162pM-8IVpinKZ_WR1x6(WtT+DMFwqW6=zw7{ zg%sy#eLSR0(66T)GLspW$EWiwh?3umk0WCsAl!=@7MsX0GCJe+Tf;mNrx})F_kh+ zNB7X|nwLLHh)0A2ye~*hhV1%nN!}F8_W&S<8l|ff46akggSJ-<1jeSZhDlM?q zYV6zw9`v5;@@`^KV`bdINB3q%)_V+cW|UY46Fgi_b?ig=!zAXm!Qi~D*OkQK8Yk-1 z)k$S0T7=LND8Hx5eg<|WKT>ta5x`?-PHMiv-U($T-hV#yg*_Y5qyjeD<_12i3`QNy@JO2Ah zc)ysw@(BpymA@nNUirHi^OX-MOovFj3qp8pxqQX%Sw-L&N%C=7sZw*x)#WNW6g>Ix z7eD^^$%o|D%D+B-^1+8so;Du&&hWv9`bMBs>h@rFjkJdEc&$vQ_xzd_m@&Yq_qQpe zYhTgu6?!Z|Htz<}m!2eMXtMPo zSVNSRx$uXOrbU<*xoLVw6vzw%yoH+5R4`@t()kP#A`#C2Uy)t8Jei$SFQ^6+j?mtl z;20rt&RIh+@;#Zw1X3?$6p~(1K#G|&+sqYo;UDRh6g(*$>cozp;5ijpSL{YfFl3qD z47NkFQecIgiMaR{<7VY#o&YB0sSdBHWDuH)QiK4v6(I?!Uv=dKIyL*>$fRgEY4=0F z+y2}AsFsf|iB4CD+G1xkTdT-~AR(ulXJ;zkC^a+d<(a0}{GWqie|mA(!$V}V`{$qW z_;R}6281#{X3vQvW8yF+T`m#kO`-+EQ3Q8e!dgPR)JX#m{eQ)Ao_OsBqZ+Xo0lGey zt0=`r3FLOKwL_ol)bPy)@+RwL86uGpwhb$}ji|4hy@=S+fga>2Vpy&+OA4KAQkeFp zye3gzB6kx=P5ur7zF($@-vDI%SOv3f=r#SN8r4zOsPgYNO{1t{oK||@NmP(mp{uPI z)<{d&Mc4*uHaw<=)Tf+Ws>|9+^q#gO2(M{~sP^^WUyuACtz8u5R9b;Y)(6Vk0;I#H zc2h`7uTkKr&cMx1{p=`UIpfa3}JoC%GEWVeccaZ%WfjR~(&X><`&Quu(q>Rj>f`Z~cM+snr z3UH>!wZHkLu6<#QQVI>&#?e|r6sxoGwgGoQ>}e%-v3qo`Olo$mj>fVk1YMWNDt8I6 z|D#=qZPEQlsZO04^PZ?q!gpw+m=!_-+z*wI)Hr_nW})y~e}KzC2fDpkUD_A%cQv6} zJe0TPKlUJ(b~suQ(JMnQsDf67)MQNN{zYkDq4}BB0rVI6Z*s^|IPk`d66}du`6G~A zb>#61b!kWilqtcl^AMBp9~)e_DI_W^6;?}$QDgJ}e@O|si>d`pmt5$g>KQo;`t7mW zQ`grUh?BJEYm_MAan6~x*FezIy1Obx4ho30P&D5aKOc~X$vx?4NyY%%*AB0?woVnU zHCmjNBA;#$(W|WA3DQS&Qz@i0>&xR0=q#UU2zRdvr$Ro^2L3O;u?KVb(s{L5591>6 zuvuhSU@w7;k^AJ4@4}Dup{JH=?W!9nfjy7D6(#l8W!A_iWH30?gC!sHOx%KT=?by#*Bj$0ZOT@(xamEF2AtXJ@*LDKHUCogZ=T+W!De(vEw=W zIbD6)om;&Bo$Zl!xF+jU@z=BcJi^hzpI4(c7l+>tH*!6R}em01VnwVd;i zY`!Hea-~!*(;--oj%3+stMZR_++;F~no-@}euSdkeqp3r(&u#a2irGk?B;Fw&W=5O^_NCIA9_nX|jX8j=wNq7d}`tDzPi z_x|=nYKsfgRSdxB)zd6>c|<~KWrqCCVOa=qm%^-o{Shj=;v|R4V4g6g0Yy!cljGHf z$6x)BqT*^AXXhf)S|d!i)cux-y^=UpJ6)wMS9C)lmQ>BX9?-{K(Ga2a@^lAlkwD;q z1+zJl*p3Cuk>lLG&MW2LVQtm%6A~MnJK9)*AnT{iX_)|&hP!bLOu^T_J{~`6b7+lnxc{oCZ`7A@f0Gg*nsf%ojv?`q`0=rj_1f#bso4 zJ6!$NmccVQht$}lhjMpi{XPi-7n{2u)#kZl6%bwEmkFcO;7Woi8c;dPTocD5L#y`Z z)n2_;7s0F0SFESbJGs@Zs|(w&L6wU~;TJK%(4K4$T2LuDDRodbvE zH$&5{ zvZxkLWsy{&r6_wWUqLH&-nQbiNs{{2XkG4W))Hxtot|;o@jJ`hzk#PnKiDc_Edspn8nKp57r57RC03KUi47^kBBz+(%Gzq8eLrVtTycuT zuK0$Vbr1*h8T^M&+KliH2f8%MEg6fyTkdgdu5QHnj*kxt&V7XHxv?iUU?a-faaW=3 z-%{O5klT7ec(=Dp3f0h;afu}hJ;Tn|5f!KaCTqaZzsa4lbf$njj=1~gYB@erUJ6e@ zG~-J?6G_be*aZ=p=z8Pm2SMa*YNZhrfW^a+g(ieDc5&aznW2N;2ZE((^R7TwU_}zo z4qm%xjbRX4!7~!zDRjg$;SkjH;8s|s$tx*+2{%tAsZuVq(UQ($>x)ck(mEKNswRr# zKP*DJs=9gM7E7~(+tVQ9cg;(pO?C)DCV zdJ&OPYs!+O)b+yMSgtlqLzb#!OD@THD~cUSUrnOkz5q5eWufhe5izH>p!tN2hUzHZ z0C=MP)cC@3yD-OaFHKhJ{RVU>C16TEpg*K!KP0e3> zp|?n+ZX9a6(k-wc1)}?;=!G3?tc4w!&%{mw)d9xZR+jPZMwiW@G9Cq0LaN+Er`XHu z8@w_{p{|krE^bMr+~YU*rTm&~b1w;|yi>VHlj@K5!07R$7CZDj#HLl|ibyXpiYOI; zYDyEh!=_0%v@JQjF-B_(1Zve~V-2(D)u>A)Mc>VqeNHxK8xBpA?$uFQM8`t2`a_i2 z55GI`M!NF}%{*8{Ms~|d2fiH z(Vx^$t+ghrKR7Da0v^Qi6dugDU=iRQDnl0O^?n--j5%pvv+ZM3(5!ztK`1R*g3$tR zy-|)+1+u$oUHjDieNJm_gj$h(6)@GgG;0-Z`!)+Kc89LY)S`!Z>Pza@x zQ}(TCk*SpbC!>v^3|VamLJc0)aOuQd)a1n|$R!0Y!n@Hm2sV#nh+^|~r%Pf*(pTDC zW{6P|hssmgAoDZ~T@n_e&C(310GNIi=5UN5WF%RIjxY7GM}w|fB))q+{E%2LjLh!+ zAhtf96w#Gz`DpaRS5ifzt3+T&6k+rVoGMSjPDn7Vz|~MG3K&OCA=Ua#u4W!=ueVd+VMl_XwG}mQyYt?$2ecsM+i7eDL^L)2Ioz(q6sr=Kzi5EMh51_5Usxlx^= z%*QO>Z-MN9JqOrEAJB|GDu;7gIqGt!?Wa1x5;F=DEqZ~3wFY%aDQ`Dz?n8Byx`jt$ zTa*Rv4%G!_YEgVFUzyd~ZI6;{d^y+DQwuMsfWr1i_lVwGd&>#b`am0Y|2Oujt-;cp zJa?nTXLsEV=$5dbmfCxvHK&fTV!C}m+4m0~%wyFcr)$?d%(~UrPoH47cInjIAMKa; z1+MLq_Bd9^7)nM zqygmn6^GoW?)$)7{~Qg+8q*jG%57YilS6A?+Y1MRz5eMF33-!a{W9LuYu%bz#{rC% zL+6!_+EVY_u2=420_2cYMon~7?zL`4t|Oz@oB5yzDFN)cz#xyjmBt*@svC zMK$>5_j(Tt(8g1d$`u01?KC^XlPRFB2^Q7rDioErou{b}s(E78#i^7h<58#p>w{O# zIMBiIu6?|#Noc6tu1P5K*<@iysSf?1G!N~_7A&G_nlrQuq&!J3J2D)qC8aj1_v$~_EKnigtU(P8s|*6?%~tTfPA z-wu&5MS582)MR8tuD2}o}GYKFUf@^TC)0bEMk3`oI4xSX;I~8AE8m}u{6V8 ztUfR_$pZi1ID13a*jlvw#+k#ONFI|LaUw*+a=C4z6g9K)9BePZhj)h@^x*8x1AW8& zE0L4!D@9iGYib`ppI&r#HgdCLJ=TpuaM}HINbG@bYQte8A3{HCTLOxgV`^XEACDq^ z;`{KbEX%v@&Es z^twM&2Zs?`Eo^Eo;`b0C>0p#n%sfwp1$21$!6t%Bg6ee)3{2Vm-Ue`SL9yg4U;7$I z;jZoZdYDAD>TyTmx>^8s&rsY6FGvH~mELDX4^;pnbnjRGj5|$ahq{nc`r^AG-I2&qQZ;RnZxBWAa;RE^84?&7!Kk7j zOJYN3gk0cSN(yov?V~eu6qBG#6|S<@Bk;}HhoIthDgYwnW>)@|Vq3{A{jl_f&79h2 zt&jj+UelFQ2`$SNi9W`+BFI=&C-3MzI1jajH(5MyLt8LXOl>6A=}bq-bd1E+1FHN8 zG49U38&WWeBb(3>Jj>_vtLNGEvHJ z?+(wZy_Vk{sns=&YakVMqM-CMVfu1D-?y;T0O{7|JDo=$+96m?U{3c2Tb-?S9P}ys z$cAg-HLU$U?=9)4)A z1bBHVE+@{pVr}cPSYlgHr{7tlA|39?_=$w|h~7ABR~2C;uV-TU(_BwOvM+&A@s(_X z6jc(EucfMO{hq=Rp*pu-9 zgG*@DGc0C7ad&TL1#82cgoHVuI~n(8*j@cFf9xkkkT6ewe12;P?KHO-===@Z=HFLa{jWA5YKjl-=>&s{p%p#u{IBs9v^oeJvN%_u1i=j(g)o@8q=EcYq8qD^m8gcYJGeQ!qCwAX5xLw88lCu^T(WN@Q$B_>I$ zG++oY;`UhBHmSMI8bJ4 zaL>Loouk(!@bP5(P88Eu78NNX^S&Y*9ck?d$H;vNY%)cfAn^vAfeYXfigwk_OgjTF z-`uS8&CNQL%5Hk@-`uQY6I*3Qn?V?9D9Oco3qz-1Q{D#eS!g3`J7<}{*7!0dPOVtp znCouQ`rGtvkb_^ngJN}VNd){CRdgXus>mw6v2eP-xmkx}Q{E_tX1=*ur|F>gH&xI# zH|ulqPS^5fWGYEbZtSjnzkQw@g0{+0GZrP|>C#Z~?MC?XRte!$ zyCMT6$h737j@mUCB3tz;K`YvSjoJlz)UZMNib!Jz6ddOK_JKI>k>^%QG`_FyQ_6R( zY>QOh@^mpfu`^W6_mT6aPM}vGOjj!EyuSP%$4g7n1+Q?zGTiORQ>IrkHXWJ$H1^E^7EQwOtb%YL7aiqe2{UxgcAAh8h1;3uAq=7?aP}x^r;!33ai`VBj z3z}-sO_LkH^Z>yrqCK?3!Kfj+vpU82`3TYC0MkZI?fT{tY3{-u8Ih7k*9dhN2)q-+$}56-AuvoW zTL#x6M4o}3sFvdFsfWl;n>EsSwgI<#(01WX+Pu zyA-mOlNPWl=#7G?8mcnRH3%agXRH>q@CD&KxS>JChLn1##`IbK#o>LQZjILJszTC| zG)jB_KwTKPO`7%tDsLgq>o8(8c~ERM?$(17`6)WzXn@>%om(nBeft`(4b+vIxmvHI zA*#^0xpqx)nc7qtD~Khx$kxv4Ef5e5c?c>2SF}Rb21RV-A&Iws#hF+IZ{9?Z@4G$0 z4q$La_)K>(F!BGVYFUwLu=x>bs3iW1E5`oHi>FRmQ zSKMi~Hl}jNT|qFA0cc`xWA~1@O(bHmA3oCn|?!t~dj%ga*0)l+GR?Q=e-KHtndWIu22Z zY191kxr~P7OiQxbO-QA1fpPl>84EQWnCHYO(*u<{s}NTWi8kH;Mi35O1@}~kg%i8B z{NPvE{m1p{9>H4L5!|u!^~_30xM+Q>Wuac%IJL32>rq2}nw?%OIMhAbH)uD+lF3On zfu($6K#&h53>xdh%C?lCPyfY$jc7+i5W*_qoW! z7bwMe*{{rG0_tPo2%CKNZH?z=Y8REALv#5jCuBfD9NXNQff1pYHRP_p@^vS2JHhNW zw7voZE%M3D>z~{l-AFGz53VoNt|iBm4eZ{HjTC{Lv9HL_ESI!fkzD2en_=9}mc&+T z3%Jx;VgMjCW+6k8E78=5G(}v&a4|h2l3#Ww4Uc=@zE@wN2qp}y^nFThg6e@UeS&EhS9PWeIVno=PcN3we5>K7 zVUH+b7}i!vAAt>>G7+JYl#pfZh{PdpimavMVyL{|LH%khZ-6Hi`$49e_2K1Srh+Wbc=_5fRY$vVR+47bLi*~fmsOG*JIZ@T6V`tR3TAhc{ z3G&v_m6iZjllWbT>sX4sPORb%D|^nW4M`I(5cR#d&Zu;ChA)E<{k1XNxQ1>!7@B z@nwwC9G3xlw?q~iLwy~pu%J$#V0a(+qP1U<3}U34UdTC~dq`(UaO zJ6+kl>oy|l<~V4leqC<2o|w6~eHe?8b)Lk?xfwvH+=}%HM;5e8LY0#qNXd1?$IeIq zw9yJmEo!28fOQ9QV#36RvOMdjS&G3}{7Iz;13O$x5>Lw|D4eEX41rESJ=E8B#|r_p z#RV!f%-tlL1t^fb%f%b@t}QocWD5yuV&{^aVjcejM20LU$T|@c0Ib0z9Z||ZD14f^ zaXk5ZWjrCk6H`)n!X%=j)J3?kejE;*faQIB&J_o2;7Vuf>DI*kbtwfkeNu`^2X!nx zyz-W^_i7jrN*`ISj-ZR#ghmRyl|x8=jSC=>@e5s1Kr{q6+9ZA;I88HjB6i2tn_E-J z)-uEjru3#cRuwT%dke(If<=@jZ~NT%c(;Vof)ximLGq^Lb`Ld6C2hzSF^8sQp`0$u zJ0k9)do_7WCz#g!%8Mf!OD&G2A|jm)LA9yYKT2OfFUez7Y{WTRUr%Ux)WL{{TU*8! z?8FtWS%B!eo8x2D-t>J5Dx^(^ZEo~KrYt#SsyqF_!DF^NO7@Ac1g0Q4Qv&8&hdN9z z+Vq6D&I;7v4&4enp-;uR)R*}^t{||wJ3dyBqg-UeiXr`W20nvVJ!Q~X4++xZAFrZ_ zY$oDCv4rW8aO;YxQd=cDHbsW&R$*UJRd?;arD4DztsO$$yD56wwf9>O-?i@r5^3|T zt#>~`S;eV=cJH{UDmj-GG=G{Q;gDM6Qtk#0M_QchVzO`Dmtm$sv>4I&Ch!7`QC4`+ zT5Vvf1FKLRg>YVuSW-J5YILn08x13o;?hl~b1jJ|Kl}hn@lbIAivp_2@hn2Rz750| zMooAAMT@Fu5LHZ0i!GM4YdK-RUt=7FOZ9Fp! zQxG0yBU(5JoF&riN!XFk)fs_)%K<&EYj$CLjL0^*J=&Mk#hhJ{1^R!{n{`(+2kv*1B$XM)jycb zIqq=#kc$jB2HO>Fa#Rzt9Ixy_U~)=!%4~{Z5RHm_$#tO_6^)(khEXzlpW74LkBwfGk&{LTmVnU^OKV^v5Y}Xd1Y{Wb#%e^5;_-leF|+TLQzn zBThuyY{#+$G|8&9_j%14AhD-l#ZE?Iq!5@>0H#|h0+?Wut!F#^=++yODuT-qljYkn zjJ^mS@I~Go+184xyy61RDG7k%47;-M7-jdSARXd|&84!M_mhI-{mKp4mhN6F7ww!2 zP<0w#|5huDQ#s((j)|r}v6vVno?%iXT%Pb#TQ-;%f>c^0>b<+fNx_=?>cllH?D4hK z4R~Q%O^u3<^K@D8zgsHG_|#1xM*+*vb-R0Ei^=?ym{95UA)zU(A0MBevg^>x4JRY? zt@0l6dY}9VmHYxrb@$AIu}~$eWat>f+nk8gxp0{|aTh2Sr~ufAbR|rIbnfi7T(xl$ z!ul87Vg?C48a{~A#d;oz#^q*828Bqv3=>$5q-4FuUao;1!-f$Mx+KkZr!eBmu~a7R zx7OWpNO+>A;9?jpeeL8e=b{2i>uz141j!(rf((}{fKmijI+p`0xmS;|X`&8)1H;f! zak60YjDow|m4f)#Hs=BYm{h7IBx6FY@D?Kkv(yd8q=eB!(4vE2F+!x#6kbSOQ~S28 zp|C_cq*BJ&pIE0QVh|s2EwG3g!n@4$g5Ze!1tN*q5AmL?!>@D`2Lv!O)P8WP-g+-? z;!YYpt#HFfreKzU5~S6Qdi!+xIlw48oKXkvVidiMPY@=QdJfz&F}u9EbX+F3NN$;e zTk$%veD}N720&nxqN{TBlM({9W1kV-!HvlJBd^tzNkS@krE4*ciA#UhuU=D-l~A}T zK8{4tT&)P6Xq#?r%n~5Ny7llZN{ufUSxjewj$v{Ke7^@0B%Z1p3t&n-afYJ6W}8Xw z5NKs%V~`iq3xp97=p{Z)h;NLn*dVYLfCLwX<<+`3@m$?e=hv&?T-&TdOUxQpPw;w4 z@OaY>AO8H%zAI*c3<%cj@ObZIa3_kIZfrRjA&?*tJ>a$;+jrc{y0CK5618w#q}*Eq zoJzjwg3RB$!C0hkFNjkNSwtj?+NXOP2QtPN`)H>!fF^Sbwc_>3zzE|6Dw2zQz)eDDc+%ouuc- z_mF@s7+5?`CVL8i8J5`*YQH1K|k zaRN%BJefuDqy`spw?}ItNK`BPt+=(elDI_s@;bPbtyIe$;aj7$ZliXB)7h+}af$2Y z$z0uNnLl*D6|H$NLg%IH6cqLH9bF|X5Y_cb-o3Zy7O5d);^jN<*55UEJ|fiBN8W9Z z^0myq8Kes{N+nUt-smEf&9uFHkQ*a?tPSGm< z4TEDvPcko$ILODPA>ec(1J$j=D}y12qFbO=UIXbx5eu&(ZLkoE$&C6-joo6@_0VIY4r`5F-Kyw8TNOl9H%9CjtV%BM6 z&z}?Xf04tAKy8aOO^QXJOpA#nG9|!#sCRU@fuaD{+?6bE$LS8^nc4mEpagb+Itd-U&P6s30CsYP9)oB>DB-ZpRf1%}sj^02T=>1~)+ghX#4 z?t@TmqEt;>ZE2<3E4wv?SfFm$6t~JA(l_*~e_;Zv6KmfIQ*reU@P#{Nfha2~81?yc z3nYKR3KV=a2J}KiCw0$d@;KtO>}!3yevxm7N5W}-mV*+gZCt&+eE z(MQCH29fC=yr*>ACsCDGge90bXT?Mh6|qpeOU5K-fw{tsIrbgVj2b4w!1c#>->tu5 zT;Up!?b+r39uA5$Qn#;+hDEn?hJ2NP;uYo4SA}C7- zD7x>g?ALPP&18a@UGB@nS#vczMi@(quS5XA_8r z5i|^|scm~LM{9UEDP4|REf^JE){w6z85+j18$!6yjc#054NU4XVjQ|4ppxn$Hg20% zi3FbWGWs%IXgalWvG|iY1%dp6I1Y)bNM#!?MYe`pE6oAWZGZjvSdUwq3Q>~rl{|`M zznos4$b~?=>0uz^PVy8ovOG&uauGRq0Ezlw<}XR!#-9uZgwPXt?<}dyXzW8YY3acm)J1Ic=9<; zi-U_&a0<^}&R!z%=t`u3P&Buwr7O_G1%JSs^F`d&+J+XMv)TUo61>63i~vEZ-@ zr>;x~)fLaxKKCSiR+bgg6h1Gff~#o}oXhv?6qpQO1wd#%&55U%$Zj$$U)LH^(^m?} z5 zvEIvst%QiHh0UK^n9<8?um*CvvTuv`I>y!-%*q-?P#WUK4Q=X77iPpFsC1kgijLR2 z8Y4n8kYFuUA_olr*TnAl7sq**#8vH&#)sW%Wy zpDXkilgVA|rV9z6Z41kt8Kas+#({vqN0@NaTyfD{!NFo8H!-_{S;0(fdN*urafCq3 zYl^QJ5nh;1-Wajc04#az!~eGBJEgis21RCR%ntir=twmSvie4|8*;PCAl9T}Cjr&e3b}7WO zi?My0+zpx7HTj{mXcD%dn?|~z(FIMlvZqdxU04kk3~ugVtK@@H@zSpDF<&`LXVPs# zAjM;h6UQ3D|LpO#UMUkXMJWPjV3hZ#^NJ(!pnfsK7}aKSP718FeTm|He&EVa6*pJ} zBYGSViBnc_A&&gOP~#msJSl|&aUu#*L=;4h>;PuPd}>+kB^xT zZ@u~O1fHt4tTZmwDm`PGZH(knl2ui5sIHyB{jdiP->87bc0hFEgyWK#j>5Tyiox_- zkZ=83R3nt!cC5FGXl5gO8x6N*7%^27_uVw#s&_>g^H#Im9 zM9>gbQEsjaYWsiLd$;8{uPo1RJUwI2q@yn;91h?3A`7w_V2VHiq)tU0x>+i5T6T%0 zDY0DLX0V7P0g@!{{OYs{`Qxd0M*r{ zi0QBpRU(l2efzNXI-hp7nbmeu9|@ZVMx%Z$zU)V(PJT@;cX?2PjTwO1alIq@!?1}m z<$t^mYM+dP1N0$?5E|;bJscq#y1=lsiv9pEPL5QX`Pu{A-_IwF@O5O%M>C)PCdSjO z0f@ZJ@d`MX=bcrSLLR_N{xdXrQ|!fngSTa*WAu_X$`BFJ))I0x_&j75>vYJBQTMdu z?yBV>v-#vHdHjE=8mT^EfAPQk7i97iM>u!{;wYu+9s{Jc@e9X7$gP@P{S!?*Gag!F z1u-~nLwFJ1^3FcZVW6{iI9aDus8Bd8r$V#*(5IJbPC#q~+QMAg?YQaIGJn`gd6 zhQtx+NkqnT>E2UFwpKLE;PQdO>nov1`l!N=xZ2w8lo+^8+DDvP2B7F7hPedzBxS<) z5a|>px&Vc)uL9F`W(}ASu)^jl)B_eeQZZowRE?jKnkBjgozQ0X_rDMd$kETUVgg+5 zh_a*D*hyusAljs#6Yke7P7xxZLnMnkQUQAd&1pr^7Y2#6}yHL zYI^UPDzoQ!znAufI?Kip)mj`^rLkNobFB;^uIzvzllqD#lt7vU$P!d#PIa(~j(oZv zDO?FtC_z-!ee#@EW=hVfk9lH;NwzlYiyd+Mt!tYuA^CXvVUX>|Tf5i(IP!guygx1S3#)90_^eJ06Lxiy26WW=MPCXKv!;1kr|VLM$F z6Wh!0UdSEUDS1%pZ7!xie^eE*v=`($q#SFqOgd9v814t+1;1aXpHq-@Q_EBvUFDRR z9`b8usI}X#qqHeliet`a*dcluoOH~AYiUU0P%q?;BZZ*?KX?vxL%~9MP}f!M;J@N2 zm;fhaG|+lgLqjsnC-&_jQX#WtzN`&z3Thm|1+P%1rk32fWPCMc>@v_;=BPNjn zZ~4c`r~?PQUJ+&_<}|`cmnvv(i>6KmnZ=VZPXv%tcL$>RKmgf+Pe(E%h(Ag8tJX&H zNxK5;>ufoC$;9xCzo$-1Y!7gpQ0=KJ?T336LvRdLiWa#(14X`rO&6Vs6KM4lrCq2z zRjjG)a1fX98)P5;6RL*g4qFST6c`ZDV`@C*V;EraC-9IZ)*(W>S9z?{En|#2Hp_&dS z5p3$pH*dB#Z`7+)Q?WoXCVkQ|tNKVxR9Nxic}(!}bhN0go7cM8w|RCnpt&>S$knNtvnv{Sf?Oe3kf-(Toc$pOGs9$6DmotDGoKqTbeaxQXE335dBAQ z#1BkF8Dy2Q(=i-7MpUbWcq|%_$_x)s?W1UFnVfWPZ4aqI;){jo%8XEjHNS5O3jsU9 zup|`r8H%@zD-!mk8z@zv3K83FoU?@F%~?00rSjFi)*!xuWY$ad%5m6 zwp!ytMP1WRAf4{Fu(DJpB^O<&S5~%KLR}`&6;82qTfSbI*TU)$3RWE|uyw43IKEvIrJ%MiP=2KebMzsoUr&H??j_ zb#SjU9!fti6~c8`&*oeO8)UP;cVB& z%g|;GQmG;fv;ji0Pfx``cgpYTrrU0jZWu1GKfMS;UQ;KMii$CO267k1!I$lf@9>Oo z6~@G&Yb8|HcDPTdi7d^NS-!9jAlx%ydj|dqH;WJ>z@YTii4v&eG$dV0ugiA1PcG=5 zj2fGFE7J>?Wzf0!-c&=`}1^`Y;U${G?F15D#pmAO4v`Mxe6< z>h|LNRhXnH;B*`W169VRJ4wb0hHWv?wG{xX`>w?jbRwjfjYttbR+Vy4lL}cFu5lZP z33)KgbbpWgRD|Cz=YnN0PUs+NZ(PA8x;Cqxd9R@_^UAXIphMRaAKl+P_&pKq)1BGo zgKH}+bHxhc3a&MfjAQ;jdL2tCQTbXy9nZc_zVTE?fQAnrrLqD3ud4(aD0on*oIH|k zZAv~Y{-?iaO^v880NI*$vffkY>3Op2V#Hr{o2W0PnoNFi2&oA@AsI{$2$L|ibmhE` z6`v!1tU>65#c_Rto0dE87>drPcc#Cd3(bXIXq_*(-#|D3YnB}bhGG34Gc=VR$M6Ob zgsDq0^a=GQt_*D}0_EF9opQ)6txqfhDN8O?-sTxs0O0DQ2?~hlL@SVCJf7(#k}QHp zsC`=#Ku8Eb5RpIa)p{$s^d!{TNNat8GfR!<>Dqjwhg}n38SaLH!CKoWoXW+C`w62=;pn+rt|5+pkW{8~1W?o~vS(b4yjgcv z0}KuxaIqAx&1U|vJALLplj-`8rOU5@TGqEskKJUOs#xw4e9tj~@D<9NovFo~vu=p7 z`w2V?IfY5~7{J*x60B7xrWIieK9_T~LJe71M@4)gs?j0`@Gej4&X36u6OlwlOQAf> zD5`f5?Y?V4uQv6-Na9Wp(=Gcr(T!*+FW{+A8m_ABQ0FrFu=Flh9XU%8QGfmyc-C3j z;(z;>(B?1V>TWHc>)w^9u~f_!SEcvJ=L`gek(Uj`eS_w~s*Msc(V~xou{yASkbMC`4}*3h@Y9!CPIBaIO_&1V;UD1i*krP zbay?esQco%^#PXLh18o%pfkPAf|z5tB~&$I=3QDQ-z4gZ3x~5!pS!JFw+Z}}wkmx| zwp9qNyLgk{kUvWW_yI%sR1kuXu_2!wPPS?FG+Q+9mu4!*#|Te}+NiY?jQnc{zSDwL z+^7!I`Ul>-Q!*;jdBjQKLC|{K@o2IE0&Q4*-Z*-)Ar($>iWc0n>tmn|p#WNg6X4-; zirK-*bn%Rb2)i0yCB6gdA>qPr8lh`#o*+(aq-n@Q* zLq+!y^L2iJBAFgJ{?wu3Vk>I3ON` z_s9)cSPY~b?rp^^`fYwT1;o>PgJt_%_{*UFZLX)$ z08mpeTM#=_Y-m}q>!48BHh|ZQ4tN!W8+9xu23K>wm){i>q52$_M8C06L2?lqK1`do z)*UerXWL0aw~xh03gdKTsVxhWhcHboFLx$x!kdh9yBO!<-~IDuua4`q*0R*Xrtzbi zy-fz^t0WNUL6H%-b|}0@PdY1CQoK_Vr8CBj<%25f-?pY3hg|Np{^9BBHOlvSd~wKy z$u%Gz5G*ZRSybOBSc4paJ_m~3aJvo5lSn_D@PuAd?|HIg`Hg*tGmrxW zja`c7x{`LOQ`O3~)Uw4aH81&;QO@GxEV!><)``1(go$-dkFe?qh3UR34L~YXY~M+%`KNiJU!?1!x^hS4{QucY=+2BTI3F zaDt;l##YiqQ{gcV$!L)j;A$p0EV*H;+;WnlwN!0r7N$D>zsx?cpFZ>j!8$~)JuA`r z#+3(I5{&|8fAy^NSo%ZwHaYF9Td?R;TInm+(stovZ!NZXME(yvKf>Hf>d*?hSG+7= zOc=|ue}KF{#O6JoO#KD}rFHr8?!@K0U0czCeT0_Bmr|p*r8!JuSZ7mUwWAzUT_J^x z)hh*4vBldpO~v08*Hos9E(0vdnBsjjD@g!}z5W&)Yl@hf;VM^}so`3Ub&8jPKAIbfbm#%!>byjx5@0EhATSJ!!Wj-T50X`dYOxXS4~Ir6G6#p?O{A4u z9rSv5nY#WC-UUb0Kg=yq%bq{q!um{cZuwHgU_@i;u%3KJhYcn04vs=H4>Mg)9vLu( zu|n>;#M#K%Uy~5)(Wu1j@V)TBL_sN2IUQpov|FVG;1pNr!dP&vKrR}MCL-y`dvOFv zf(INhh&mwX0q%QNT<5o9oBeJ@$)T%6{775S4a$0_Cx?O~CQy@GnnlkgK099D0<>yD zA^V#bGl5b;Y$W#S3uxgp4i~gWpOcwknd}q_(G)mF)bJ7iaa5`LDutP$`3AIryGZLq zi+=toc}9-oHi8I3i1L6Z*;33=6jsF?)EHE>K`Kd7LvU|hiyShM!yY+FHGd3}o3F8M z>6jh%XnsTUo3#%MjYn-p1&YH{-MVSTI>AygQ>7Q(B^2wh{deV=Yyr{{nf@ITnD+sHtWV49|9HG<3dE9u zxJQD7^@2~P{xlyOu6~9Gigi||ORC8pPdoualT*SD;if$2jv4?K+;}dJ9M6NS63ltI zuIh>8P+)X>K2nMY@}OYJ6h&!=4QmM}leYL+hPN>+BJ7k;e|5)Pv?g(-M~>i~W{I&S z6fgTSWlW)56Gw0d5QwN62_{NQ^EO~y#19vDGa3Y+tqMEWVqFc>oh+MsWhze8%_?+$ zFbSCC(SZV5u@5;UNZut#-ze~o&dHvNnbggn6Dxz~h@3)0hfjxehK9w2_V*oJ=qWmU z4k9IHv}yVCpQFWEvCPZCevPAF#qKO#+86b+;X8#9Zd(%%xN zp+!0BGQV>v7|@g{^Md@SzEau#~&HaE3Kg#_A5?5=Y$M++FCk`AXabxvh%K_pcGFi^T+ zs|`>?*1Dp^jSqtT&HEdRiMnZ0Gp0ipy#u=;Pv6M~#8BDl;4U`v2I zXH=`5&ZzU0@{a{a3|12?W_D``V>}JDK)=Olar(7=dY{i95BYZOmGVKtgckqfU)cwl zuIO-)EUUW{3@IXt_!@LhnQk=sXypgY;yEqJn5;F0q9{Y#-+13pUxtQ7I&#yuF$YgD zo-O4?rQ;`WQ_AF@l=bO%pb!Lw!!ydlGhNSektE-WZa6wmLyUt|#JH6;2RS;SN3f%@ z4Snq^mGe_U%JQ%Peei?pVf}4f3OjAimQ-R#EAq5ffND-n3iP1PG@oN)uSb^7pk8VW+5w)Vp#gLkx3y8$#>hI5ce&We^F1oQjU( z4^F<-Rc5!z6%yqpnV>w!-EV4)4MY&Z?&BpjCd4t9bD^_|?M6B%gcXH`Ek{k3pYti% zlKK%1vuYCgT0tDE>^kLP#m#V%FM*y6kZ$Bg%e@c9+7>{%IUm$kpqCXH9>dPUzwNakZa>z75!!F?AK*){5vi*Ktqun$P! z6~E+|@9}G_1UTul@%A(OJx5Nb4pSvkhjQ+39sOycfY??(7QuqpnvNq<_7|j905jm- zAez1OtXCaA4NpxGhtE!Y1oGBe_Pv%RXRxH@5o~lhRc>vcb#Dxxo4amklj6mZ_v-I%Sn*i z&X{kJ$@5O$)s~VnYN<&ZgGyYo)<+o;)VAjsBz35C$5l&%@Ys}sSER-_9vQbiwptE$GdN(57 zY|qgXyoK|6PeY& z6py-UGS%X&dsZ8q)CF>a?`Yj@l>=aJx@S&!2QPuQbIT4$p~#pS!Y$!EEzYGGvlkQ( zv#a81WH?sB6p&~ZA(4cjD+#cAHjcn*4W09W4l1uF;@4y~5Py3*5H!?+#{G)Aigk-GDbctw!6Q>Cq@ToLx zjwNUQ8ay$mr=n``O_{mAPQtpb79~*Fkc5{|@FOVzqIhoER5pFeK^PQGBLm+8V~V!a zjmzSfAk5Nk5O^OtFP&D| zx9ucWUFc#c$PdaDh72+!2-Y(x^h--`wzrii05If2nWKJSyF!`;+F<44Igb#MRSilO(g4P4M>{u6qxl+~4?K^s2|>ijz38EzcQ>8Bi0ghj;VRRAVC({v zFu$2xwI1}0(8Joo22KlE9Uo8NqAm1f8q6nkGA6$`4s>fLS*k3jN-3JiPhUugio`HE zDajwO`rweby4>MkF0(KBcdcs@b7j$acSW1VpRmUO8Snr6U;z-iQcTKGc-t=_%|sE0K4~^)n(=(Uli57+#=WkGKx*RX3(k zc|csp@tC&Y{dHgp&m$*|jkHpOrc6GOX!MgtsPwTG3(ivawi30DT`39)ArdrQ zoC`W^=PYGJX?hNWwHBWCT&tIpUPJtLZ53h+$^7O`%~eZxfb@hU+q{{0)jbz(RnC%T z%5=TlTx^n^Xs*TMGT9=nE@$wxbqdwd0cPL|XGvI3*X<-}e`&%Jw?LF4WKgU7J{F$w z9vKI=0075X-3i?}PW5Ho_d|4L&P|8XFqjn*b;$;J(a-@bn$12*F52v@Fz?}IGMMlp z|AwjBi3-WjPt{{+d5P7CIHr*^m9rUp@MBE2=OHJm)HW%13Bk@Ck%>5*(}Z3_jt@d}?{yITz`9QT3`NC)2urw`?&5iImmsKwIk-jBMLMZLnoi&??$D3-Cr4KTt z0PCkqRu>;zNg9vggvFFWjH)iv3BjUQWK;0H@#C;O?)5C~q26Izw^!nQ;-p|s;Hc}& z2dQV>P8uuN&qGS(B1{+!0B}j)vwhL&CSm9pJeg1{6~dZta5c*<=WOrTG8zs(=`>85 zPDdlB1;1E;ykSwts!F=}MKJv?!eMZ+qW?)Uv|jzOCPRL4N9!D-8&wvBc3X86Kh|WNo$LA~rL6pX6e zFVq@B64~?xW9RvN+IsR-;RA4{-p`4|=?91eTXaoXJSP`UujZ>^p60Sr>HtQKhUmW) zn;g=5jM$^LJg^9zE{Qf#B^WDX!n!XyqIA7`FYg$LrESf3zS^1ZV5-gHbMA7T;kk?` zO3Qhc4-F1FtA zy0PO%SfgS579RC@;@fV>Yi&MFRZs9MKbq>`=;_hy0& zy7B48HHhym|GvHPpx$w{URV+woaXjblCo~wSWynb`5GF-sRj5fEGLRbaEzqSo<8Qf z%o+$escKv+AWDyfT=(Z$Spt; zyQob|wR<#Ako>d#ecsV4k?85bA~QK7NXWgk_QE(tdd42`?WjHF@OP$PD!(q*W#j&m zQ6gvQ=FZ;R0=#!Lo$l=J?)guawX0wB{o(eWf8RaajY`RYJ^P@r_;DiyH9eKbG1IUh zVKt@ufPY^+qoX_(E&}!b{x%o)i~>Y<%QnU;M-gFsXGRNVTraOCd5&IUFY-Ph)>-rA zBtgQbx(#S@{;v=Vwcmw^*xavDG@8ek@Wh&*V3jKm>pWo{jy9X-$?{gC5%cWU{)*!w zL#FzvwE};DVC4%Z7@eSa@eDA~>R!JDw;cMOy3Qt!1>bmAE687?UY661akXGbvev7^ zx#T*$`dQb_;~t=eTJTi6DpiZpMh97<%hk;1Gv;RQ>)?y{9w}pWtEQ`T12D4Zp{;bu z%fYV`WDebv1cY>C^3c_^UU&kq>Rgw44F1T z4pB zc^6TtCF=bG@|_=pBWB8E&7xSK8B*vvIXKQMK>prw5!KqO-@&&p?nE=9yB1n6M0 z72v&U$7r_M7-r=CaB#_ewB(#oVP4oZ?XN?iPOH)}xb<*wwP{j~)F{@RBGa+D{OBMW z78BGF2paTRZUZo zgTt34XMk$e(P@T&ptd_dX2S>M$RCPoLRKjQ)?x)6Yq3WBL!L~)?Q$6jnwbuE>F zkWPWR{gh_TI^5ARNHFAuns+*XO6}0FQ^)!H+ki}Q4C2g6;aTOqonUL~((0#zE>xO{ z9P>Y%s-jl}OJSIp?p%;WT%7tQH%bo_=Jpr5E@tQt{PnX_^pn~Yd7mP!?CUM*`%>I& ze*e~kmfsG_J>laIr@NFR?L?<(E})H8!Mw8gFaMp)CK5$h-)tI0xevI(eGd^!i^HTDoM=qo<1yx3HVk?G%g0k2@jN}i(J$xw8<-}5VPW3^pLM{^ z$F#5y2Y*K*j~RPq4os=ZH+9XLrq7^EE- z98@u%>RyhzCv_Iv8Yor$0BKj2&&m>l8L>!}t%dJte}D5QoBO&f7CTs#CuVcTXfF9M z#mmATjl=n=F*L8<;#J7~p3|BFQYf)7mlOO5zQsIGu{Bxjw`=%8yrb?xvpdP<-D_J7 zkG0s(QA4+X3A4GNtI`bFVwY1A{^-ymL6P%#3ZU~?sV6M@$x~%Z)uCpRUKDuzTqW#k z_Zlqh=p22K-PoCG6}K;%!L{JB5!5aQ$AeLK>LJSV%^YpzRk4(VnybAXlL}GO9|A+H zW!rg6Raq~D>{m*C^!h|S_8^Es>M{_mqmVh)x?#@I%w)PH*8h9VL}>N-VH8C2Y=U7i ztr1o20sKPA7-toBxE(}dBY9`?^K7ToK^s78zJGs#=L(!~3np0;;q}#5*}WgBdzy*h zpisLnwo6QP9|hm36y#i@7(CqD1ragTkqw)-wjc1vH6J|ySpr)4$GQckr0IwX@})++ zdC*f8ROJIa(DyV9ZU|0u7E27S^oYA{|jMcsLe|s`nKg5o_Fs4;fkdW?Wkh)vWD|kvGE(crENR zUbp-evTOrhlhzuCC?QMv=DX=P-)SKttfkH)o8Rp6?Vi3CvCFCGrbfjvQ^{eYz7!`# z^Tr)+Y(VLdmPJY}>K1GV+eXZm0XL>^On*Jpc!URG&C(^YHh%7cE9RZE%8e8z-9K+k zKO+q|J4JWdnL4biN4}%@ADh>r){p!phb_HhBOV15dUh|airD!46{I0|191CBxUw|J zXp_lKhGW?@c6p1xJ=A@T;sAtI7;AUuYkyMXy)oU44>mhIMg*&qA)pB|n)7QatJ zDEOU1B|8|~D*02_79Gp)PakQ@;Q@wd^7udz*>p50?>e5!OWV^5Nb#HRR95@no_?(a zRQMCDRG8`r6fQm;5WqN!i={Y1#>C>ub@O+x0O-7%yLOVTq@{feq|*AkbluS=5CK2e zMV7v`TrX&=UZSpgsUZtG%Cpl$%UcWxRfArO41o}z%Tt`}Y~<0a=op}5p?T79D#Quq zn1Ql^($+-ZXzf=N)!O{YLS!DMfEJ+G12|#>i-T(m4vj)DoGrb;C};tGqxiuR>HjSq zQ;rWTeCh5g2l+Rm4cZnZYnlxxne|lvq7(48jiGhpvVYv&L$}6?Uz34QK1H36%p-r;xL@#`oS7P z0qn835|N>=1_?>K0Z(BmQYi1CW38^P)D$60w@s5EzJmpFo94b)z|Av+Y2d>P9leAn zRNanE)7i`8$-{7ocYNTWr%Kcn_71+4Z6A3WVh>Dah|tTmu2RX1N}K+z6$hKFuXw9m z7hjHOVx+)#DXuFWee#3JWaEyvSu0AwVmQN`?Apw8T?5lRLM*X-W=RRuzLO$Es3=V| z&pzO;lpvcpy+*1NH$5yMeA#=S-1d-zEk!$0rm`JN%S~lAz&JE}u?rgVGtVq{cM)zL zRCu#>L9yZj!(v@a6wizyBfcKT+2g@_GHoGW^Qa+TAdJkYK8ZQ1G&7+uc9d=}OUD$V zxn^;b8bYTe3c>;A=AvPO3Y*fnvA~ZIQ8d}${+HIY%A1idQu?nGFKWvH{jL4|jSVUJ zv_H~~KNRmUvSZ>IB7}`%hs8yjx>tqUDb#;*ouopAx5YYHHxqnKDHKpf`t5_9VivHS z!>^mvOute}Fr!;^uhyMpb*45>EielXn2N)fbDyq1#}CZ!AKX{K`@#J;9-wXAw! zCgho!`Vp_D8%yYhr%2PZ)$x1hMABE5MBQ5(k31`lYZ>^!|2_17KlOjPUxLr?_`gs6 z-+$}>p7_6~{x6*wEOXv^;e_Fy?0$>+`wz9#kJjuo74MXVNMD?)&}vR-gXXx{S*dd(Lg8odKw$3+)f5sn2{c4$*Fr{8^N(NH8d29caN# zgyPNS9P@MMIao_L!l8zaYMI8D6Z0l{t_xA3>y!JG2?vd5tUz9nRCY+-l}rsiuOZe5 zh1}U$cP)kwAcd!VGURM{50#-BnotkP{`c<(%I>Lu8dBq}!fn|dDApDn(siBXSnUHi zPg^-6OI;WyKRNLRS{!n)>u~#PE{@iBCtNh==aPGV4|M;bsCfGyv{Q2^bD`S7B~+Xn z%aj?=(|DforbmaQA03^ZtrZ#pw;sp(-#bkDe!nKZh1%!E+Lj!hsj@6YO7YOpb;O5@ zhol|rx--q41|3oSN&XpLFX`yKdG$g6xz9AyUpL>-nO;i$X$&Ogw-cqy1F5&yC(e#` zvfMK~2Ia=;(+1M&wt`;jx(*on5W|W`(WN3R#nVrYUWRRnma_YZ#VLtvbNAH0K|A{6 zrT);Rhgf0Rv_5oQzP#S;N022C-}ofW+_qfQIS4P|qXZ)s_}bJTN4@9HPtSJTbvt|L zL7ct-p?ynNOvVv@GS!KuDsw3}8sSY_M;RD~&t4Xux$P$OIaL!xnhtn zEaeN^Sv6fPEJPi?`nhi{n_}5-Dwua|uwdznCT|EZ=XkaQz`EgVyVSCEnv4Bku!eCk z$^m}tyKZpKIH$CRE{{XljS`DQi{*leXQUaH5ajg2^ST7uAlTvp+N>N*w2ag3=9Do& zz3w}tJC^biUa)siCF_VHI3Gw?S?C$Dx93jrbUAQS1JV|r2)pD5=Jz}NZZb=i)4~0w zujV9^*G*#may-dXO%hb~Zw-z+{Go7vZd~9B`iX<>MVwq&FFXClTFN%Cnne0~-m}^O z)@*Qv@q^w&BGwIKF-60$d!XBFd@!8{)}~WozF{cm(;XO7iz&^tdUfqp&WIYFH#a^v zDkGhJatib$?b=DISqFO#|B?Q%989h zu?gt|i~tRE=4Xv2FRv&kG2Dp}AoxE2{c}r3Ef7Z!>aBmim8U=SaI`UqQ4shZN?5#X zPerGF{3G=fOYH$Y3;%z_&+xi%I#L+`{kPMfTSrNrw=?~fa~Xq|HLlJbfr#@P%cuE+ zU=(Y6Tx&xih=j?V=_e5!j)m2EMuY)jdnP4EH~zwe;%5!*a3O&E5;g`~o{923EblLe z5}5wX_^Ba9BL}t9Uu0-?2#`-*{Gfgta%0Pu%en>1Um z?Qcm}{~jybdsiB%utQYvn3Z6=5=?m7o;EGq5a3ArMgsiw-P7|@V#53D;=9bpv^xQP=&iW3$t zz&;|S&z3;fZ_p>YcC=)P&CnS%YI!xU{P{sJkz!lo~ zCQfBEduYd`QOm4pvtY+$$&Utms@zKGLO^|7!=CuCCU0v=1zEFVX?#n=X`N*Yg|beX z?BV|}6=0Aq@xOM#m+h2|m;;PA;uUY_%6V3m0SY4%i+c)gyeK9isgK2X`3DHw*Ecx>e^Fw$tgr(C@Gia0USobGp+q= zccnK3hYP}5cc%82*N~i=Un+%$wYKlqz)g^d9i7Zi6is1O1A9{6=@vohI+3|Bjp#@P2>r&D-sy@Ra( zz4M`czh8&69(lHP$Sa(@6Ex=bsWvP~?V;?QUAq>>ipLtb1&S5%MXCAe>69x$o>I=Q z-6{{={WYxKx#dor!@AKDseGz;=XWD7R;I2JZacBBDX@y4=C1p6J?5kJwSK9TNXZXmKfonOr#km7&5)apse_T(I8bMP! zD#e^uCK|r{AQ*Cmi7t$2ldnVB?z2Dl+FHVT<*+Yjrz=zpORFA-iZ>w|2rXv4ns}C2 zCfDO8jI)m4$D}4yq);ws&8rMRKS^;5eEUty*dX+_PWdJ%gba)r?iz{~P8`}?=xbTaj^?ORo{2aK?GZqXt2H+OID z+_0jN2|bAIlf^OlE2{CAhvA!Bek2S1#L(7&L~TVgCtSHIUneftrI49FPMQ*Nz>{i4 z6vDSb99Z4v9%TAW;k>B2AC)zwfIU44Pr=6@e>_$7;dK?<@t+&tZC2v!=6v(|6z4zx zdAxZ|UhT~}J#M%nZc~56n|jCpzvMMlBHh?|@2$vmUq8l;Hv8_Cvp@Fi^KSOFZ_YO7 zk63Wf!yB|?wUt&Y0;9k2i<-Ii#|U^vVVJn$O>NH@{c-0P|`ppj6% zBqIQ(ZVvNN2 zS!H|bqs{HTy?1ur-}`MI-)Q7`{`#~%Q-}Ik^K*aZH=8y1=B?>4{AL?pAGf!^tJgP2 zv%GHoGivjhF3@ZA=IZ*^VRToknF-dy%f~GL=Jq?kuQhFLiqyns==WIag=%i$7ve9_ zXH%HzQR7<^&s8C+Kfaq9<5cSn1*8T|aT(R~YL=(whk8_>e7CcCt;pwb>}k!!TUweg zK)!tLn>!)G#KM;5+J0wecc&3SG-de$C*}E8WISJU&loQk8o=c=eMq;AqjQQoburQP z>C5ZWSL267E55Xdul(;T0I0_V!0|}LopYeoA@Y9s%~;JhF`^JR#{BMDqbPmwk^W;K zF+-gc!*9jwZ_`7HYg$=Aj^_{7QxQZ+?RJjN}%aOL65zRP)p1^cxB(KgcS~ ztTNDtRB9HUY?9r0z9;UYUv31ct{*HPT^Y|WQrK}@#T;6uu*Mg#YoU=N_R4|)!AHsD zuxJF*hc|mp=YF=CkDpwl|44{3{%MHFP#=$ma>9EQMI6F5eUjsM`D^@8VF6?PZZuXU zGp`O)-*hAQOPXCajsz28oqNgcrWzEoiw2TvPrJecawtq?VnDU2F zWpn~E$VUh8))O$~n_K+T$U}`l;mrC6IrfHeN};PrWcC8z(wE9={~(^zul>fSF)IID zJ!+NYz={UjJ5*`)Ih$^}E9n&zZO26XbM-{dbQEGniYE6+SD=p5jxiX*Q?A|Gm)zS+HXAm%}C zrvG@UKSIqTNSw`C$WNx|q*jzP2|;i+f|Vx;I|Gyxo_>0(Vb`CGI||MNWQW?NVnN8KCx^ zw**imNhW}f(Ea*=Cwn(;zWvU-@4f%C-2l+ubw0SxC)fE18v8VRmr8{#D-6qT7|#By z1+r@IXFKl{(9Vhd9P`-?-v(~J|B13b9;;SzK}cV0`PR;jH;0A9I6w89v6PiJ-hY4R z-M8OlQMqYS%C#7H;?lS&d2w_Wp;1~MsWhwlY^Q$Ny1}VmpT2i}3fb@7 z;Q#L+x8C)!Q~8aIvFGZcSNc#{X~WvZ3@iljk7&h&rY8yL^duQ{x4!WV-+iMOz8j#<6j)Jw_L2T0Ll}MFBmeiB+CVmK z&m-jr`bR(SEd3WoP+z_4uZI8b?d{fA@A<3Yzk7S_t@r(v|EsRo_-)!-Kl4}q?;c&U z`KsQE{@D0c`PsXnui9LClAoXJKYKU*)!yX%FV&~o$-tR3x%i*|jd~^0oX@7ei-+t5 zSl?e>4Hl{fUHY_?X?0-nuQ;FPQY6mQ&WnuL?%wq5gr>}MlHp^n**&;rD}8o0=d&YX zVO**EYQ}L3Xn5!8A1SASe^e%%AJOJmJc-qqpoxYYz;=Zu||s z;ZKz#9WD0mZ)|N$@0YtEI$irh23q%BqbK~`Pk;N%&+dMzMds8oR!q0SQfTZk1?V0c(Nv?-tFDW*c3P zKi@dPXQL0RL14XA|58moez1_d9>{;c6>s*Hywse6;`?Fo2!L#kdc+a)wbx)0Y7V30rXwJ5d)F-#@mCJ|#3tAlrxEGBN#0O0c|5bIW)Ilx1_jmBbxkp zdvTF!v=XSp=#MVAtr@QmQJrEO-S#!xz?+6T)F}uBvvZD|J4YvfIQQ>LYVMs8Tudy$zXafmRd*ASA(J>1P&RB&*uVU`v9f2?bpbQVaf@Cwp70+pOhpo>=4MP<_H%*KWZD7K@3xQ+6T7^V1SD zOV2^}+7-%C4!ZT^#+E+84Kr~rT#pjN_3*RCYZkKz{KsmkydJ)q;r{*zOKmpb3EeYC zz+#z;IZY{`AEysUo~U)iz{{d1&w}2tnK9C4juYmd@_faI7UPdnz9;Hy=#G6ew~ZMJ zB*Ft2Sfo6|*1#*P)7n&<3n8x;)=;DCL&RZI5{A7}l8?|tQtHX&*~JQ<4x9`X$058-jmf$TEa zU`N|BUc~h_8hz5tkzI=A`|b*HgJk!f)W(`BnesYsr38U#hz=}5-8A8K0Mk0Cb|wZj z=MwTQNE$yW_ovGir>;?r@0pgPiUYtcd~1@i?8YZX&2eH7a!={|t%H#yi;N(Isr#Nw z>T%-=x0eJK*Qy%IfuY&EzuM)CZv|pxyCC+86roQh(BonSkeWh6THOMc+kBuVqA5Cg zO}i94K==K91tR5Ev4ks##945b)dy03M+01)TSACSI90T-wjS-x2d1O-EFPYoJcRlm za_h$Nt1Wi_^y28`BPZUrp67rtztH0JUHeKZN_~eh*YvggY$pJ^1*+&W8=ALgeD9B^ zryFLL8X*1E`3_M|c%3zS;STN#iV`8MVAP`?Y?g`9j!qj-<$f~zg!dLRbxW$fTPUU9 z4sgo(w(6F z-x*<%($Ha5#jGc^i<%9(HvOXnb#V_?|^6I(T0Tl{hvJJmVtFs;v-72L#K;U9p?G_r7 zps2gq0j&!P#L0D6^XHEa=Divwm@XdEc{dQJ*_yxflR`*{$M=0C8(kSfC(Q*@x&g;k zoM*6ZIHK02o(pRIN-1e)+XAZ;03Xn^zV=sKTSPI};qjR8sM!P+B+dSB$$#idJh}!2 zAPLKD9Jmd$FSA-RjfwHKmZrGCENl;NApq|r6A8BAPMg~iqzk66!@NB# z&SlD_=!@=ku>imugLK*95H?ah1HEvtnR5_KjkDtHMqp;%J7%`^Yal<`wBR~F}iD8#BU|o1^Z@^2e!aQ9z_vJU4(}O zjun|%BgUOwi`FXl^1yt8e1ap#^Qg*k%+`!)3V~Fwy-EAb9)(ZF7$Gar1~5ZSa^f~X zT+S1KVDa%aguuy)E#;O(`NLGhnT29&{+E4QU=o6bbULn%0_zPgdz^zzkv;UC3!DPM z*Nyt8O>geS7J#mJ1O4fnpe3cycW!7Cd9kLrK_G1OU(#ydeF1D zvk1@t)Ljc@Nc^fgEZD^`e*_nRfxsSx3kRq8hXs}ktY2eUw=N~BBS44gxY(CUbeiv- zoYTjW;3-#~co|C_@^a$KnWmQB9j|yb%CurOYUcx4=mE|MKkJSJFzTK2{vxQT8Z6Mq z-*c$Z%h;xZulNZqwi|!A?#x-&yoZ{{l~^>jz65uZy#>3RpJ2;MK=j8M{pE$;T@%3$ zt91uOUSF#V7UF8Y@erY3`<F2eyoPjP24;tmag06p1-J1N-Q8I&;L`r@5xF25ApP0qfegwfhC)O zU>t~&jt^eS+LPha`UQPn_c*P8f4cRE9^~jl)oYzwuWU%C{fCb2=8d6Kv6eQD+%at- z&0KzAf4NqD|ei)EA85pT*&=q8+<@k)dH>cLU%&yPG@_kU&#WC9`56Fo^V=>kuIy%

    ~atux*{#}TfBB#ZI|Jt6^s!w-!Gxuph*14D#HCvAm*))>R$gofQe5EZ5+keWlzAy@_=8je z-y1Jj&ICn`_2nx>|MM0t(ni2VHVrEJ5Bmj6LV+$ivhHv-hQWw$eMus4cktumixik$ znCbY4{KK? zqJJQ?5zAq!X5pAt$`{WLk6+MHhs)=@7!Ri6ibsd%U+bPdydGX^cZHVumqNb69Swum z3$D?)@DdGv)+wf2-sm+*a4~_GA031_gN6Tp@%N;ERCt+&_4-h%m^c=6KYG>}5p+?r zN_L01o&~0H^A6}V*tS6oo!c~T@9yB3={*DQjPPL8?S8xQkV~$&vWS-$o%&5F7RJXj z0VTiTH^1fv5UytZHmY6qyPuQk=r8=-#(aZZg^fQtisrJ|?z`Lm?tk!iF`eT@XiHFiKFm>|Z#g$BpmX;sJ%-~)gz!7$au@gAU zw_{nHjiumtvpPQ-SVk+#y7(Z~lle)n!!t-^E0YP^&B9vYXmkX}nXN`%$N{$(C)MOJ zs-n)g5M7)je1pQC_~90${LPZmziZa`al2<71Eb^*wbuUo_yI-@uoQ#Rwh+}m+a@AThmCk+TWiKS+_b&gfI*3@C|kB=qWAMwfbV=pkVM& zcJW-#7iQx|b-O%E_x*hhh_fK0)(o9e>IrH5vVksJ-n#<#nuYNSUZvwUohbBmO7Cmh zYX7M8c3MfVa&~%=M8}UxufrF`?|xKze^h#ZRC@oBO7Ho9Zlzbo93c=w#s6G?KUr+@ z@8q*q29);zuTy)`?p7XKtJ$UnBmd0hnk_?RrK@tfw%ipcKk)sw@@AprZv5W&ef+mX zJ14j0V61wjTljs~x|G3ouWd}$+AE6D+Efm;@4>!_9Lq6ktv0)wV z!E{Txkn6r!pC5@SB!zneXsY(_4~GxaN!8{Ubgq7$iPp086H~8$e)^|QudK!OL;eX% zaOS5|QrErQV6hAW(ns}te%y9#YV6j=4c6pi4j<^9Ww84Ab~Z>w3SS^|?rb<&*D81$ zI}W-V3y#7a^SWz2)z%=#h+0C6@;VR#z|-`CYKN^oO52IKK@~BPO*xX*2rD|4ui7FE zp%cO_iv^yd52jl;u7y=C8^Vjh6tPwAv7uf^1bypUq-kzJGNx*-KF0?nv(A67i+xZs zLr_DvmfXX^);1v$$BmJTm%{@W$&u=w#S&o-jLH*#TP3uW!)icto|;y5DX~%wBT!Ewt4a12 z>!W@B_yGVL(;prjzrr?lT0g}Tz7Km z#0)xO*v2q<8qv_!UxI-(1lf^la08du%}?RUoB(L~ zo5i>2Ba=%CLF-V`>6uzZ=v-<ReRI&K~p={M}^G#A_Sjm95xrbQ&69G{A&xl*OUS5wtYXgqE69 z4{*q21EAHDo3H&L3Uc^ZIk))vxrpo4Vke=kjwTxHF_&+~#Q{JuzvBzScGe6Y$%7dp zjiw6(G`OnbVgadCu2L=rI6SGu?_f2&W=BND0fLSwzOyhFzXY_I@H7k}2Sp4dzEkV- zQgwm5H^4og4+#Xx@4&7CKJ1YDry9^ZTv>f7Q!{EBWIR_8OmFVq&=myYf#nZjQLec# zttHztN{Ka_m~OFJ z{GFsEl>>@wCZ!Ju?KvzQMI1^VhvtnONDV$BIY!o>ahWgbaXiPVg}X2C8dccf z(;{LXYt*agD7NQX4R%wjNHL%V<-N`Ax~ zNRh8U%Y!(3X!fHoB?yKGumQqr-qsnLO>T(bkQfkX&(u8xWGyjLh`OP978}D&Ao`+? z1ZB+Jkz~MpPWuw?33DiJ$L@uh1`Djwq-&8%aB$hOykneYPjzmkGom`5tj1cVq0ACv zfE6xq-C-~TP(k3Z&p5oEM0^|-QSkVu7fMHg-VBjtHo>B`?}0z8uChNCZ8AqUc`cSk z@1*6@S9K zsgu>kkzq0_-$s3E%rrTq)}e-X;zeS6Z4u%;3T8;Ke`W*Z)3Y<>NR62r`;3=!!3lj6 zo2+n*ua<1LJv4OtwS4$RwX$J1LJ9l6bk?ejwS<&X96=U58~C9 zq65Y~Tv-x`5&<{G;#rGQ^piJ|@&(OqE3it0Hh6o_m70E&Ga-<8sIF4B>e*d=zPja0 zaKqA4JJrr&TC)7D92}F^U+`Zv0U-p*OBoXnLJKRNCV-U?seK5t8ru*}{^Kc^4qsy% zEw~W-S3KY@nsMiKLZo4X?tqe5Ls5Y&S)Kk|RXS8tA`}LuSEwH%VCyw;`ShSt6{jBb zc?*}wp#{fd4PvghYduO=SxC~O{Ns_LlQVhUN4Uzc7?i1+0epjjfCxRN5&>> zaHOZtk7X1n-&|;@HeG>Z0ZGNPs9}s8PECZMjMrmz0&0Q))73e_sa^znk`^Ep9o6Jo z;6bRqEEOaQG|eN^5jRWU293RNVli0ubQg=~cBVgvc*a|3yeROkQSPt><3pPo`GfCG zR4*+FN-@ifhUbH~A&ja=hZqmQPFfMU?&2e9?@kXcZ0`#YVn4~1Vp6Z2302P0=2`}9 zzo6<~+VnfE38iIq+F~9FH_wn~xaROY$HcvHlA>Z@rxE8F+GghlfreU5-7HsU1HQCU zX}Z=*;Y>hKVRPO!EZ3{wdPzJaU(%zz#F>x*0zq$R6#b=Vlu@9f4E>!u1jSl#cPscV zWeY8jH`#P0fyGN+B*;tqs+9`4wmTuO@QdXe(xLw;KSk%6{8a`b7+5xeF=?cm^L2wl zR7+TPm0Hohl(8yKA#O;nu3Nnc>0`k*_?v^G(>l^B5j<)Q8^lXLNg6}LT7&tBfW3}`U>eQaiJXdZ*5+tKP8}_jK_#S+t56HK>Z39o zdAV2~juCtKaNr>t$!d}JBQtFVZzJfr*5m2o_n!J}PY3ImM0JHeX(jL7ZsKghVBzDF z=~L;5(!~j8gddoXso+qjmX=3kc|^h-p$(W_H(X3CxelmB?`27~$`S+@Z{I zD1-#48f#c_N!wy&0g>h&g%Y0+O0A%;TAP9g0C(b$!hrgd_aeQArKLk ztfK^a{aHrN`gwGvAVe6**fcCngA+Bb8Z@5Twl~MM1#fS8e$LT0 z%i!Jp{V!h;sCik|e2GU#LCl=2!6kDYq>fVjmb_TW&`h86M~l;AYV?hGbw))dzYXIx z$Lw?=cGFx#&56ZHEAChNQYiR+0o?QXS0dsHuoj5pT*Ge!F95+_v_bTpWIYZzbCgp& zlg`*Tver~08f>FibQjQ5RRV(VHv*L$N=A#or`6rWy|sl!lT3;%zHj&Zvm=Q-H1)H& z664X-aWgY)m3`GpT13uJ(aJmN;l$dYaMUDxquoMV@nIXY^kFH@(1T{nr31%guLZ)e zUvYuq!t}1Al=0#Pan3KUcelDwBEH6ff{UAfNAX?RMT1q9&x%Lu zIJ3t)ykcn0;8A=U6wVGIS#!^UE^~2!|4`Xru;5m6qJxUByF3KI+RG%r^!$k0Nymc$ zR}Lt8%|ezOF?0c5J|o_a6C43d+7$1pOF+bcIgtt?(e%PM8AuKSa221+eUqLZIcG8n z+3G&_9&P60tdDr^b{(jz@OS3@dzBT>CWz~&q47?9Cin3Fcc${54MkCQeTns637M0r!j;WUb5gQ$fFjN#QJ(czZ zs_Uj;QF1`2=|ZRE&>b5RR}97`$?^4=yCr)r1>8ERYE8NlBP`6uo?Ig3xuS3whaHP3 zd4yVTKXzGp!>W}DGW}A`m*_-bY>}tDijrPj;K!l&#givkE9B`+&h!r|obNCZJ)~8Z z>@rhQY6;4$sXU9~3Sl-WOpDJ45H+Jq=NBF>_L^t5?TYhoXN&$;aG>P9boMp_c1+~- zAQ@Z_Bbtl)ckX)g20EFiLl)qiKZ`%cMlTx+CM}yjnv~p<-pjLKoh^NH{^Ap|CX2y~ z9)>ErW2G5{!vq64Wor%&XgNSlezBlOLo|_!n434QZENRBB(?@m=}jjb?PggCf6QHlS4qTU9H zUfwkmtmy~9`%>B(pD5RUYf7PLU=HI1AEED3CBG?t#h``teh#}$MO9E--Mcknx=g$h zd8jv@F3}D&g;7MGx|d2_8Q2%)cBh<$xS!aw4`Ug3EF8gK2>iPAvv33W@g{q2h-qnY z^yf&tXm0NcZ3`-Fqu;))Z#wgO+Dg3({m$YUHe3SB1eVEsoX71Il$)xLFMsK5rpQa{@4>F%MLkI^R72*RnPhDL7p~+y&C%aZF$--$#q* z*^wg1JZd>k7O&Kp;xhnC2_Y~(z!n0_wIO{_%FLyy`4lzB59x)k8^j`dV73s9pwis! zL=;~-bJtSFA?qwV@U=TRI(*71YW}&kaqMD`Uq)-YT6gNJdQzg2HaGRnx4N@n_=DRF zhCgtU=O2Rc(u*1^D=wmz+5erXhI-do@!hzZUeEIlNl&L<;jgH_<`KX3R=hR*t@*m8 zjNgCh_y3Ofc_iM~^TTTOcsJi8KmT){m)Bo~-f!vo(c<&@y{f|I`&yg^<0sdz>hAZv zzZxvQuJ5&zJ%3+|>%RBodSdQ*o_Jxm{reqX+LB4bzWmcA=T^Vq&6~&gRgI5v*RoY6 zKK`XYMzGmt6z3t8<>CofLKyXX`XBi>|oW`3f1yr^``CB7l1ZE9?^vJ}yT8?rS z#Me?H{=&71*fuC&Zp$Y0^%nL19xH=IesQd<@4~5~A22-~x1mDoO<(N@<7GvfIn zZ9u*e?r(Qdy3St8`} zKf8PHy(hZ3`AdEC-p_8_cz^HR8}IDBedFD?Z{B?GouA!&=k1$6duR9N&3FC8?#=h! z(=WR()vVt?ztsEjbLIQ>kpJC%c>vter^%W9SE`N*R<>AttFpRmTsUcLm3N{7{-L@e zdIXbZd`QoFP6N3HWTMafEd>pbsFIvo9vkn8Ej6!dYZNat;NIx)Ub z=6UrT5{A3InKe6D?&H=JQyJUC6ePkZZj_d!5(}~eBZ4{_OA-QDX)LKO;OG%;r?8A% zMALhEKu{yoivF5z6JgGn9+OGh0p?TmNO^Q9t4ApzcCObull(djA!~2;C-H&R3w5M+ zBOPI*53BWB9Tp2Y^j&}MRAi$Qe9<7#Kn%?o&8!_Xt0J#zr&IQ8eVj;I)m9V}B*Vh*$P)J?kab^&rIld`3~KZ}LcGe<$A9;vJ1CBx zPCcZ+IUREG?=NK1>8il5Xy_hFkj8zO(0)B~_aOZ^>YvS20?!D5hV8AcJ3<#js)8n*#{^<^z7EqRftf70QJC`2dGN z6j3C1Yor&83{Qzo*9C*rZqilX135w}Ph`*fNparKOg5}nAHEkQ zuX=;69Vh1|f4|q|J+N_~qH|TOfS@165?7YMSvqce9rsr_MOI-Rj@s(l27WBDeoi6R zP?(W>h;*6q&Y;NP8TB2y5h`ZeFiU69p#xzZVG8{-ZFRBufBtLO-`$nAtz#Z&PKX1U z=MHKA-wMnE-vwQNV@wBEIxtDpgmO;XXm#nf_01cf8fK~xrOcozg8Xz^nru{kEaPq} z&uIHz5Sdv)S8rJm$VcQC0V|57a=e-YYXC&ajW~pI(CPFvBG_c3e`a`PSnI_RrLvkL zy%3`nd0OCFPA`f2In5gJ>^V848G8nbhowljVx1iH;CWCx^{~*PX|)WCIvLxA2`K1^ z7GVVO?1PXVmEH$*eHM|Z#W~zg4}eqFm3-{9&{ik~gu+31bV6hOvba57dK*|;J)M+GaS2x$2juRfh4s*g6eLbm;7+;pxHvx>?xlsSKgq7 z#Ig0$-5aZUUc1hGVA5CY#OG;`-|{x(%NnN9v<+pUG<;cH)}gy)&?bn-L$2y1j{8f$ zic|Z_oQYF8=Lgih!Zk$1Zbk{KdmiqzEhxyjFE|q(T|6ag@@begEhfF7ctMV8ZAk^t z!>pP_EwjL5T0DlMY*;bQ*5Of7_#s_IJ(Mcyn6x8Bm0AXi0E&t)IkDe20%UHT)I@DK z7=Q$VJonCN8`>xXolh;5jlw4HS)YgNR?RNmt|&V?1s{xAqbQVQ+A6XB!0=d zg>tbkxST#4Z+{X!&vIm$2+^%Bk-GcV?M1sv0&Od~3)?APV1bW8_3V^ARr^q~40R#W{|fad-U$9qf2AKRON_Ja%!r*)Vgi#(Dcj zSu~IMOM()f_15&r@H^6}#`S%ByY1GT#4;u}CHUZnotJ|KYxVS49T{WoI#>mbkz7PP zWGsl+4BOyzobM+e5GoYj7=Op*62fqlCQhPfwp~q)hW5chKeNM=KOEs1QgB%5CdT}b zwPY8#zIu%9!JH!Bv*lTqto5i-ToDm-_8fztt7+OyUT{WGZG4`c#9P`X$Fy}1nyKN9 z8{OLj>?}ZIE#e*7k(?`YwT}s}rtg^HZHzJ)1mCk_Oib=YWFkiTE{H4eY5s9S0DB$j1GQe9B=K ze?chgo=?LNBAN`@9QFsA2U~gzyZN6x6p9FxTODe;`@TOzO;9wH$F!7mxnbhBYO;*R z>71KUfsfi{ZmhWy0G->d$pDIYcMpg)%6Q|h{d<&an z$wS~aXpb~J<0O1jR*VyTUFB(C37Z*`e2ZOr?w0RL=*Pqq6kSPMk^d*D8=wy<*C5Q& z>FL?;*?feMkHl2vK?kc~Iu-|lzPLC8(1*f@DhtRfJo+didIPNP;-t{UxJfcHX$|6e zgxe0Ef}_JT$&O1)HwDVhsMzWfxBWm8hE=+|IhBjbG{jqtgU;0c}BstHOu&PsX?u2qMV0cTC zv(`0@j2>reA0zLy@j0&vY}sy2oiOH|6Qw(LXD>6By(Ex zI7V4^SSgU?rgT28E`b~GFshc)J}W*MOs@3g8eur66c57Jiz9CJLEN-4Lj7)ks%?zs zNS#FqGx?4xN%Fv#*Cw`B{b4Y)sS6e-ih(q;z8};EhL^%&psp;3M_a3z@odAnxO@eT z81Ch0;L4$b!K)6?M_0%u<&h&hdV=#z{`u+;gj4(l zPChbOQDdWT8|T${g-@_ytcc~}{8auA=h3%#l$IJ!G5cfZ?Ks(pGsS#2<2{}dhSr*d z9VGB&dJbbp$X-Je;MR@`pOf0x-2`JxLi0OoFf4odCB27LH*6}r@pQ@R;$vZ!W(-RQ z6T^9(G*Tk0SEie^J9~+kXjwJ|-y1&;%R3*mhkA!?-A<#S(}DzLmFKSBJPj?OA4y|{ z8Sv0S>Q>RM&`wxB?{t$ebWDOYZj(tP6(Z=;T+MRJj<6kDM#I4;orWFNt*$ce1@eYP z9f6m0@rz*kUCYSQ-BZ1bQS-16pCYQV?}@RbzXb3&@5p{%Ty;{Ds*IzuCfAg0wEB(w z#Wo+4NKRKT3^7~lVtkfLR1-dcpHEA_Hj5SSCBmRnAKk#>xCRU*T@*f^#0t`p*3`P76q(RyPt|GV+A@k zp8OLF_gc=Skxyea)3p%bO5q;BD~Ga%*MW$X zJ5QL+q!{|MZwKi7ZW12KlgIrhW@_HjID)tsCik-9yzKNE zAlGzy%LheY?~EwSR4YcZG$h9kJrhkGsH<_gfF%IbIWB8*kvs(q*FmAMZ2)gVQ`k@t zZq%`uxEtEq^xZ-9cZ<;Q0gAR(yC0)6moQZOSkzD$$F0&~G@3kwY0ACJ%uwFo6c+#c zf1=(>-SbS;VzfA-a6SRLX^&pzF7`et4kA(}TIH4T=lYJ>VXw5_ z(bH(so#{f!tZ9Z7fsdDMq0_DUBwt9&(^?)ZK|Y29djX=;cQw@(JgtsZxA1sf4urcc zseXBDRRf&vdYFycWqrWEFP@#L-p=_$`}^BePmT-;i|_L1o5eXLCPgZ@+sP7eV3;E! zvv8XXL!pl~xjYkym0>x%|BSeGZg%nC{8t>_r(D~L1}2Kiv+&`p314Rn8x#gU=U+8jAnSg0;I!D1nGSz+*LM@>|Xz@alW&@ea;)oLZ z4|%P6y*p`|cD%Lk7MDXp8Or3d&}pNLm)Hk27&9&lfyfY(zs z*kJAW+O&-bxas8%S@pWOq0K9!D4)o5)fkV>pq_EZ8*3h=csh_qbK|L1sDQIOLK;5GPBM%P-cl5gG*-<%%!NZSmZE-cW7W85RhDHms`MO|2AJhxE;jMr%NT z08BnBC&1x>v&b9o323h8O9Qk=-)m-}1h2YAaF8Pq4kY5-kVbKh0S{XYl+rM(XBtpw z`n63TJyrE|J2h+ID3%(-M6paVR`YGWG9XH7>&$DQ;}>a=7tf%Pf<~zW;ORt=unz)O z5uNBH%dr1Y-ZaF}n@F|@c?KV_#e3*26-R6qlB^7w50N9^35v6;B*ocPqT=i-S#hPD zIJ@Me8ROd^xW2$mof;1%LAzj&!{7;yv;Y|JAJq*~EoLwd% z2OlFeln|!{r1?y7$%Js%iKEB4T85PJ;tY=>#Olp!a_itam&Ao#nqjt$*v6H}!## zSh{|G`QeB8%f}z*FMpN){x1LhmVc$C-s?q(MoE=TVK`MXqcGy*YW&fe2}dW}t_zrM zagqd4#1&>jmzh&OHA-rHdJlJ#ZYJM~el?FBH+qC=q28*ESKA|G<fMY)agl1fg=jkVDzzn#MU&129tuLLjv$DiIQ?|sXmMz$> zUP#N{!Bf?B$E-pHxIWCe8HByJ;pFgXl1ryZk?^znA-!T&KRn`sb(&#?zXB&NJNm>> z5n?vY-uM}wq=BY7rYU+#16t;Ez=ip2yT#7`gUF%dt?5~7GdJ}Tr_1Vx^75^I3MZTo z4_~$RX1ER7PV_OLP~3)mESb6e7ogUR@q4V_bLj)n<;w`pCJhc<@imAjvI}xra`yYC zGd4Hdwyh;tTyv|Ium%l*)nhxX#-(vy$`ynMy&vtOC3KLzu$F8``z`ODM=;h&o`hp#D?O*yN2V@^kJu1pHOgsM@ z+vgW#%%g%iOgpe^pUKQlKsAptts$2nE%Od&;5npSvq{OqvQ=r-U948Ap6X4cw^WKK zZ4HV%CCQS^WES*WpsjTX<#H(NX{8$a3x8tf;blnXh1cGt?vIbcd(&;FChrT_2XLq zlf_?#(_E2?ZNYo7_z(XE*ZHsP^~F)+Nixi(uP<|+&t_zZo8NQLY&#- zEQy2p`CR)TjZ(jgisngj>h8NtPrbF4+DAjl`H({@ce6~M(6iC z3KHsO6KY_=NHIXh2e4@LR7p{@1!VtwF!Ju<1%IEgKGDr_SX&!$OGjIVI6eJK&#rGU z1UV-x%jmOyZHgp*3dYxB%Up}p<8#$<4c17qUIC&OkEt-LXJ>?k8LD**)Kz=Jep!G{ z1<#D058RDXF+xledb)vucqni_XcV8ocBE@-QU+A zmx3?eWXF1{)MFuE0YgCg|CoEX9XXRE&#!?M1Szl(bgiqH9P~07O=go--E&|a05*$- zA+`>!V$POU94<4NOp@7^2Tn$2lbos9$B^DcfZjnjdKF#kLcjmt%-sEph|FToOkqTH z7a0-X=WcFpXEQg)s7@<=zA&5m$Yb=?5B9|`hxUyl=KVIlp)em9lEIA%cqA0IV!6iMpVGVU^8X}^pwS)=&+fUz8>o{^F&7D<0i5jesZAjt(LL^+HxwLtz0oaPiXQ+W#a$fynuZ0tUSrI3As=FKh zkGO}eoM7CGDQ)5t&Up2zcD||Wo&yrrZ2YuI8b4U3iqk}4pI9ze;OSQ8f|34Vb&2jE z3)u<$lStcu3p_WhhgP0S> zACOCjoS>yNjJ@;eCed2fM!ecTe@+|K+qoI8p#uj^u2@wdyt$uK?R8AzFzf}l{7}sh zFHd$7;#2b%{zt6*jDsX7-)PRQlR>B#D*GTQOWP7&F$tX<$VQ1~>iUPfY5 zjA1h&&RE!NfGFE7nYAJrv}nXYK*5rCll1LP`vk+Mhl^e7`eI&tBJwTq{6+NJkJg8D z))teIMO1Q?G`%iq4gzE1LS+fKLL%~^5eI7Q-96~tmw~y{h);WS=haxqA=E$)*6;kY zk*24T`oV4!U7*a`(cRfgzJtca>RP}LhunHxAOR=Z(i9t}d<0Zjw=CcwX{+m*eJ=!K zK27j9Zk$ET^)quO#QiyD3Q=bK*PR{JS;a}K8^d|&&2X?(H(V;O3VRiotN|$Gu_@olM%60>gBNkF+8MQitK z@eOLVZA6BNQehBNj?I(^iS5jP9~OG_2$9U*)KjcxWR#%25kAnji~65zs!9BqExs`n z(6tb~Trph9Q+s?+ba+izbVn)|{eV3Vhb-}9^Ob$Flx3xC&!Xx6B`4e;zT1~jcNJIv z!Ow>hq;$(IN>Gcvq8@&Tm5ubJIaJbPGe@fk+oo(0Q4&?Wl8-L5O`Z1^rr1CJVdzoX zZKXa44+qOe4+B4f&K8kqXVcQo)=+4LOQVbXdrVA z#TPhOj9Uk{;*78`?PAElOM}uDo$n`|n%44jSOfnPg@F}WQd<7bs~rp(cW2-RBhJL% z{bbJ3_!(7s%1Q3G_}+6VTR=ve=r0XpSha(qPaC``AT9a%vb+Q}HVED5g@iDj>Z_2S z1;_z_JbC)b`~{Fac^aTd+iRtqMb*FH&8al)(CDg*BgjD4+}={>7Ong+|0}Tn#L!K!~Yyt$fDiwk;g}{FyCFtn8IrLfBa7h$JlQLZ+X%S z?`KmWCJLE*1*07}bOZfi&X4{9$`+P`t|nu#tJUnB`%HDhSeuJb>eIoA?zEK0Be`?( zY_5AtR-Y2f%<3U*q6FMCv^{=)_KrY?4TaqGJ`oi4w{Bozhdmo2Lv({mamSis5OSd2 z$taiO?QzN&L#OUE> z4Xy&+w1qGMnd|MFX4P((6Xdop7Y`h2@pQDgrR9Z4lV#$RV2#@Zt62>>w~%RT0&W(d zEVInHU-9mr_UA+2_|@#khE9TvAN1$P`4@+AQb|V3)qj4R{c836$xnX%&^H8kbwY%< zKIqSn^RM<#p1;`F4q(AKYQ5=2;QrH)&C?(HM!@afWRL@ z+V^VUe}1^#eeGIU#~**3|L*JznQ}V+_Pg=>)qnr|aKm;#h2#OK4)^_Uz8Jn={pZgQ zH~JH}$*g`5^d0VRzTI5~cKH1B!+mrb+F1I({;epqjD@f+;@>Vxrl;c|CkL@i70$_X zvP-Xz-Wd8H&GW6cA%>_5hflMx`OmV#;WPf`tskjtQma7;-e#x8R|7_P?q}zDYOE(S zUjKo;%*y|NYu=$m{CZF)zjnC)mumt4`SDGK`vkJcHgm`Kxzq&5^`Qg@Sm!Cvmd*DaHK%*%>fAZHG(f{+q{qBitR?>&fPxtzF4P^fV zp1*wF3~(ZYQJ_N4EnJsd{n^l$?|P?hf~%C`Xk*{)kli>xqUd48`uuS?$ljw2ea!mT z&yN$_wzATf9q^$ow!SsS1e4@hlU7M;z zi%)d*lQWzx|Dgv&<{#r?tGxevXF7>zQ5*Q~m+x=RKUHPRcAZ00?X%K?B+!s?&WmxR zmoST~?}&fIEEV`79pX2#fC}EETMZ*9FrlW4++W6ezT|x_c2zXmV0*CylrD8bnQ$zn zwin7+5sa<)L=~@jTCE%p>(Rr959fdR+ux7|<8J7~+a5;vh?7xqL{zplp*d+N=Wlde z_wY8CJj{PNzkA5v?8PMV5t!$ouM#C3!i{I*G?F$Q@gY3B!WTIDc)zOgTy2?v%kq!X zHRHn9*@6>Fn4))En*g-z62_{k6GO4LC(Q4>B$el6MZ`i`d(9uE3p$moJtE5)u`quT z6;zImP5Tvt5FdOBilN}7hHXm`c`6i1TGzx3;qQo0lsrt(D zz01#KHi+OphQnUY-|1~v6h#^Z>To_sNyRL&A)alM!$~|!jC2E8>~B`vnFwJf9mCyz z_iNKD<3NDQe*5|r@3_ugZoj)N(*8Ax7>_YhBoqhgVSDFtGF_3Cl7$#W_@de(5g$9; z2}?c7$&sB`l8{KO4_$4)yY>F&lRHo6i}`y_j=qEDfI&cN^?_VnmmvPI$15EDrkGOH zhWt?Aj#r`{EH9#LB@DhF+VOVv`w*bd-^U?L0%=@bY`Sd~1E9AM^dkANl(LSalN_V?KT#m;w@!M0GnP zZA$72TpDXStP0!?BG>W=H_9|ts^qKtyN|vxFb}u~efR!X^RFK6?mql({$T$7qusxm zKX~}Xqp!ZYPtDM79Jx^dyx?Yw_UErv66Xqx5EYZ_0`gAd0 zBzcK2i}|!OzkO;RoyO-q1VSMb2^@!{be2#jYj;XQ_wgaufry(dOR`6z4KcVRwIUK^ z^uKsYhxqg3BNm;?(OM&EkzJxCgf7uiDd8KKF<}>dWTrc|j1hTs8+D&`jyEH(7l{OC zJKiGN%zvnV-Kqg0NT%1WgA`T4x+57WpQJZQq7f+^gzjXDkr0@ZU0Tg<7c?-j7 zq9|`{DGynDTx1iCPdPpi{Z&xofuzspaq$et4PGDWYC4_B@*vYH z6Cu-*UsWYS8UEX@f%+w)p`~Gv@J`s9ZuL%@jQkT-C7O?VOR>FYk>aM?pDN(2G{`$M zINpf{=ZF++(FWJKAIVY7Un-5XsTU+|)N>6T56knvc5fD|^Z4bPt+d~O&Q&kw^n-*Y zQuK(8+S~hxru*dj_~h63_U`QbRy4BwAE_-aNNz_K>izP+s;x?(LGAK+uN|S;l+s$L zuo(5IXSu)k}sWW(_`tPT!ebKeWd^cYkWSN~!ScCOND?h1~3EfH5~@TpLoLM|5z$MJz+ zyFR&DEKIuSF-{ff{H5Hmn{-82mQ@_Ilgxi z6>#!6(>&h0;8LSsXr|@=rdto!sb<4IL}qb?xPq!o;uETx5{|7LrQ?;aa_hgVsB!aq zL2+UA)it6=c}G$Jq$_|Bek3{Hb6L=0u{FQ+N=sYRpdU=N z@F+AO<8rb12*wE8*{M@~X}P<;Taa-Yv&wUhx2t;Oc6_KE-EFDq2?BnBi1q zVzsKugnT*O2-hlrUQ3^l@!VCESB+&2LY>+`D1NU#cs?9c2zI$E6d{o7!J*Y3l)2J# zrQ{dTVxXhTzhuX-3T@iCbW3?`D1hya%1fm%iE4Oqaco8U7%LDBa9EdHGUicSwzu!kU9F>CR*?i3NC zpRud;4KARq59F?Xz8yqbzu(!pBN|n4HzU*4g{*qq8jl4D{$A+9NgxkvhuhRY+L=TV z?i#0Yj2b`YW!S!bVZObQO)tksD5VUIb!j(O@Z~8BVX{1s|J8|K&;<1=ef}LyE~E{l zx8&oR0_)AB>wy#1zWskaJU{y)`-)`GjGcLnqlSL5Pa=6zR52oVra149H)~#@Oh=xv zxm%TX|4G&GHCSB2f zpYfAQ(aOh2QMBFQlQ~#-57S@E)5$o190|v;AZ|M0rTg^NrVF-y$uEH%!H+r+LOR&A zY%4LyYH!xlb)$5Om6Zour+(T~LacglHheIqF_Fe`L z2cY4*Y~N)zK`q;*Jj!K+d$2W_r>{s?N3U$ht@-vxIe=Kvtlx&IWsKW6%Vhw=J`-!} zjiUZimgT4*ltNKk-rFCq%rP_33>F_o-wI?Q222i}A{+a}VKG7C^m+X@gT!o9pjLR490BL0O+e4( z6?$R?yBH3PY9z$uePq;)zdL0!I)#iRodn0-K1HvFzF~c+*7mhVHa9}m>olNsMv|l} zOG8@LQOmYvRU5jT|3SxXg&_QQwF3pd6gfcqctu_?a&`nzuu^XgxO9(5y}!I5Kq>)i z{W@F=mPZ75;yoS<;39Egm7%H`xu%j}6Dq0;be0Ji9W5o|O+`a7HEM}(zth=^pSUn) z5U2JPvky#M5e2tHb|_RSAI;_K{eFzm1Dj!`Xf=N%5TCBE*EGv^9=4 zRV*Q(M8_0CVjozEEoTI^O0E+`{Ug=iJ6lrXCbxhhkW1hDQPhW_!%wV4UFL{d>VYta z9bDU=Z)r>EUc-<6|5O4q|EFM zj6mB!m1E(C958zr*ZM8CJO##a|ZtJ-eW`&A&I;|~rs|Ncp&?S(~ zLqz6%jD}(~1#G{3uqoiD2UEbGC)dbY?~gn7WNH~aeTp{~RNt3b81e~Eg#rqy^TXTz zXDrG3pqXE>dA0~KhzO_!v(58>Qp@GkWM#EMmXZm6!APIH5WKXDNmxzH+Jqu#LnG^x z&>A*0=AKB1Vfal0BiYYsq&44$ch9*5Sx@+M$NbS3Up)h?apW;Lj0{Pzk5Z07}ua)CbfZr(v2$>XSlTr!AqbGivgghJh?e zCEUb+>KK<}$=6b3%zWGq0h;#nP_69f;TWm7qAij2up9a+297}!aTO&CPO_g9o>_li zPx5x%X%jXkZP91E`H>xH*jeKsyz(lH(1R+Dv)x}@efEm3|lpR6s;a;Yxxe?lE z@IIZ21#HG%!%=|ho>kVRI3|#r%n?k#M2Mp@fv5J<2+qo2xJN0oC(9PSMi$%aDbSKS z%3pHKwFRpq9t85RQi-mgo#R7VOYwH0FT5lhIMYFLhFkWv`o$KV3ML)A}3dIm2KnUXiR|)S|v_IK{9OmV%a4tAqWU` z;+-9;5m5OYb}*oUDAnGTIxUmJMDv>L!~Xff>-USia4a^RQYB7lUO4rs_328Z+Wfrt zNZqQVv?-)xv`fPJhC{_9ePMA&nGabc`~B4F_PIPE7g9JtsP#3=-uMX_8PsnW}`~M%9C@o7HC+|0^d#+p9j;ZAYQ5 zNK9gxEgn{&VYv`XN$bec$W7;(Dw!^)FHGdac;FLo+9)D9wbpBvFFpBuHFGG||K{Jd zs6ZrNKg1S@PF2BoJ!N~iU{iI5K6XM?Y4&eHjPw3BBU6oNj@%#SDF-OLq+n9#3dyL9%RH}1(cr1 zR~B8A?NDx>rA|K>)#=Xw%(e$Eq5*`=VxcUHgz{R*VJ1b_nF*Qa;udW=yd&=OIo7_Z zF{NTk?F6J$m080^?)nc>jg?M-03j_MIhBD-ggsgXXoa;hAyqilPxp@;^k8>wju z2}=gmAunuLPDblE45Cu@Ye$diBs`)DNwQ`vY?(~YWpwoM8N=3>w;ED}P?vx{K^BC?1xx(5Br{?+mjC;->ASE`;9UVYM+zMo+w`B+ zV^ftbQ7;LmDz}P>TSD7g8-u5XwKIEA^T}4oBeWo((hPJKvA+oQw4`<%C#AEgPQ<-= zgW6lp;>hEe0!G6quOx7KB|sc$ZEM6PAiQ*Vd>qO(93opqR)a;%{b?y2p46_pL(T>q82|aY@kHUgZS(G z)6eEVP*?R0+Z+mU@r~QP=(T9TQrfh@wZp9%$8I)9j3uOxbURAul}#|hOedsmx4#5p z>H4?(=VV2l`Mt@L0+u3&0$}O%IkBCZn zoi4~EWqUKvkb4A`TX1HU@?ZtC;faPRW*s1y zx2YU?L(xd|zKIYNz82UzQu78Ii>mVxRYjtJa;9c_HLgGlML&tOCAs64;+!w2n~1n(Fo8@te8?Es6q)Q=Hh71Ot>{BE~Q^Xk|eRLO$0b5GYys zN=cRBDDqR;P6_OFA+5gW1S(j?}pTI@i z%i0(Qpaz{-Pd#={Jyo0b7?7tt@^;g~pCKQ(BBByk5F+wsHYsU~9Q4y2N z!CS+{(99AQ$1>d5>)Ljvl@e%19y`XnLI9|JJhu2$?aaFN4B=^qKeaI<=&;=U4g=h$ zxtf2A$6^SSk|NrtH~8CeW;CnF@AT~SA4rEz(Jz{H$*tbiQ?asPgVJQ1>s^_fNQCON z1?i$u>CFqh%3aVHbyigN4w@9BHejPSE?N!jN+t_&x0DWu+L#A0Km@!x)1==J@o*s1 zD^GZXqXLluuif*aWj2OI5EpPTn)bRlA1IqGV=f)dkR6TiO=}8Zs!=f8J|%R8LqkDP z0@5#t1KoP@;>LH=1m+Z+)MI?qPL3hF%ojJ90Yi6;{IbI*g9<@=Fw{ zLeKGr8O5kX8umqv%it@r%6W-bq{Fh1J zEdh(NPf;EN6xEJ=(G8Qv7ggqZrEtM*r9@sW$VEph>@k0=0wYj{Q5_de0s0z|AwPB% zRZpBbVjxB-y#)`Af|h;pCb6ir=*X(Q@#X3ygE8Fk*Q3HH2*59k2`kg4b}0I+QPN>^ zrHOynOobbC=SzYG^fx=D>LMS-y5LT5huC(5-7MONu*~Y-8vs@lI}>b_pmnThkJd1g zs(IX_ZYj1sx>|PeFrv*Hm6to^pWw7GmCIJ`*{KYtFN~;o( z0UAzuJn_YpCu|RKyIQK^U1LNQhNyip+QKiCS3(oh29op`y}bszA>E(4b!WnNQok8- zyjkgVxleYO;)qeR!N#S|=friL^W2-)d2Bg6fw5Tf0-G~^uIH3Ta z8fk2T^dFq0i%^K9f@{rw)k3YkbY()jF`?H@6(8$;2D~_<*PlA;kCtCKRuh{<9c;gi zEi)HrfKmV=w;H&QnuxSwN!SDGwRN(I455tDX|2+>PN|~u2GG?}yY5ov?l7Un!!}S{ zvd|=Qm|`f<{mp7a_rKu#T{BGUQ{h7wuKv^^2jRzlRv;#95w03=uD1Fn_I{FZ5iHnb zgcLz}6FvL}HrpA<#^B|%8xcY-L44u1H;O6~ESWoNbEfF%kQi^(n#ep}wJycM9zJCo z%71`wV8Dd0Zg!C8cz7~l!;!TR7+2ttH9sC*9v`d}Nyy~Wm<}PrByn>HM^fxs*fCdz zp7#eCTB26$5LA%_2e|f7ytYx0rmcy70;w`{lWNi`2qRDU=B3+$hcbWi^FcP6xx}Td zMuOno#S#MzXu^iC0A=Aq>oi$q%KuzPhC+UbLjHIZUYfoM?)Lym*2g|O)L5*))>ydS zpYUwT)`p+VlBRAt#%jBy8!xnwedrLo%m0BeeNB{&=I8&86qXxQ$QBQ_0OpM?=7W`d zZ_o7Ms8Lj!Le0@=$fxGJZ43J0mW*|1{5W>uv3yLxCrb9?pFbj}byuh|9P{n@)~BCt zaeCZ^ukfY6HYf_EwAN;MJ0q4PC}2OUEIgvzV%jQEhtv=WW63(oj15N2UtRpJNE0xb z?!3$G{W6W?zA4UL>ugWyt1LdoMB_jY?MA7bA)R5)uR4l?3sStFFUM3owm4nHi>Qgp zfUuNmXc1zN3gzvONbW`8;l7V}B(zr#u@dRCu%WEXL(OuiZ>oek;Bn+L%WNEX_)kN% zbWa1bj&RBzrB9bB_hx#e*kTM}Kw;?lBn zP8_R+IZcWyFNbINEt^g`{@Ze7o7rnPeDfmdt^ZDZqwR<6m;cX997B{rA7+)x(&lBC z2h^pyk*h#tn)Q&4(4}xnoN9Hy@4n-dN@s5bkuafNspgu@*!y>+dM8<4kA0A|UdcfY1Q?OAC0H z)yG5nTxIo!us_vb?dU|>Abb%m2_ws-9Olh3RMF%oz3zF3CH-jO6YqMq;WtmG7oJ#L zKBE%h^u^Qp);%)+7zIoj-{?Jwu!O*`txe>&RPz4f@M*k&1dajv3w>F7WSHZsM`FPE z)&CW^(@_c??IAs~MWYUm1431D4j})N=SQzNxb317aVbQ0g1?$1r^oKWh3`>eP9?zQ z#BY93X7&ffv#M046$rL+`Xk~c?W6ewb*N+ci0Ps6$}9s63J}KiGhx0Jr@{l@4fa9? z!qEj7r@ch+Fb}+iF`|{xSR@vwRu&S%LqbG$tOOsA`9v}c_x18atWnBn0w;}zf52jB zs?#3Fl`jIC5Ef_Lm`14eRAFilNU6ZOe2k>%{1wYKY5I_E=`Z3Ov6biSal%EC8t`Nhsu@btHsn| zid1l#Cb*H_WnJ)xL+%<|+uT$W56imbaEs21V=U;fnk$K;K-^$SfRgbNo%%7 z0=lEZ6(yH($kY?PD9A+(g4SSyipy)}KaiK@1kndPNdb53<4} z#OW&~#{H}*PN0eRoA~z#ET(_8c_e5i6?LGCV`qK-7A)G^dzeo_&f)iM9xi2Otwjin zWu;gBC)B6rg+FjQHkz4S|2%sG1Y#q7IP`~V`o(033E{0=*eFBpC@6OVVhDb-bl~8R z%!rg$8awp)EuD32QU!HcMY7uUy}B??;(Ii~HBwAycfl)y5+>6_B=BN!P;k8t_Z~wR|f-{fQ3U$rNyiE5P7?)j) zdk9RmxQ9ZaLONs^+-GDKu9wW=BUj$EgIz6)i-t*((6#WoY|&xW`@J6sWiM4xFy-zr z%mp-&B_^-akkJchTPKec#KnhgOB`p5xDSySPxwXam4$Xw`8s$oOLAoQ-kd@k(?+A| zsweDAleGsd_yeF?VnZ?K0j3cOTmkW1fhCTm0GI(}fZWT~CS zO?X9?k<|rBdEhU9Trp zWoW7*lN!}YZr2gw`+3oa~ZnMFEXN;tqW`k)nw)1@?^IhdNKZvK8pQLlV=S58u*&52=)~ zIj2{d*dW!l9g@&FwzU&H+14DV{rhmr2e@`lBMigF1!}$zsNJX%-aXHK{`u!1-~y`d zGkF#K#-AsjiVWvBp3@=x#^;owZ|p#L|H>+TR2M8!@;!xH*?upxU|;ZBkY$;q_vG%a`A5{0NSX~)%%hC! z(2~+DPwwvA;klhVJef(j@`X%GQ5~%L=mrNz(w$6(zMJrcU}m8NlPTh(FVViN$_tDT zFUkmnsd&N*b+nQOBN~mqX%CPYFZw~=;Oi)Xv@sra*~g4Zt?n7e5F+w`L;d^^K8qnS z?3iKet4o>+e08V`(b58tOGp{T)>p^FFE$kN7Z_#hs|!b8`m2=j5WLc>0#Yr+&V&XI zPQyF69MY9@~R~D9$dI z^M~JlDSJHY9-G8)z@aXc^f24__QDQj-Vx>?GU<4)xsxwd^o#Rm)k7GG} zZumL38AR(LVJX5`kgz*1{TVxb@$VJk40}#`X1V-7|L?)VOSvOm)gzwW#*>wIKlPnt zd9(IfJFuQth)t4WQR^=*tdp$InX9o-E79+ngCR2^>r2M#!TFJTq-meAalMRqjB9RP>N-H?`%O&Buf<)(tbQD8Vrd-yhW*r`zafDU) zR)-ak4dg(=p-!V)Pqv&)jV{&nrPNiPP;`A%84fY7uQ_zZc{?A!Qco5#D=r{lJwksD z7iI;UZD=hTb#8>-#VHhB1xXqbiCBfDfT`BQ;~YmST7#@-G~yb~3rHzE7fHG8cQ+?5 zy<;u;Ue|>Ih>Hjw#sRcoA{7H+CAcdrTtrO33Ng>uXi1HJqT!Lg>XCYxC6IUQAWL9(r;3N+*#05*=$LHYnxNUCI_OdL$iC z>j9P8qj6k6C30%wM-2qXGR2XS2)nqgu1=`LnJ0uLxk?;N(TW5h;#=A==^orezn>6&cvroszVRKHZ16pO#`In_K!Y@;TAr-o#q@&I}~zK!=aS6`cu+q$8O} zc_x_+Y+)Bd%s^)2GAPqfDqg(H520x_iX#--@hQ5}K7hzI4rr|DnuOZUGg=yCMRIuu z#D@H|8?4)T#a19zoi72~u!$X`=mQ3@t`So715OiH%FEY+=B5zmj=H2q?-7>K!*xxz zU!n`^F){O^i-E+TkSN;dRlHtU-v~4n5YYbkj5AzreVv#&et)}8UpM5C&jW;0&dn~D zYKYd38Or+CVvbaT%_9T=r^|?)SyKi^Y3hNTSFhKEiH)PvBZ3}d9e-8Kmd18|#@L}c zKb}_cUU8c2=n(8t>yaYB1WYXh23M35WFg_-_iN5~1 z$Piykc83WQ08C)gnkD6Ym`rz0sM@DagLHSxVz+MH7A~YqsY&w5AKoWScY#rfP`8O} zJFq+r%wWaL6E@xNB*9Q0CTg!sAGbQ;I4mMNrZMGeE+^0_xf~n0g zh}aEVZ*t6%f2(DYSpyTOlE_nnl68_9%o?Rnb3L8?r{s z-f?8|Ims1#uR#i|KWgSs%#7nz5!!#JydWM@G)Rz0XH!wkm*M;sfHGcx;e7Qo_e1O0*qV4J`8F%Vl_gET( za7UqID22GLg9JWAtt-D@oJpuaHN(kYtGkJ1q!mN@SqF?+L#GyXDS`^+Y4eV2h++v=@J&0NVxv**{7mXV4>m!-QwjIZ7Kb80bmQBkE;gGY+y$&)u`ZOUe&}{gEIR`I^V1a#KkcN{nS_M zGASGC;gsRu;@gCqrYGqPmq@dmws_9f8G(KaUA#IX+vF<~lsRTsl<3f6*}!PjO4q^Y zYMYqRo`C=g&cgLr9S?IYKD>B47B%AgsK}ip10~0G+-4wg=o0iII9vqz?(3UYzdo@Z@ zB+uO-A;Y{4-quJQ_X3Khway4PNu6pj0Yp5*q)0T*Q6sg9GwALQ1tft!D?WzS5$1N* zsH6V`JYpCQ45Dtp3n0i4LPbYd>b5V%xI!w*_!OFUVvz3?IhV{9e%E{8>sy)+97rF= z$$W`Y6_>~B<6(|a$*-vrxmq3b}qRrnDawIAfHP1(PdwsN9Bjm2_BaTMzw%Y3vP=T!>tc*Wir+jAQcLz~Lec zwRV9PUB3~_d3AjD97mzcRWn`e%LrHc#ZoEz$8h$G_fCMsAnr?Bu!tEVrb9SYo~z)9 zFcmbRR;h$Y4REI$LSSU)i6tTN=@g?<>r3Cc;HMRCP*}?)b<9miSDil{z?<%HMjhzM zs&#NXl#-A{1TmmbE>Ey=xVFJtB)3exY2tNNnw`^2K^p*p5wcf!_OYrpB!KMLR|@{_ z&Tns32W?BEX38WX6<#Cd;T-RCH3808G^&p=ONy9sxjZYmzc5*aKM-NtdUzI{$GXnv zH3bwI3&{6;Bp3-2PYq%YB63Yvy=a?B?hr)B#>OCS#=!>Sb3`sTf{@-Iuoi#>7iDg- zA5F8F5yOn;;1xzHvxe0Zy#5%Yz%HvcZE^d%h0PjNp9~1rY@spw7;3_^$;k+T1cB%Q zM=@G#w$(@|_+aHC-6Du_k#cWwzUvs*-(O-ZM(za@OE+nmqPDmd3@31(v>FCX4xq{0 zfYXsF(Y#co!hhH60PX;{vhf3QN3n+FfgK1>Eu-yv7A!nR#{wzS*`mEjrQ~-8j#5m zi-9Brd3xFAM*v7busspT$}o?<8=hu)rZ^+g!V}DFr6N3bUNkls6tC`X`A`;bu`lw| zr3C8yWYG1l*o*(Q>_hCEl<$kf=a;V#3Y7fgbcgpBqR{!mOc`h~EAwl_-p%gzxy=_y zddO&woDyhQ^Tr#a@cZ?AA~I?%hXoHhmo$wX3&)r`Z#3*BZ>)lD#?TP8sTi3oCpubD z)TpaGR<}v&1oidE2?sCv)~l=MdbReJ5ckdMLCL#Ct}5Dy zXdJTRjGTsxX0}XZ5`*YQH1JkNRR}0anCgXiQiF@Q`=gn>(^*Rt3yhRSFWNk9^})%T z;8HM8dR3`eZw(4D44}AWsjif(%Zmizx!0}f(4>N z{z`Cqdvp(>;)kguOlYloJS4>@)ELI~nk)i{dmw$AQHA;*sfP~8F`X*2SjgSb| z4rOe@TI0zy4KeGqG4i%4d5t94YtAKc)P_1mZ`Fns6Z&FoxJrX_7Y_@8zJr`68y*Gd z`Y~u3a1spOzkdKjst%%^5wQ}MH6SiFFPNKfGD_K7y@sw92zt&;AYF~hvsjmMDV~;j z4Dwt-ffTAvE;bb~5H*G#M+WWtRzbPh8kA00uTzGIkZg-|O^OXef+IY*7VKQ;9eM1W zEXb4Z;X7tYW#vdZJ~ew|gb+ItdzZ^<%%Eyv97Uz-bTWCv<}Kf<L}`K1Vn#5g6Fd#kPQQlQ&p2ATgd+^aH6qx@vSc@Erpw;9^O}vR&k+H1+sR@>jblffl}@pmjs_h zlBFI%_Tb0Rjp*`}5D407=i=;Q|M*!AB@8ib8b77`CYFF;dJsw%3$2si2nB*;b(KDf zK;Y(&?m?wNWV#3MDV_3oayWmu9!U`km3T8IF$>HUT7TMiL^Eob2m`ktKl`lxionJ- zAlv2J09Hr&yq>f4dE~1)L{&}Q2i>$?hi~18MqgHV;C%Qo*r-FMKZpTM@jbV zOrcHG!$3s$lN2(tJk>cllodU>!s^4@_y<*0`D3%WB*uNVTnI}rCD_t|ZRQ4Jn&x4y zUFk4V{IM}{DW$PbM*&X1R&;TqXOd*|Ztb-@y)|*z3`wVV?Mx}XXn%n0AU|8j<@MML4m?nGcFLPZ<2kao3$LPa85F+AYbuZ z?ej>&T!0bF3TXkk46D`I5IC&&;TJT zqPVBY8(CF?piNj!fv5XS;bIozHwj~-M4;F;w7Lfi0%b~N8R-cLHNtU{&1Mr-)^N?j zMuM$jMlVlb4de*65jAZLKiqMH8WJmO6n$xkJ2$MAQDwv;Z_ zs#2{Hr_bht*)q<+rah-o(x84ztVy@NLf+3W4}Rbd)u5cerGEZ)3i-ewBF$;w>bo2UQ@Kf%FYW@?{SM- zb7}VQEtPdOk+);K8bthU%*T$#LL|Gzs3oq)*kH&Mkh&zEsOY?-r5ITbxm+IJR*8co zE!6hLB`wBjocVXgqr^(?ilE?x0M4OKG5F5_hsboTP<~wVV-O z(@L3$DM}GI1Eaiu)i#5A72Z0c9QRiDeThc%?A7~lhb)2-Jr0PtNFgxzQhs2l@c|v4 zltO_6XI~*jL_y@pwh=#=PhBhS{7vEzQq@Yfx%pIAb9;@AV1p+`J7IvY$Qqg4ebY2d zAZLP#`Q@_@mqO*C~x08kbs>kuf{* z$9?a1K4Xj!KpTPkixD`esX${pAi4-)C85QMqK=BW>9>$?{aUIKO71&0`UAa>@0wu* zn!C6UM?Sb%ji*HX5{zQ-W z2YmRIyEd1;Z`D63$t+cx4`OFR8{NAQ^FRa*Q5AI$Qfh!+E)!eCmI?p_O&vybpv12! z%0ZG$0@?Msd&HD^RFI!4RR8# zxI82&M7-ClR0T`di8GdZeuRBT5Xti)+6Ww;5sF88_vX5$a_3DIEs40;j)KTE0CY$7 zkoJuL#+}CM)-1Wx)K&7@#FGi>Pmr;}qBI}19!PrI#c>8wkoQMITM5^$jGwzPt~ycg z&>>F}E?xx_1=R4e=$Hq1%tLFGiS~2lm7J$=^jRbp>)u{0SZ_{Y(f1iTkrQSQp^>j=@rR8|Ip1dunJyJ=o4sO2HKxIm$7Pk1AJL_jEn_3rJgSRI8<4rLl0 zEl-+|>ANG>jd!KiL)ft9xEz~rjYq1q9k)A%INo#mmfL{@OC=m68K%RP35o^~d=dEK zE|JRh`3fD~AE04`@9JiG@E(p+0fS~HSV1X^=@K-$p@yZH))`-$!dPi}rYxS|dgE1YT=qZQ0XLlA*g4`H`c@IWk-Y>v(=iqT$jGKF~vUP%i00;MPy z6(V^Nu@FipqwW%urk^%w18VG?unkiR7(JzH+4@M}fFc#xg$d-&hPbPE4PWWCVK2pT)Hd>X-(X4e;PFlEyVqHL5HljPu>3OR z%@_PHh;hV4I^e4`oy_lwK4UoDu~zcfFx~^uLfb<8+b-_uyP>adwOb~EBypS8L}XMg zB{45$bxcp0bexE@bhMQbphv&qe{GUYat5{5!LN6hIMoau9!OA!OtSRFcsDSNACHZ#n2}y3{1tjx}k3hRlXAn8Ni{nmmD|_Q;(< zo(PvuJGjjKC499;Q*?CN7g1{n*bpK&_m&cEb9PWh*kgT2TKP*xfqjr9`e~s@Y_4U_ zyL~12QX;1D;G1%^vWeO%lAgw<(Ti(OhJyP_PJ&o*N(+joXy%4F%z`Y4*9yh%VS0Dw z0AUuINfuQd*$iFzrV2eXkOV^NX4pq)NPVwtp{51FWg}sIeC=|org~Fc>bbSunL%V9 z`sXU!#E|0¹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 B`WOHJ literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/random.pyc b/PythonHome/Lib/random.pyc new file mode 100644 index 0000000000000000000000000000000000000000..9e61c7df180cd1a97b73338924861788c91d0c1e GIT binary patch literal 25353 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 literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/re.pyc b/PythonHome/Lib/re.pyc new file mode 100644 index 0000000000000000000000000000000000000000..631953dea1a74152abbcfdb2cf45459ea5ba024b GIT binary patch literal 13045 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 g`+)cI(C9#EpnRb`P#(HCG&+$Yp z?oDeaULoW@z$ZZh3BCXi{T#gU$TJ@Re!p{PXI#4GBr|z7 zNGo%F484QL{23&LhOj|YXV~W{1B-oS>ZSFcdqUG1I@l}?hH0g-Fl|An+LE-DS(Ic^ znQM|G(HN0}u_mXukRWLcRNiF)A*v>8xmKGgADJZ29BN}Y(r6$5?U2=w)J3i{TR zfxd1E$~p$hItI$tRR+p7l!3BMWuUAeGA-=2ovFtfU^6;4`z}dH@-2|?8i-v0IqV8EKvd$CU^d1|=?XEI}F6aAv-AI~O|Y+yAe5HhK?9VfqAjGv_=4wOqL>653aB~&PA zi)^$vTOuEWFU7`yPvHVhWlfszQdLo6mcVU&^nUjEBcft!a;%@laW=|q953>NHA;K! zOMV9o0iPNk4aF)L#9;`k9vyme>cee}*LFxzOSf^aA4U91$D(CUQ0C|=)gnr)<1t)F zya5-Wm9$H@{|^|ed!KrOy{8B|^r*=}Q;Ijq41FHBDKOy65O}ByBq27!hZ=ffD_#e`H@sEvroZC7 z>fOZe>mKlcq`^Z+&8We76A6nEsLMGAyW7i9D&ovO*kw5`xaycY#2 z$0DsD-iW#{?>%}|rq|?TQBFYH9QxRoC%>0zhl@doi1?$NbO<^u45WAnCEzgxLOO~f zKnVEO&h^_;#lm<3{PRP||w$l*_6fA=zGn2ilsXN=Sop6C|b_KJ6&_ z$N6z=#)VB2XU_s=UOFWFNJE01?t?E)=*&_5bxdHouDXXW8xk@8PI1EGr4{EvRmH3I z-@}L|9?@K^HTo+6-tZV}hcj20Nz3WVpue=P6;gEB-%-yqeFU9U6^DP}WsVc=2mlWz z=34|wZ(c0!GL`6i9Tmb=d+i8NAyDX#K4hIhIdq)@@rI6r1>={qYLD`uL#Q>V6D%n$ z`F1&kii18wn`);0w(R<{#@g}ZV|l<@pzE==d@+-3R<#8;3bd~Jj*5lm8|7)&W7%M+ z%d$ZaJf9j`{u~X$)YT87t!v&2x@J~a)Kw@cJX_DZW~z$#&H z{eWX{kZ3XbAvo@~$*W(O zK}@yDLt9rZUzY$8pW_2v;_Y>}8^eofvP)AEBYV6`S}^|X`Q*$uWn}U*K;nbmi;;|Q*ZGK_Kmo#0x553305^+nyu@sU9CJ; z0rKwc}kzi&FeTJdgioV4=np2hh_*0*^9Z^gci>Ex`lewba3XWt&#k zJMB6*0JIr!&&^zPaKmA;TK2qyd7!opFN62GCdfv{_D6#>=-Z%s^mc~f%kC!h%^a(G zvHkVYAf50Z9Qqc=gS>AHE*!j)!gef^xE!Rw{w6TZ9$2%;Oz9j0<_3s(HE*@Hgv>Du zRjAoZbzyCZk;{Pe!iBl16bbidSpOE~F~hJ{72#bB~t^suTQI%9GxM(FX8@ zA_qK$#1ro~Zt4R7b#{ekDc9Dl?0I;m-6a9dq+av&rZ?C961CZLJi}v{K%`#tmeH)a zFNgt6`*EC%2e_58n#6HG&*4?(F$IENJ;vkQ=siZ=ptVP@BmIcwg2v93Q0}58+K%3H WQG1(TXa;Ng9lzsU_g4$J&ig-34<>d1 literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/rexec.pyc b/PythonHome/Lib/rexec.pyc new file mode 100644 index 0000000000000000000000000000000000000000..9f5b71ea0b074b060495cc47f538742b2482f606 GIT binary patch literal 23253 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 Ry+V;GLAl9LBekpYe*xa!?;ZdE literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/rlcompleter.pyc b/PythonHome/Lib/rlcompleter.pyc new file mode 100644 index 0000000000000000000000000000000000000000..faf237e76f9dab44656e3ff983f9bb2cb5dd211e GIT binary patch literal 5858 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 literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/runpy.pyc b/PythonHome/Lib/runpy.pyc new file mode 100644 index 0000000000000000000000000000000000000000..a66ac7ff9b7174221795d183948bc82a1c47ed80 GIT binary patch literal 8308 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 X7wXQ$OzT3cJ@N8r?UXZFYdik~WeB_8 literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/sched.pyc b/PythonHome/Lib/sched.pyc new file mode 100644 index 0000000000000000000000000000000000000000..b3f9ece42cc01c3388520af40c18ae0263afdb5e GIT binary patch literal 4859 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 lpHmbv2JoC~2v5C+5HaZd#jSPe=C;;}A z6-3FOe75!53BS*iul38SgkeQ|-|?Xb7Ry^f4UhpKz^eiq00v+~_zXcwI)XZcT?E+( z6pkR%U|GjtHDr@cWARv}WA<}Dyq;*mPhX*-DmS~<9&0p?jK%!{%iN>AF-Jlp6;)1E z?TWvuhCJrh1#FNiaglM^=GqClD~Tr(pRkF@7-vN{@b^j SlQd(Qs#qn#h0=jmTKxhhqgpKh literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/shelve.pyc b/PythonHome/Lib/shelve.pyc new file mode 100644 index 0000000000000000000000000000000000000000..b09bcd1da176a585056a4bbd30b4bf046eaadec7 GIT binary patch literal 9862 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 Cv_Y=` literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/site-packages/easy_install.pyc b/PythonHome/Lib/site-packages/easy_install.pyc new file mode 100644 index 0000000000000000000000000000000000000000..68fd9e8dbd0fa804195f04d5153b1f4718f02e0d GIT binary patch literal 302 zcmYjK%Sr<=6g^35EmFa~UR0sx^rp_D z7w);wbB;J(U)|xb=`aST`b?P~2{f<;41;FaaeUuHb7%p_;RUt=%n1AdEYR-+oBEgEWF}l=@s*NEhY5%R(MX;tkgS4cvY2WNen`|}@z3O)A)1>yC*!268*~&*f QIP+9=(v)Dz=j?|40czq#`. + +Install a package from `PyPI`_: + +:: + + $ pip install SomePackage + [...] + Successfully installed SomePackage + +Show what files were installed: + +:: + + $ pip show --files SomePackage + Name: SomePackage + Version: 1.0 + Location: /my/env/lib/pythonx.x/site-packages + Files: + ../somepackage/__init__.py + [...] + +List what packages are outdated: + +:: + + $ pip list --outdated + SomePackage (Current: 1.0 Latest: 2.0) + +Upgrade a package: + +:: + + $ pip install --upgrade SomePackage + [...] + Found existing installation: SomePackage 1.0 + Uninstalling SomePackage: + Successfully uninstalled SomePackage + Running setup.py install for SomePackage + Successfully installed SomePackage + +Uninstall a package: + +:: + + $ pip uninstall SomePackage + Uninstalling SomePackage: + /my/env/lib/pythonx.x/site-packages/somepackage + Proceed (y/n)? y + Successfully uninstalled SomePackage + + +.. _PyPI: http://pypi.python.org/pypi/ + + diff --git a/PythonHome/Lib/site-packages/pip-1.5.6.dist-info/METADATA b/PythonHome/Lib/site-packages/pip-1.5.6.dist-info/METADATA new file mode 100644 index 0000000000..12ecc51987 --- /dev/null +++ b/PythonHome/Lib/site-packages/pip-1.5.6.dist-info/METADATA @@ -0,0 +1,98 @@ +Metadata-Version: 2.0 +Name: pip +Version: 1.5.6 +Summary: A tool for installing and managing Python packages. +Home-page: https://pip.pypa.io/ +Author: The pip developers +Author-email: python-virtualenv@groups.google.com +License: MIT +Keywords: easy_install distutils setuptools egg virtualenv +Platform: UNKNOWN +Classifier: Development Status :: 5 - Production/Stable +Classifier: Intended Audience :: Developers +Classifier: License :: OSI Approved :: MIT License +Classifier: Topic :: Software Development :: Build Tools +Classifier: Programming Language :: Python :: 2 +Classifier: Programming Language :: Python :: 2.6 +Classifier: Programming Language :: Python :: 2.7 +Classifier: Programming Language :: Python :: 3 +Classifier: Programming Language :: Python :: 3.1 +Classifier: Programming Language :: Python :: 3.2 +Classifier: Programming Language :: Python :: 3.3 +Provides-Extra: testing +Requires-Dist: pytest; extra == 'testing' +Requires-Dist: virtualenv (>=1.10); extra == 'testing' +Requires-Dist: scripttest (>=1.3); extra == 'testing' +Requires-Dist: mock; extra == 'testing' + + +Project Info +============ + +* Project Page: https://github.com/pypa/pip +* Install howto: https://pip.pypa.io/en/latest/installing.html +* Changelog: https://pip.pypa.io/en/latest/news.html +* Bug Tracking: https://github.com/pypa/pip/issues +* Mailing list: http://groups.google.com/group/python-virtualenv +* Docs: https://pip.pypa.io/ +* User IRC: #pypa on Freenode. +* Dev IRC: #pypa-dev on Freenode. + +Quickstart +========== + +First, :doc:`Install pip `. + +Install a package from `PyPI`_: + +:: + + $ pip install SomePackage + [...] + Successfully installed SomePackage + +Show what files were installed: + +:: + + $ pip show --files SomePackage + Name: SomePackage + Version: 1.0 + Location: /my/env/lib/pythonx.x/site-packages + Files: + ../somepackage/__init__.py + [...] + +List what packages are outdated: + +:: + + $ pip list --outdated + SomePackage (Current: 1.0 Latest: 2.0) + +Upgrade a package: + +:: + + $ pip install --upgrade SomePackage + [...] + Found existing installation: SomePackage 1.0 + Uninstalling SomePackage: + Successfully uninstalled SomePackage + Running setup.py install for SomePackage + Successfully installed SomePackage + +Uninstall a package: + +:: + + $ pip uninstall SomePackage + Uninstalling SomePackage: + /my/env/lib/pythonx.x/site-packages/somepackage + Proceed (y/n)? y + Successfully uninstalled SomePackage + + +.. _PyPI: http://pypi.python.org/pypi/ + + diff --git a/PythonHome/Lib/site-packages/pip-1.5.6.dist-info/RECORD b/PythonHome/Lib/site-packages/pip-1.5.6.dist-info/RECORD new file mode 100644 index 0000000000..488a362688 --- /dev/null +++ b/PythonHome/Lib/site-packages/pip-1.5.6.dist-info/RECORD @@ -0,0 +1,374 @@ +pip/__init__.py,sha256=j6Zp28eSA6gvpf2Vm7gb4ybz5Y_OKfXxY3a146aRH6g,9450 +pip/__main__.py,sha256=9JBJhprGRLUy1fEvAdufs0tsjKFAvFAY_nTde6GDkHk,116 +pip/basecommand.py,sha256=N_nE7BCcoMA7t2nRNTiJB8T__1XqI74SJI2G72VaM2E,6578 +pip/baseparser.py,sha256=DZKWTOA1OeD5mLyBUx183Jx-M16cqWOXPZZuJN4-4j8,8162 +pip/cmdoptions.py,sha256=C0JuSfhGIgrp2hMoVDYVPekPlPiG0wIFcIIFDbrsatg,9507 +pip/download.py,sha256=jnZvTGYutxPtgJvF0URMnsBGkTABNrfgFevu5QmscfE,22580 +pip/exceptions.py,sha256=wAoboA4PdhGN7xH-ayf_dcDFPYZe9XAivAlZJbOgCN4,1086 +pip/index.py,sha256=CLPb0crVhOQ3aZpl4feUKpf1pVR6qLhBiJTa71PoIkM,40403 +pip/locations.py,sha256=YyFyCLYADKgT5x-Ctj_LeZl5bEzkbBXuR2Iv8IbVqDA,6202 +pip/log.py,sha256=1fW7cVRIRBhfqWz4JH2HhJRHzVQ4PJTRbolRj3S33f8,9455 +pip/pep425tags.py,sha256=jb5Rq395Gz_Uv8kn3L9Im1HX7EhEj8nqyYX0nXulzWo,2969 +pip/req.py,sha256=DMGDl2N30fmLzh4VzhqQyix-bifSRKNhp2c_OS_gza8,83557 +pip/runner.py,sha256=VkcZKNikprpDOSl2Y3m0FaQbdGuYsoHkxdhjtL0N3oA,431 +pip/status_codes.py,sha256=sEFHUaUJbqv8iArL3HAtcztWZmGOFX01hTesSytDEh0,116 +pip/util.py,sha256=GTnXa80tWauVlIvSQiYeNw12ly5X4hMPmDbRVQ79hwk,24172 +pip/wheel.py,sha256=PwTueHq1c30KvZF3-0wlTTUiR8hxBpE3THxN1bc0eS8,20618 +pip/_vendor/__init__.py,sha256=f-xO4dF7jRP89yrL4h26_nULYgYTzgnTgUFlkDasJrc,266 +pip/_vendor/pkg_resources.py,sha256=0y2CkvxQcHCBVOmTCNvdMN8hTPPUogThjhkCxegggII,100025 +pip/_vendor/re-vendor.py,sha256=PcdZ40d0ohMsdJmA4t0AeAWbPXi1tFsvAwA5KE5FGeY,773 +pip/_vendor/six.py,sha256=whAS1kvmixxh-pKqb5qQ05-fHMnGjuKyU6m7_wa09O4,23462 +pip/_vendor/_markerlib/__init__.py,sha256=2hgtRuYDOrimZF9-ENCkrP8gnJ59HZEtlk-zoTEvn1Y,564 +pip/_vendor/_markerlib/markers.py,sha256=YuFp0-osufFIoqnzG3L0Z2fDCx4Vln3VUDeXJ2DA_1I,3979 +pip/_vendor/colorama/__init__.py,sha256=eABG0aR8L-8JfIiftmvixrDZvqHawB7KIIxiRdKsi1k,217 +pip/_vendor/colorama/ansi.py,sha256=spKO9jqXAB9POAj6M3bZLrdCf-W9wUVeDCqF664WSGs,1039 +pip/_vendor/colorama/ansitowin32.py,sha256=C0mA80tFRvkdHVTHzvyrCzsI0CNQ1gY9ng6deCxkbGY,6664 +pip/_vendor/colorama/initialise.py,sha256=sL44vQFKG5BAoFgoIxfhH0wG2NnLBw9mtnWFVtXkHGs,1297 +pip/_vendor/colorama/win32.py,sha256=tMAHgaTSySAt5BI5hBoID6oshHIYnJBlUqDsOoHbV0w,4911 +pip/_vendor/colorama/winterm.py,sha256=RhWJPcGA_T1knfS-84AXpQ0C7cn8XWE6iQkqy1GPsmk,4206 +pip/_vendor/distlib/__init__.py,sha256=kTBiZ-2Ndb1k7wb8yCvl7iRBCDTnvaOR15qf32RgvsY,581 +pip/_vendor/distlib/compat.py,sha256=pVILHBDu1P72lO1lEgPFpwRWGs4Cj2-eo_xOPLKjprk,38875 +pip/_vendor/distlib/database.py,sha256=reYrKl6tqHs3eOrMrdXX4W0OGlBqathuqSzCy-696MI,49138 +pip/_vendor/distlib/index.py,sha256=D-Zz8pQ6Gtr4t7HlFebU36P9inMPSfExmit061S8DUk,19476 +pip/_vendor/distlib/locators.py,sha256=Vi88LbYqF981rmCc8dbD9qnmt5MeJzv7qiAlvgrK3vs,46946 +pip/_vendor/distlib/manifest.py,sha256=I-JG2bVBN3Zmf4gpt9MFjgsukcIt0rMrz95jQ1kwbgE,13497 +pip/_vendor/distlib/markers.py,sha256=iRrVWwpyVwjkKJSX8NEQ92_MRMwpROcfNGKCD-Ch1QM,6282 +pip/_vendor/distlib/metadata.py,sha256=IS0Q8hNbQWEhaLtItUlLxYC3j9zVtFD76DgXbHxcRZE,36815 +pip/_vendor/distlib/resources.py,sha256=H9QmD7R_8t-iLxZne9EnjAHAdSEbJ22PYotEppOGxts,9432 +pip/_vendor/distlib/scripts.py,sha256=0bIHpJFwyvymJ4CEnm1-x3AcJZbYTEkhBAKuas295Ic,12307 +pip/_vendor/distlib/t32.exe,sha256=snr0x6iR5Yd7ZndiuvGMuuQGg8VklUc5538uQcOeVYQ,91136 +pip/_vendor/distlib/t64.exe,sha256=71TYxgPfviERRKhyYaXPx2pl4o4ugs5zNWuIMLlm7ss,94720 +pip/_vendor/distlib/util.py,sha256=UBy5ki-nyb0nJyM_-TlXSfni_cEOI4r6LzglMMB_1zc,51230 +pip/_vendor/distlib/version.py,sha256=FgTBNWH7dDY12fqTFy6nATw21wV8kKJw5G19aFouwDE,22996 +pip/_vendor/distlib/w32.exe,sha256=QoyveFPxLH-db4j2YDzb-VmP7DmGT1vHwPOLGpzc3uw,87040 +pip/_vendor/distlib/w64.exe,sha256=haGpLW73-UaPHkjhKaQVPTBJCZ9Lg1rMBZdhpi7f_V8,91648 +pip/_vendor/distlib/wheel.py,sha256=TUMl4Pzri_jglkvr2jZ4GJfWAumG3VNzT2CaW7oBXQQ,38259 +pip/_vendor/distlib/_backport/__init__.py,sha256=bqS_dTOH6uW9iGgd0uzfpPjo6vZ4xpPZ7kyfZJ2vNaw,274 +pip/_vendor/distlib/_backport/misc.py,sha256=KWecINdbFNOxSOP1fGF680CJnaC6S4fBRgEtaYTw0ig,971 +pip/_vendor/distlib/_backport/shutil.py,sha256=AUi8718iRoJ9K26mRi-rywtt8Gx7ykvrvbUbZszjfYE,25650 +pip/_vendor/distlib/_backport/sysconfig.cfg,sha256=swZKxq9RY5e9r3PXCrlvQPMsvOdiWZBTHLEbqS8LJLU,2617 +pip/_vendor/distlib/_backport/sysconfig.py,sha256=7WdYP0wbw8izH1eAEGNA-HXUyJrhzIAGK_LniUs4UNI,26958 +pip/_vendor/distlib/_backport/tarfile.py,sha256=bjyTNONZb-YEXrHFLExOSuagtSOoPaONP2UUoxwkAqE,92627 +pip/_vendor/html5lib/__init__.py,sha256=6fwIe3NEcpx7aLb1bBXUpsDgJFE9PnbpRADB7i2QhBw,714 +pip/_vendor/html5lib/constants.py,sha256=w_Lrxu8h6qE4KATYy0SL5hiJ5ebuB28SlCcdXUHf6to,87346 +pip/_vendor/html5lib/html5parser.py,sha256=qMHEOEahKSZzLHHkqLRVbuIJYgAteVR-nmkjMp59Tvw,117029 +pip/_vendor/html5lib/ihatexml.py,sha256=MT12cVXAKaW-ALUkUeN175HpUP73xK8wAIpPzQ8cgfI,16581 +pip/_vendor/html5lib/inputstream.py,sha256=qa-xwqbm-w250UR-uVzooXPSHFI4Ho6drLhPl7VWvHI,30636 +pip/_vendor/html5lib/sanitizer.py,sha256=sg7g5CXF9tfvykIoSVAvA8647MgScy3ncZC7IYH-8SA,16428 +pip/_vendor/html5lib/tokenizer.py,sha256=6Uf8sDUkvNn661bcBSBYUCTfXzSs9EyCTiPcj5PAjYI,76929 +pip/_vendor/html5lib/utils.py,sha256=T-BFeUVGJDjVCRbNoqar2qxn8jEoCOOJXE1nH0nDHEQ,2545 +pip/_vendor/html5lib/filters/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 +pip/_vendor/html5lib/filters/_base.py,sha256=z-IU9ZAYjpsVsqmVt7kuWC63jR11hDMr6CVrvuao8W0,286 +pip/_vendor/html5lib/filters/alphabeticalattributes.py,sha256=fpRLbz6TCe5yXEkGmyMlJ80FekWsTR-sHk3Ano0U9LQ,624 +pip/_vendor/html5lib/filters/inject_meta_charset.py,sha256=xllv1I7unxhcyZTf3LTsv30wh2mAkT7wmTZx7zIhpuY,2746 +pip/_vendor/html5lib/filters/lint.py,sha256=6rlGRUTxD5KWwEVoXVHI_PeyUHN6Vw2v_ovg0YiHsDA,4306 +pip/_vendor/html5lib/filters/optionaltags.py,sha256=4ozLwBgMRaxe7iqxefLQpDhp3irK7YHo9LgSGsvZYMw,10500 +pip/_vendor/html5lib/filters/sanitizer.py,sha256=MvGUs_v2taWPgGhjxswRSUiHfxrqMUhsNPz-eSeUYUQ,352 +pip/_vendor/html5lib/filters/whitespace.py,sha256=LbOUcC0zQ9z703KNZrArOr0kVBO7OMXjKjucDW32LU4,1142 +pip/_vendor/html5lib/serializer/__init__.py,sha256=xFXFP-inaTNlbnau5c5DGrH_O8yPm-C6HWbJxpiSqFE,490 +pip/_vendor/html5lib/serializer/htmlserializer.py,sha256=bSXUuFJB6s-ODOl0nzFN0UA6xlQRU-BwYamPeJvsNSE,12909 +pip/_vendor/html5lib/treeadapters/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 +pip/_vendor/html5lib/treeadapters/sax.py,sha256=3of4vvaUYIAic7pngebwJV24hpOS7Zg9ggJa_WQegy4,1661 +pip/_vendor/html5lib/treebuilders/__init__.py,sha256=Xz4X6B5DA1R-5GyRa44j0sJwfl6dUNyb0NBu9-7sK3U,3405 +pip/_vendor/html5lib/treebuilders/_base.py,sha256=Xf0FZVcVwIQS6tEseJdj5wKbYucbNCnbAsnsG4lONis,13711 +pip/_vendor/html5lib/treebuilders/dom.py,sha256=ylkIlwEV2NsIWBpwEtfqF0LVoCGg4oXazEWs4-486jk,8469 +pip/_vendor/html5lib/treebuilders/etree.py,sha256=etbO6yQlyV46rWlj9mSyVqQOWrgoHgyJ01Tut4lWZkk,12621 +pip/_vendor/html5lib/treebuilders/etree_lxml.py,sha256=z3Bnfm2MstEEb_lbaAeicl5l-ab6MSQa5Q1ZZreK7Pc,14031 +pip/_vendor/html5lib/treewalkers/__init__.py,sha256=44g-xYZEoYxzkMu6CepBTLm4m-g9iy7Vm_IG8PWAbhY,2323 +pip/_vendor/html5lib/treewalkers/_base.py,sha256=hnL6zMgGJoGqEJYKVKveDmfpz1d2xriyuuau6479xq4,6919 +pip/_vendor/html5lib/treewalkers/dom.py,sha256=mAg05wBWN2k-CGPoo0KNxa55QAlHciNccp8AezCa8j8,1457 +pip/_vendor/html5lib/treewalkers/etree.py,sha256=waFU6dxcV5y4SEMyxZpQ9M4I5pKpMmCtUSN1GbuCVcE,4625 +pip/_vendor/html5lib/treewalkers/genshistream.py,sha256=IbBFrlgi-59-K7P1zm0d7ZFIknBN4c5E57PHJDkx39s,2278 +pip/_vendor/html5lib/treewalkers/lxmletree.py,sha256=vWfXWK3GOSrq2trQm2aPmIRWPhVuYDZ3g9Fu8hUeBQg,6215 +pip/_vendor/html5lib/treewalkers/pulldom.py,sha256=9W6i8yWtUzayV6EwX-okVacttHaqpQZwdBCc2S3XeQ4,2302 +pip/_vendor/html5lib/trie/__init__.py,sha256=mec5zyJ5wIKRM8819gIcIsYQwncg91rEmPwGH1dG3Ho,212 +pip/_vendor/html5lib/trie/_base.py,sha256=WGY8SGptFmx4O0aKLJ54zrIQOoyuvhS0ngA36vAcIcc,927 +pip/_vendor/html5lib/trie/datrie.py,sha256=EQpqSfkZRuTbE-DuhW7xMdVDxdZNZ0CfmnYfHA_3zxM,1178 +pip/_vendor/html5lib/trie/py.py,sha256=wXmQLrZRf4MyWNyg0m3h81m9InhLR7GJ002mIIZh-8o,1775 +pip/_vendor/requests/__init__.py,sha256=Rl423kV-MBTFDiTtEOJiP9CuaubFSi8rHaqzq1KBN0w,1856 +pip/_vendor/requests/adapters.py,sha256=fp4t_woMNJPv8vikcrLbkkDxhJHJMZ3h8MlgtKvpuE8,14608 +pip/_vendor/requests/api.py,sha256=4xrabBN80yaqHxsomHVQD09v2VndgCz1cSsEnRvGGL0,4344 +pip/_vendor/requests/auth.py,sha256=x2bFqHK3Lkbm7qPUyh_dAqYLTDTotBi-1za9EpCdA0U,6123 +pip/_vendor/requests/cacert.pem,sha256=ak7q_q8ozHdQ9ff27U-E1vCNrLisFRQSMy9zJkdpQlM,308434 +pip/_vendor/requests/certs.py,sha256=wSaqhSNoB0igp6Da-hWw0jtXICKXBbL8aS9swthlt50,544 +pip/_vendor/requests/compat.py,sha256=JGrJPV2YGatzwrexl9kSt8Z8QtmFboRZH9ywsLK_MMA,2556 +pip/_vendor/requests/cookies.py,sha256=BjMKtrI8TXQD5oQVeToYtkRBF149eI85UhWsBGwsJac,16686 +pip/_vendor/requests/exceptions.py,sha256=z-3QpicafKtIh85bMEaClL2OpNPdsc6TP_83KcsVh8Y,1877 +pip/_vendor/requests/hooks.py,sha256=9vNiuiRHRd5Qy6BX_0p1H3NsUzDo1M_HaFR2AFL41Tg,820 +pip/_vendor/requests/models.py,sha256=OYZOkemxZPpeTp5cvhdx-gAnl9bW82wdnGIr4uoVH20,26436 +pip/_vendor/requests/sessions.py,sha256=kwPPNj1M3D6yfHPcygUERvfqWaSx8odBijhqKTqRX_Q,22290 +pip/_vendor/requests/status_codes.py,sha256=LYpqLv4AEKuTPby-QSvgl_gI7fcVlUDqSBcndIwX-Qg,3136 +pip/_vendor/requests/structures.py,sha256=d7f7ZXZZzgZtvrBQBZA1boJYX_QlP1YqL-_xtpzImGw,3541 +pip/_vendor/requests/utils.py,sha256=MxSUha_2szwhfLKmGg5bolxt6lA6OghSvVZ4xMZwQhM,19973 +pip/_vendor/requests/packages/__init__.py,sha256=aXkbNCjM_WhryRBocE4AaA_p7-CTxL5LOutY7XzKm4s,62 +pip/_vendor/requests/packages/chardet/__init__.py,sha256=8-39Dg2qEuod5DNN7RMdn2ZYOO9zFU3fFfaE80iDWGc,1295 +pip/_vendor/requests/packages/chardet/big5freq.py,sha256=D8oTdz-GM7Jg8TsaWJDm65vM_OLHC3xub6qUJ3rOgsQ,82594 +pip/_vendor/requests/packages/chardet/big5prober.py,sha256=XX96C--6WKYW36mL-z7pJSAtc169Z8ZImByCP4pEN9A,1684 +pip/_vendor/requests/packages/chardet/chardetect.py,sha256=8g-dRSA97bSE6M25Tqe1roKKtl3XHSMnqi6vTzpHNV0,1141 +pip/_vendor/requests/packages/chardet/chardistribution.py,sha256=cUARQFr1oTLXeJCDQrDRkUP778AvSMzhSCnG8VLCV58,9226 +pip/_vendor/requests/packages/chardet/charsetgroupprober.py,sha256=0lKk7VE516fgMw119tNefFqLOxKfIE9WfdkpIT69OKU,3791 +pip/_vendor/requests/packages/chardet/charsetprober.py,sha256=Z48o2KiOj23FNqYH8FqzhH5m1qdm3rI8DcTm2Yqtklg,1902 +pip/_vendor/requests/packages/chardet/codingstatemachine.py,sha256=E85rYhHVMw9xDEJVgiQhp0OnLGr6i2r8_7QOWMKTH08,2318 +pip/_vendor/requests/packages/chardet/compat.py,sha256=5mm6yrHwef1JEG5OxkPJlSq5lkjLVpEGh3iPgFBkpkM,1157 +pip/_vendor/requests/packages/chardet/constants.py,sha256=-UnY8U7EP7z9fTyd09yq35BEkSFEAUAiv9ohd1DW1s4,1335 +pip/_vendor/requests/packages/chardet/cp949prober.py,sha256=FMvdLyB7fejPXRsTbca7LK1P3RUvvssmjUNyaEfz8zY,1782 +pip/_vendor/requests/packages/chardet/escprober.py,sha256=q5TcQKeVq31WxrW7Sv8yjpZkjEoaHO8S92EJZ9hodys,3187 +pip/_vendor/requests/packages/chardet/escsm.py,sha256=7iljEKN8lXTh8JFXPUSwlibMno6R6ksq4evLxbkzfro,7839 +pip/_vendor/requests/packages/chardet/eucjpprober.py,sha256=5IpfSEjAb7h3hcGMd6dkU80O900C2N6xku28rdYFKuc,3678 +pip/_vendor/requests/packages/chardet/euckrfreq.py,sha256=T5saK5mImySG5ygQPtsp6o2uKulouCwYm2ElOyFkJqU,45978 +pip/_vendor/requests/packages/chardet/euckrprober.py,sha256=Wo7dnZ5Erw_nB4H-m5alMiOxOuJUmGHlwCSaGqExDZA,1675 +pip/_vendor/requests/packages/chardet/euctwfreq.py,sha256=G_I0BW9i1w0ONeeUwIYqV7_U09buIHdqh-wNHVaql7I,34872 +pip/_vendor/requests/packages/chardet/euctwprober.py,sha256=upS2P6GuT5ujOxXYw-RJLcT7A4PTuo27KGUKU4UZpIQ,1676 +pip/_vendor/requests/packages/chardet/gb2312freq.py,sha256=M2gFdo_qQ_BslStEchrPW5CrPEZEacC0uyDLw4ok-kY,36011 +pip/_vendor/requests/packages/chardet/gb2312prober.py,sha256=VWnjoRa83Y6V6oczMaxyUr0uy48iCnC2nzk9zfEIRHc,1681 +pip/_vendor/requests/packages/chardet/hebrewprober.py,sha256=8pdoUfsVXf_L4BnJde_BewS6H2yInV5688eu0nFhLHY,13359 +pip/_vendor/requests/packages/chardet/jisfreq.py,sha256=ZcL4R5ekHHbP2KCYGakVMBsiKqZZZAABzhwi-uRkOps,47315 +pip/_vendor/requests/packages/chardet/jpcntx.py,sha256=9fJ9oS0BUarcdZNySwmzVRuT03sYdClSmFwXDj3yVNg,19104 +pip/_vendor/requests/packages/chardet/langbulgarianmodel.py,sha256=ZyPsA796MSVhYdfWhMCgKWckupAKAnKqWcE3Cl3ej6o,12784 +pip/_vendor/requests/packages/chardet/langcyrillicmodel.py,sha256=fkcd5OvogUp-GrNDWAZPgkYsSRCD2omotAEvqjlmLKE,17725 +pip/_vendor/requests/packages/chardet/langgreekmodel.py,sha256=QHMy31CH_ot67UCtmurCEKqKx2WwoaKrw2YCYYBK2Lw,12628 +pip/_vendor/requests/packages/chardet/langhebrewmodel.py,sha256=4ASl5vzKJPng4H278VHKtRYC03TpQpenlHTcsmZH1rE,11318 +pip/_vendor/requests/packages/chardet/langhungarianmodel.py,sha256=SXwuUzh49_cBeMXhshRHdrhlkz0T8_pZWV_pdqBKNFk,12536 +pip/_vendor/requests/packages/chardet/langthaimodel.py,sha256=-k7djh3dGKngAGnt3WfuoJN7acDcWcmHAPojhaUd7q4,11275 +pip/_vendor/requests/packages/chardet/latin1prober.py,sha256=g67gqZ2z89LUOlR7BZEAh4-p5a1yGWss9nWy8FCNm8Q,5241 +pip/_vendor/requests/packages/chardet/mbcharsetprober.py,sha256=9rOCjDVsmSMp6e7q2syqak22j7lrbUZhJhMee2gbVL0,3268 +pip/_vendor/requests/packages/chardet/mbcsgroupprober.py,sha256=SHRzNPLpDXfMJLA8phCHVU0WgqbgDCNxDQMolGX_7yk,1967 +pip/_vendor/requests/packages/chardet/mbcssm.py,sha256=UuiA4Ic8vEc0XpTKDneqZyiH2TwGuFVZxOxWJep3X_4,19608 +pip/_vendor/requests/packages/chardet/sbcharsetprober.py,sha256=Xq0lODqJnDgxglBiQI4BqTFiPbn63-0a5XNA5-hVu7U,4793 +pip/_vendor/requests/packages/chardet/sbcsgroupprober.py,sha256=8hLyH8RAG-aohBo7o_KciWVgRo42ZE_zEtuNG1JMRYI,3291 +pip/_vendor/requests/packages/chardet/sjisprober.py,sha256=1RjpQ2LU2gvoEB_4O839xDQVchWx2fG_C7_vXh52P5I,3734 +pip/_vendor/requests/packages/chardet/universaldetector.py,sha256=GkZdwNyNfbFWC8I1uqnzyhOUF7favWCqCOKqdQlx6gQ,6831 +pip/_vendor/requests/packages/chardet/utf8prober.py,sha256=7tdNZGrJY7jZUBD483GGMkiP0Tx8Fp-cGvWHoAsilHg,2652 +pip/_vendor/requests/packages/urllib3/__init__.py,sha256=sLIKv9dGJjDloiVXUBBjXDWWq8bM66kcvTH2SU_WZKg,1701 +pip/_vendor/requests/packages/urllib3/_collections.py,sha256=Oh1gxPZRqtOSy3pTV0pWQ949t9sjRAFMautsHiHP_pY,6557 +pip/_vendor/requests/packages/urllib3/connection.py,sha256=eug-y4_dOa-x9bxDlURwpqlZuQDhl9Tjre5D1S5bijE,6533 +pip/_vendor/requests/packages/urllib3/connectionpool.py,sha256=8eDsWYJzKYOyXMiP4CJqtLeychOw3iD_P20Ov-dbGUs,26904 +pip/_vendor/requests/packages/urllib3/exceptions.py,sha256=T-ILeqVPpEvrOYAq8XEyTF0X8XRWcFVGT2gMrF00km0,3364 +pip/_vendor/requests/packages/urllib3/fields.py,sha256=UuTJzGxUc9H1LPYZnD3f8GW308Vx_znb5pt4yimORsI,5976 +pip/_vendor/requests/packages/urllib3/filepost.py,sha256=tWPY33HnFM_RPpEU9PHv9D34n67w8ZRt80ZSsWIv0Kk,2512 +pip/_vendor/requests/packages/urllib3/poolmanager.py,sha256=bMYHdNaVI5O4YrJHr1T6tE2RYHEMzM2_K0cTy7uzX2M,8977 +pip/_vendor/requests/packages/urllib3/request.py,sha256=cXTcrr9d50Rt213ZXLgCf53KNWxe4LQ8lxSV1HBYa9E,5808 +pip/_vendor/requests/packages/urllib3/response.py,sha256=ff9-9sZkghNWCyeoECvImHspITTum7KOM20J2ia4SAw,10347 +pip/_vendor/requests/packages/urllib3/contrib/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 +pip/_vendor/requests/packages/urllib3/contrib/ntlmpool.py,sha256=VJ-GjxpYITxSj4UDKX0iqvHwaatyg2RA3PaTym5Wp6w,4741 +pip/_vendor/requests/packages/urllib3/contrib/pyopenssl.py,sha256=D1cbFXSoWj4ahM0azQdvIDFkvNnzMLxOvo1wnMrPo8M,15086 +pip/_vendor/requests/packages/urllib3/packages/__init__.py,sha256=EKCTAOjZtPR_HC50e7X8hS5j4bkFkN87XZOT-Wdpfus,74 +pip/_vendor/requests/packages/urllib3/packages/ordered_dict.py,sha256=HtHphtStJlorzQqoIat8zUH0lqLns416gfSO9y_aSAQ,8936 +pip/_vendor/requests/packages/urllib3/packages/six.py,sha256=U-rO-WBrFS8PxHeamSl6okKCjqPF18NhiZb0qPZ67XM,11628 +pip/_vendor/requests/packages/urllib3/packages/ssl_match_hostname/__init__.py,sha256=cOWMIn1orgJoA35p6pSzO_-Dc6iOX9Dhl6D2sL9b_2o,460 +pip/_vendor/requests/packages/urllib3/packages/ssl_match_hostname/_implementation.py,sha256=fK28k37hL7-D79v9iM2fHgNK9Q1Pw0M7qVRL4rkfFjQ,3778 +pip/_vendor/requests/packages/urllib3/util/__init__.py,sha256=nI42Lb9ShOOOl_uRDyJfZP_nxHCR4wTFJXmDa_GEe7c,622 +pip/_vendor/requests/packages/urllib3/util/connection.py,sha256=Df5MeJaIpPigbIxEa87ojZ7qxXm1-V9dhnc2m7S6lNA,1348 +pip/_vendor/requests/packages/urllib3/util/request.py,sha256=-mIHA_M2aZwEmW5PpNfxEi9B47YDmFcoTW5FvQ7prf4,1924 +pip/_vendor/requests/packages/urllib3/util/response.py,sha256=EVO-5Q1Wc9K61i3RIhPB83CXfnvZpphL_NNp0SLznzI,354 +pip/_vendor/requests/packages/urllib3/util/ssl_.py,sha256=0SJbyE9KURi8IjmOwo8sqmmit4sRkXf9eg_ODWOhSD0,4235 +pip/_vendor/requests/packages/urllib3/util/timeout.py,sha256=WGx3s4593QcpwyHLY1FpFZgGPiTdL26A2nJhsZa9Rj8,9236 +pip/_vendor/requests/packages/urllib3/util/url.py,sha256=ftfW-i1XtyFZEOEKfXLkKNmM7APmgNHbtcGWYr-6xdI,4273 +pip/backwardcompat/__init__.py,sha256=AcP5dr3nL-4AGxSwsFIEUcf9ki0ROUFwfc0IrIeHaJI,3756 +pip/commands/__init__.py,sha256=N_4io-oGcWF9-raDN5TYXbGlJFsx5po36HZmwgLso6I,2236 +pip/commands/bundle.py,sha256=tK8LU3Khjkrz65y3brNP71QOBkQCb9mlv9x8s1W02T4,1787 +pip/commands/completion.py,sha256=LnJgUrpGGO4x2Y8VdwhKda4kGZWMFO28P4jYzYT5Q8k,1838 +pip/commands/freeze.py,sha256=Hyx1gzMaTFwTMcP98fwNCRVvvrWenX9j1RBziLCIo0A,4664 +pip/commands/help.py,sha256=ETLg8xfv8uFwS3KvxmsCE-I56S15jUTvfkwaPAA18pE,927 +pip/commands/install.py,sha256=PPFxd9RyUpVxfkumnztooBdrUkMguDI6eRHS0IrePUE,12694 +pip/commands/list.py,sha256=FHf7H35AajbCuymiG2z8xAGNSx8W5CNZKj6Hh2QGo38,6814 +pip/commands/search.py,sha256=_4Mza0qEb6P1aDA2OROYd-KuOJg0NrITOtQoiCDJF5Q,4736 +pip/commands/show.py,sha256=ipjEcTrk-hgvFysSKJ5E9PSPXZGTuE3NIXLYvXnsdNk,2767 +pip/commands/uninstall.py,sha256=MF4zSLfMxnH3E8T673ORNWz0Bsc4C6LEI5KImpAQrck,2203 +pip/commands/unzip.py,sha256=_PeTWKOd_iRxPt_7njQ8jGFpjX006vobn593tcIyeUc,185 +pip/commands/wheel.py,sha256=gyzZ4dQ0Ua8cP2H3ihvuNbv2z87ov-1Irxpu3m2MQqo,7320 +pip/commands/zip.py,sha256=KECCb3oCHxJqDT3kUEnlf0udp31Ckoe8oyEKdS7EKNQ,14821 +pip/vcs/__init__.py,sha256=kS31hLmJ6BgKnBu8kvXKQlJEwoj1MxYE7wfRuFL-daM,8748 +pip/vcs/bazaar.py,sha256=qUIuIqDJqwZ_nP6WR52YwvYVy1lvIUmvaT-IdxDYUHo,4943 +pip/vcs/git.py,sha256=ib3TqDwJyfjBnSRFKVe_HhNdwkmfcOZfJHbqt2RUOVg,7898 +pip/vcs/mercurial.py,sha256=71ESfgxotPPPZjiH6sMTBWcj5TS8kjgJxVnWrRb3bwo,5820 +pip/vcs/subversion.py,sha256=P31K7o83JdcipIyuEVlnpSp5KZqakb4OJ1PKT-FB7C8,10640 +pip-1.5.6.dist-info/DESCRIPTION.rst,sha256=n5sT7bxCOnG9ej7TtEjjARQZ_n2ECqWFDiJK88BM0u0,1422 +pip-1.5.6.dist-info/entry_points.txt,sha256=1-e4WB_Fe8mWHrMi1YQo_s5knbh0lu_uRmd8Wb6MJfY,68 +pip-1.5.6.dist-info/METADATA,sha256=lUBJx4V5mJY0jPlxYlu1x4YUNML-AN4dn4Dv-EFX8-Y,2499 +pip-1.5.6.dist-info/metadata.json,sha256=QZKMcKbHx-PWAvCvO0LdJX7JZjzx_yoKl2TTi1yKEKE,1361 +pip-1.5.6.dist-info/RECORD,, +pip-1.5.6.dist-info/top_level.txt,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 +pip-1.5.6.dist-info/WHEEL,sha256=6lxp_S3wZGmTBtGMVmNNLyvKFcp7HqQw2Wn4YYk-Suo,110 +C:\Python27\Scripts\pip.exe,sha256=0f80zC7gr6wCWKPi6VMhTyroJYT32W6LCBJjr0xWRx4,91468 +C:\Python27\Scripts\pip2.exe,sha256=0f80zC7gr6wCWKPi6VMhTyroJYT32W6LCBJjr0xWRx4,91468 +C:\Python27\Scripts\pip2.7.exe,sha256=0f80zC7gr6wCWKPi6VMhTyroJYT32W6LCBJjr0xWRx4,91468 +pip/_vendor/requests/compat.pyc,, +pip/_vendor/requests/certs.pyc,, +pip/_vendor/distlib/util.pyc,, +pip/__init__.pyc,, +pip/_vendor/html5lib/treewalkers/genshistream.pyc,, +pip/_vendor/requests/packages/chardet/latin1prober.pyc,, +pip/_vendor/distlib/_backport/__init__.pyc,, +pip/vcs/bazaar.pyc,, +pip/_vendor/distlib/metadata.pyc,, +pip/_vendor/html5lib/treebuilders/__init__.pyc,, +pip/_vendor/html5lib/filters/alphabeticalattributes.pyc,, +pip/_vendor/requests/packages/urllib3/request.pyc,, +pip/_vendor/requests/packages/chardet/escprober.pyc,, +pip/_vendor/requests/adapters.pyc,, +pip/_vendor/requests/packages/chardet/langbulgarianmodel.pyc,, +pip/commands/completion.pyc,, +pip/_vendor/html5lib/html5parser.pyc,, +pip/_vendor/html5lib/filters/lint.pyc,, +pip/pep425tags.pyc,, +pip/_vendor/requests/packages/chardet/__init__.pyc,, +pip/_vendor/html5lib/filters/whitespace.pyc,, +pip/_vendor/requests/packages/chardet/euckrprober.pyc,, +pip/_vendor/html5lib/treebuilders/etree_lxml.pyc,, +pip/_vendor/distlib/database.pyc,, +pip/_vendor/html5lib/treeadapters/sax.pyc,, +pip/commands/wheel.pyc,, +pip/_vendor/requests/auth.pyc,, +pip/_vendor/html5lib/treewalkers/pulldom.pyc,, +pip/_vendor/html5lib/ihatexml.pyc,, +pip/_vendor/html5lib/treewalkers/_base.pyc,, +pip/commands/list.pyc,, +pip/_vendor/distlib/scripts.pyc,, +pip/_vendor/html5lib/filters/sanitizer.pyc,, +pip/vcs/git.pyc,, +pip/cmdoptions.pyc,, +pip/_vendor/requests/packages/urllib3/util/ssl_.pyc,, +pip/_vendor/requests/packages/urllib3/poolmanager.pyc,, +pip/_vendor/html5lib/inputstream.pyc,, +pip/_vendor/html5lib/sanitizer.pyc,, +pip/_vendor/colorama/win32.pyc,, +pip/util.pyc,, +pip/_vendor/distlib/resources.pyc,, +pip/_vendor/requests/packages/chardet/hebrewprober.pyc,, +pip/_vendor/requests/packages/urllib3/packages/ssl_match_hostname/_implementation.pyc,, +pip/_vendor/requests/packages/urllib3/packages/six.pyc,, +pip/_vendor/html5lib/trie/__init__.pyc,, +pip/_vendor/html5lib/__init__.pyc,, +pip/_vendor/requests/packages/chardet/charsetgroupprober.pyc,, +pip/_vendor/requests/packages/urllib3/packages/__init__.pyc,, +pip/_vendor/distlib/_backport/misc.pyc,, +pip/_vendor/requests/packages/chardet/gb2312freq.pyc,, +pip/_vendor/requests/packages/chardet/codingstatemachine.pyc,, +pip/runner.pyc,, +pip/_vendor/requests/packages/urllib3/util/url.pyc,, +pip/_vendor/requests/packages/urllib3/packages/ssl_match_hostname/__init__.pyc,, +pip/_vendor/distlib/_backport/sysconfig.pyc,, +pip/_vendor/requests/packages/chardet/langgreekmodel.pyc,, +pip/_vendor/requests/packages/__init__.pyc,, +pip/commands/show.pyc,, +pip/_vendor/requests/packages/urllib3/util/__init__.pyc,, +pip/_vendor/_markerlib/__init__.pyc,, +pip/_vendor/requests/packages/chardet/jpcntx.pyc,, +pip/_vendor/colorama/initialise.pyc,, +pip/_vendor/html5lib/treebuilders/_base.pyc,, +pip/commands/zip.pyc,, +pip/commands/help.pyc,, +pip/_vendor/requests/utils.pyc,, +pip/_vendor/colorama/__init__.pyc,, +pip/_vendor/distlib/version.pyc,, +pip/commands/uninstall.pyc,, +pip/_vendor/distlib/index.pyc,, +pip/commands/freeze.pyc,, +pip/_vendor/html5lib/treewalkers/__init__.pyc,, +pip/_vendor/requests/packages/chardet/big5prober.pyc,, +pip/_vendor/requests/packages/chardet/langthaimodel.pyc,, +pip/_vendor/requests/sessions.pyc,, +pip/_vendor/distlib/_backport/tarfile.pyc,, +pip/_vendor/requests/packages/urllib3/util/response.pyc,, +pip/_vendor/requests/packages/chardet/mbcsgroupprober.pyc,, +pip/_vendor/html5lib/filters/__init__.pyc,, +pip/baseparser.pyc,, +pip/status_codes.pyc,, +pip/_vendor/distlib/__init__.pyc,, +pip/commands/search.pyc,, +pip/_vendor/requests/packages/chardet/langhungarianmodel.pyc,, +pip/_vendor/html5lib/utils.pyc,, +pip/_vendor/html5lib/trie/datrie.pyc,, +pip/_vendor/requests/structures.pyc,, +pip/_vendor/requests/packages/chardet/euckrfreq.pyc,, +pip/_vendor/requests/packages/urllib3/fields.pyc,, +pip/_vendor/requests/packages/urllib3/contrib/ntlmpool.pyc,, +pip/vcs/__init__.pyc,, +pip/_vendor/html5lib/constants.pyc,, +pip/_vendor/html5lib/trie/py.pyc,, +pip/download.pyc,, +pip/commands/unzip.pyc,, +pip/commands/__init__.pyc,, +pip/_vendor/requests/packages/urllib3/__init__.pyc,, +pip/_vendor/distlib/compat.pyc,, +pip/_vendor/distlib/wheel.pyc,, +pip/_vendor/requests/packages/chardet/euctwprober.pyc,, +pip/_vendor/requests/packages/chardet/escsm.pyc,, +pip/_vendor/requests/status_codes.pyc,, +pip/_vendor/requests/exceptions.pyc,, +pip/_vendor/distlib/markers.pyc,, +pip/index.pyc,, +pip/_vendor/requests/packages/chardet/cp949prober.pyc,, +pip/_vendor/requests/api.pyc,, +pip/_vendor/requests/packages/urllib3/filepost.pyc,, +pip/_vendor/requests/packages/chardet/big5freq.pyc,, +pip/_vendor/html5lib/treebuilders/etree.pyc,, +pip/_vendor/html5lib/treebuilders/dom.pyc,, +pip/_vendor/requests/packages/chardet/mbcssm.pyc,, +pip/_vendor/distlib/_backport/shutil.pyc,, +pip/_vendor/requests/packages/chardet/sbcsgroupprober.pyc,, +pip/__main__.pyc,, +pip/backwardcompat/__init__.pyc,, +pip/_vendor/html5lib/tokenizer.pyc,, +pip/_vendor/requests/models.pyc,, +pip/_vendor/requests/packages/chardet/utf8prober.pyc,, +pip/_vendor/requests/packages/chardet/langhebrewmodel.pyc,, +pip/_vendor/requests/packages/chardet/compat.pyc,, +pip/_vendor/six.pyc,, +pip/_vendor/requests/packages/chardet/langcyrillicmodel.pyc,, +pip/_vendor/requests/packages/chardet/constants.pyc,, +pip/_vendor/requests/packages/urllib3/packages/ordered_dict.pyc,, +pip/_vendor/requests/packages/chardet/eucjpprober.pyc,, +pip/_vendor/html5lib/treewalkers/etree.pyc,, +pip/_vendor/requests/hooks.pyc,, +pip/_vendor/requests/packages/urllib3/connectionpool.pyc,, +pip/_vendor/requests/packages/chardet/mbcharsetprober.pyc,, +pip/locations.pyc,, +pip/_vendor/requests/packages/chardet/jisfreq.pyc,, +pip/vcs/subversion.pyc,, +pip/_vendor/requests/packages/urllib3/util/connection.pyc,, +pip/exceptions.pyc,, +pip/basecommand.pyc,, +pip/_vendor/distlib/locators.pyc,, +pip/_vendor/html5lib/filters/_base.pyc,, +pip/_vendor/re-vendor.pyc,, +pip/_vendor/html5lib/treewalkers/dom.pyc,, +pip/_vendor/requests/packages/urllib3/contrib/__init__.pyc,, +pip/_vendor/requests/packages/chardet/euctwfreq.pyc,, +pip/_vendor/requests/packages/chardet/chardistribution.pyc,, +pip/_vendor/requests/packages/chardet/sbcharsetprober.pyc,, +pip/_vendor/colorama/ansitowin32.pyc,, +pip/_vendor/requests/packages/chardet/sjisprober.pyc,, +pip/log.pyc,, +pip/_vendor/requests/packages/urllib3/util/timeout.pyc,, +pip/_vendor/_markerlib/markers.pyc,, +pip/_vendor/requests/cookies.pyc,, +pip/_vendor/requests/packages/urllib3/_collections.pyc,, +pip/_vendor/requests/packages/urllib3/util/request.pyc,, +pip/_vendor/pkg_resources.pyc,, +pip/_vendor/distlib/manifest.pyc,, +pip/_vendor/html5lib/serializer/htmlserializer.pyc,, +pip/_vendor/html5lib/serializer/__init__.pyc,, +pip/_vendor/html5lib/trie/_base.pyc,, +pip/_vendor/requests/packages/urllib3/response.pyc,, +pip/_vendor/html5lib/treeadapters/__init__.pyc,, +pip/_vendor/html5lib/filters/inject_meta_charset.pyc,, +pip/_vendor/requests/packages/chardet/charsetprober.pyc,, +pip/vcs/mercurial.pyc,, +pip/commands/bundle.pyc,, +pip/_vendor/requests/packages/urllib3/exceptions.pyc,, +pip/_vendor/__init__.pyc,, +pip/_vendor/requests/packages/chardet/universaldetector.pyc,, +pip/_vendor/html5lib/treewalkers/lxmletree.pyc,, +pip/_vendor/colorama/ansi.pyc,, +pip/commands/install.pyc,, +pip/_vendor/requests/packages/chardet/gb2312prober.pyc,, +pip/_vendor/requests/packages/urllib3/contrib/pyopenssl.pyc,, +pip/wheel.pyc,, +pip/req.pyc,, +pip/_vendor/requests/__init__.pyc,, +pip/_vendor/requests/packages/chardet/chardetect.pyc,, +pip/_vendor/html5lib/filters/optionaltags.pyc,, +pip/_vendor/requests/packages/urllib3/connection.pyc,, +pip/_vendor/colorama/winterm.pyc,, diff --git a/PythonHome/Lib/site-packages/pip-1.5.6.dist-info/WHEEL b/PythonHome/Lib/site-packages/pip-1.5.6.dist-info/WHEEL new file mode 100644 index 0000000000..f19235cb62 --- /dev/null +++ b/PythonHome/Lib/site-packages/pip-1.5.6.dist-info/WHEEL @@ -0,0 +1,6 @@ +Wheel-Version: 1.0 +Generator: bdist_wheel (0.23.0) +Root-Is-Purelib: true +Tag: py2-none-any +Tag: py3-none-any + diff --git a/PythonHome/Lib/site-packages/pip-1.5.6.dist-info/entry_points.txt b/PythonHome/Lib/site-packages/pip-1.5.6.dist-info/entry_points.txt new file mode 100644 index 0000000000..a237b5e4a0 --- /dev/null +++ b/PythonHome/Lib/site-packages/pip-1.5.6.dist-info/entry_points.txt @@ -0,0 +1,5 @@ +[console_scripts] +pip = pip:main +pip3 = pip:main +pip3.4 = pip:main + diff --git a/PythonHome/Lib/site-packages/pip-1.5.6.dist-info/metadata.json b/PythonHome/Lib/site-packages/pip-1.5.6.dist-info/metadata.json new file mode 100644 index 0000000000..2a13d37298 --- /dev/null +++ b/PythonHome/Lib/site-packages/pip-1.5.6.dist-info/metadata.json @@ -0,0 +1 @@ +{"version": "1.5.6", "license": "MIT", "summary": "A tool for installing and managing Python packages.", "test_requires": [{"requires": ["pytest", "virtualenv (>=1.10)", "scripttest (>=1.3)", "mock"]}], "generator": "bdist_wheel (0.23.0)", "document_names": {"description": "DESCRIPTION.rst"}, "run_requires": [{"extra": "testing", "requires": ["pytest", "virtualenv (>=1.10)", "scripttest (>=1.3)", "mock"]}], "exports": {"console_scripts": {"pip": "pip:main", "pip3": "pip:main", "pip3.4": "pip:main"}}, "name": "pip", "classifiers": ["Development Status :: 5 - Production/Stable", "Intended Audience :: Developers", "License :: OSI Approved :: MIT License", "Topic :: Software Development :: Build Tools", "Programming Language :: Python :: 2", "Programming Language :: Python :: 2.6", "Programming Language :: Python :: 2.7", "Programming Language :: Python :: 3", "Programming Language :: Python :: 3.1", "Programming Language :: Python :: 3.2", "Programming Language :: Python :: 3.3"], "metadata_version": "2.0", "keywords": "easy_install distutils setuptools egg virtualenv", "extras": ["testing"], "commands": {"wrap_console": {"pip": "pip:main", "pip3": "pip:main", "pip3.4": "pip:main"}}, "contacts": [{"email": "python-virtualenv@groups.google.com", "name": "The pip developers", "role": "author"}], "project_urls": {"Home": "https://pip.pypa.io/"}} \ No newline at end of file diff --git a/PythonHome/Lib/site-packages/pip-1.5.6.dist-info/top_level.txt b/PythonHome/Lib/site-packages/pip-1.5.6.dist-info/top_level.txt new file mode 100644 index 0000000000..a1b589e38a --- /dev/null +++ b/PythonHome/Lib/site-packages/pip-1.5.6.dist-info/top_level.txt @@ -0,0 +1 @@ +pip diff --git a/PythonHome/Lib/site-packages/pip/__init__.pyc b/PythonHome/Lib/site-packages/pip/__init__.pyc new file mode 100644 index 0000000000000000000000000000000000000000..235be03a2e871c3fb0d276aa8be2b2313f7a71e1 GIT binary patch literal 8946 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 literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/site-packages/pip/__main__.pyc b/PythonHome/Lib/site-packages/pip/__main__.pyc new file mode 100644 index 0000000000000000000000000000000000000000..e7b945caaf62fa4d85d28f721a5046e7da0032fd GIT binary patch literal 288 zcmYLDL5{*O3>>Eg0b&t<;L^+T0)#jt#9_IiN>QQKD$s_~1PRW(i&yaga03X-8ISGJ zIMMy5H^6PR#XFSLnLM`?$R!B{uoj|_M<@uT!dihiLLOtUP|v{%R}sbFIJCen@GF6i zbJ$?BN?KxR9uiAKLX!r3Bv7BM??~0U%#77KD8t5GoNvDrmg_%Zcq?sIverJ937?Hm zn$;KFNZN6_Fq_mF&%af+-Dm&o(#lln=ghde1hYwb$WH}NoBz0;K%a)HPhD!$6QDUa A+W-In literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/site-packages/pip/_vendor/__init__.pyc b/PythonHome/Lib/site-packages/pip/_vendor/__init__.pyc new file mode 100644 index 0000000000000000000000000000000000000000..29ec53ec98c28e1a9479d3a35cd8dead6a1f34c6 GIT binary patch literal 473 zcmY+B!Ait15QfvPs07rzr#bG$9=r%5vIp@Zh$vo`LP(qGZrC)5$#iia&NuNbd;zDs zMKFhdGWowuCdusQOrDFcw^mG}Bb>wZ(u@#cRS|f5RE2=xScJgY=Km!> zao*n6@0ri6o$WrX_Voki4TV_0>}VbQ^$i0 T<$8C0FoVPUv6Vdj;BoN_tCEYl literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/site-packages/pip/_vendor/_markerlib/__init__.pyc b/PythonHome/Lib/site-packages/pip/_vendor/_markerlib/__init__.pyc new file mode 100644 index 0000000000000000000000000000000000000000..3685f74d8ecc717c40c6c67427ed4e50373b874b GIT binary patch literal 1264 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 literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/site-packages/pip/_vendor/colorama/ansi.pyc b/PythonHome/Lib/site-packages/pip/_vendor/colorama/ansi.pyc new file mode 100644 index 0000000000000000000000000000000000000000..bfcc26b1effe264088b91d83450b83642011c819 GIT binary patch literal 2317 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 YYW`ORw4(MR0^~)vP7QIrsf!o>2gm}qC;$Ke literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/site-packages/pip/_vendor/colorama/initialise.pyc b/PythonHome/Lib/site-packages/pip/_vendor/colorama/initialise.pyc new file mode 100644 index 0000000000000000000000000000000000000000..df96bad2470c945fc2b936b7f0663294313bdf94 GIT binary patch literal 2007 zcmc&#O^*{t5UrjM?|Simk!-{P37^nNKor3N2?3jkgrkLe2}ssRR^w^Bz0A&-?l#Lx z<`T$(6TgUGl^>AQD|^=jMapRtYr0(1UEN);s$Na{$L7WkeLfh|@|W}fk37OB78O5= zYNFw}u4t&JN~lVyPUtwLVM@v>I?8C66O;}O*F?$4tS@Iwm+S_aOH^g_fsgCqm5=7f zZc&xf2j0F-RYz8Ls9F7d8@A3#xNR2a=7#$vh=p!rhlzRRKfX(?)G*4)f0wE?PvaJ86 zs9|6U#dK){V>Zhviy4h_G96i7`^V*V;>5)b3cn*bM?H$0xIx7&G8;Hq!U!)1;U>!y zZ>A3(n>yJ3xNTn6ZX84Z#KptDX-@lXJhZ-V{N%w?KeNR)Z(z5Gc#ZEMdS>dG{l)v% zOHOeZXTn=^tR>N~4W}U@49g5{u?oAXtQ~m7g0+eEt&5|oZLC-? z-s3tic{_0-S}!T#fDwu7P^3D{EVfc1agC=K^Be191c%shH`w%d{6+11YaZQ8Xz@Tp^>i@DA6vE z5t5e50^4=II3WI{y8nuZ(J`X*OGMbJk=id1{SRQgfVshbtiT}H2s6ABnnTPp^7~7c za}Q*qbMs}cbN>a8Rr)Tcc}_>%+_+r#MNjA*(d&H>l<9s@0P{ejqv*>JJ1o9xd*QI1 z)zt{Kx?~J^S4h^cV9(!o>u-2YYJR~!zp8}`ECY=Q{lFviSdi*)3GAt!+ExYp(VGx( zc|mLbCdBpx-vnvzi|R#POZ6`5SSkTcKu9aCOXKhr;RoCnG^{yQ-UDbkc6Nx7*FT`Cmk#xefpT literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/site-packages/pip/_vendor/colorama/win32.pyc b/PythonHome/Lib/site-packages/pip/_vendor/colorama/win32.pyc new file mode 100644 index 0000000000000000000000000000000000000000..8291613adc30311cd66f79dde87e8b3901c372c7 GIT binary patch literal 4352 zcmc&%TXWmi5ng~7Nfc#We2FiyLtn$Ril=c}yX|-~wIn)mhaufVc^sphK_TE!ghT)= za2Q1$`=O&e_8;`O^jGw!w0(BJT@VyKuKT7|6qbuUi^bXfcK0kx|5&N5(cgMLP5-L+ z{td3|w>D8g7Yy}(5{F^MKr49RLOc7 z-=nf#AiYQfn+|J~W@K3wEV6Qye#Dz<6#w1&j%_c*TDH6)cjj(*T=XVoN7Pubd6i6*@Ri2N%e>NV-Y~muTN2eUaRcVO!df>k$s!=wL<@6;b;0aa;_KpFn&Xnug@uipDBMrPGe5_rYJY&l)=xG zZ;^v|!X|dOBFrVBH%Vh-;t21pLi+Zc1@JQqcgVS0SdhKtPcePp$lW<3;IB{!uMsiC z5#b_w$TybUSoF}j$FiVCKLY2g6f94n3+lprLcxkKpHgs6m^+*{z2+)%D*V^mw{OFL zGQst>)3hKoD z)*pxCzWcq7gCy#q|q{(gLIlz?D(#d<`9fY1d0F_X@W`@4 z9~tK?6vetoswaMC=lMP2T_cPeh>V}a_lNhz&)}#R{z;oPs02sblQc`x=LzB)Cb3zD z@aTy#X}C8rIuoC>^ks-h9~m|p9DVEk5JrjGET zy}|F~fRk0SHt?xhcdRBSwP5DDu@`CAH8n_FH%fxZh;MTXLE^iv;s}Uq?sm7UcEsJ6 z%7Jiz9dAtr1D!sL2Z`b)(v(Lz-he}UksAgQ%iNH}($DrnF`i9)UuW5A*v=+m(uY30 z?ceiW8CtSx){gTBQQlA5k3^EL=b^1LdK7%o2+&j#O=+(w5xwGv(C|E zi|RJ3akM;iluX?LcjiH04?eJ|JuJx~#SswSd2h2E`YUeWJ9j6G{(}4w27Lyt?9ig@ zbCw^Jrnl)Aa@NfrU_F~IPgTHivLS?JjsS8G%`MNpGIu@nz6E+@yI^f9!zfD@SyCb# zO_IlWvPQ4b9Fe;me-3FU1fh^iH}7T4sq0KOm~e|$pMpp-_I7u=FLtG=sSCWq^^}9h zbvy^&yT?G2F zn&{k`lofj<^9qkHBOULXq3C4>GmL;Chj~1S+@mx!M#t(NG|#;Lco_PyLq}MZhR!8e zw^o5v$-4F*@aaME9elWIWZ-2Gqz?0*&JY!4$q-cwh=7a~8bef-?q5L>NwRt{-gs}5 zr_HM|oWil$;3j^5ZX()jU}j2Uo_nyEBx#Tz51Wm9KEsy1%!A$dEQg=b$>EnuKAO`Aro$=GRCr8<~8*QqW=%Vv*7(1TgV3!)E)2@gqyr6 z^;6z32LyeorIfI~{FYD<=1UkWciL@P!qgg!MtQ~X3^02|D@`$+^C7FGxJbNbiMrHx|3B*&tOp@cq*1U9I zwk_NI=1FI#-I9Yo#l(!CM$&-QEq(=8=~lPfRuTX~|7Q>>o>!!8OCG$J26GMI0c$>H z@+&4cnfwxj4bG7>8Y$S@$NBX575kF?0VE&B)=;^t)&=W4M$Z-d=jBTqb$ivW<5NY? h&A*HL;=2Uhs&#R?%6xuTvR16MQhi~mytKYl`#0Qvv+Do= literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/site-packages/pip/_vendor/colorama/winterm.pyc b/PythonHome/Lib/site-packages/pip/_vendor/colorama/winterm.pyc new file mode 100644 index 0000000000000000000000000000000000000000..2e0d610186f5bf50e9762c9520d19e0d3534894a GIT binary patch literal 5164 zcmcgw+j1L45ba$_mgEaEV4QF(Ot^{S5(t-26gS&3A>hcVkwdUbRa`b3I-94kyzf1GW@=v=b~%^Kl?!cUqAg1_S7@sfZAGG*w3~IjI`JTy6t)6! zk_GyDuHgR+0|hUY5?BL>1{&Ie(`n zQB^v1G3_Q_ouIgh6Q4EOnv^NHgk+AQ3elX0(8UD7Fg%Kbz)}+gM`<(~u*v5)w%0d* zvK+p#eRoS$H_g^oOI4eD>n+Roo2?s`@4UT!bE~zxZaK-`*7o+!J$()%_L@-1ROD?m zdtY|%=5dyH2TA|eBph~c#QC93kGpps+6U?I+I4j7ck{%?9~_6h!|;BbcaM|fZtzq=?A!L?AbuMA6%2VAd*G@-qEiwg+$0=^ zIz!{t+SZP_y}qs04Rh<}54%%SwRU0lE@B1GqU2l@t<{YHzjgu0#6+%B>Gc;X6B8d7 z3}Zz}#tL}0q}&Jdz_TTZ!LzbF1_ePi*MtwCSudJ%+MF+%@CEcP&=2^+#X?_KJzhSq z?_AL4GevVzn+@{#8LYC$on#@C@mM>fu#D@AcX91X0c_vf(0pBCS8N# zPqpMb7!tUKFWRK8dMqI1^b$16vw)H550w>1Pa9`f-Py>6}qbSK|B@4o30C zgJ2l_uAt;(op?*$vs3%IezpG{RL*W`;cJ?x*x?~zdY&3hGg@kbdV$+z&SIX2Q2(Ke z^qi|{kabpbJJKPDAH`XA@s_KzX0f{KU_c8sm~MuS;I&oxZ@HA>D{ zPTy&Gb)3eK78wQ!-UPr;(QxM&;($YpFQ`sakbCM1%k2b%k+?&$Myvygg!^h+2W)NVB3G-_)D9DF*|Bv)a{&rcAM%kyGrFTyAmix(W3`VC>^wzJ z&tc9nnYaO6iEKOtjAaGWlgq4Cqz};D;TlJ3RFKpP?{$>qBAUDaJ^``$kh=FNm{-h4 z5KVP;x~j5pI64Zl^dz4mYzVle^M}#FD7SGmfnWyU^X$=cz>kjap`jN^I&=Yf!&`NH zrNJcECZGBnf_(MlMO>B+tCFoa&Yng6>iFg|4u^_5M&KWS0(eFRWij^wKv#%9?=h}Y zm6g*ueF)bXgbHjK`f%YXi^rk3-av)QJWd@?^et!~wo^wORJo~>U8EH)rIP+;pfO`j zPvF{~UXL^;JMU4;cXrGT7lF8|(Mdb`BX(QOP1noR_sL)|zD@0n?D5EMJ_xh0hx_{f zcTZxv(M)g^?{U;p$}mRY2MTv2aA|X(?4x-S8AzC?4cT!s}=;J@C;jQK*yAwah0J%tBLBwRTY#C)2=OG%#l@o%8F}dZ}JnEH~!#Q>)h+^NsnI ux;zMq#ZhQtPWKPup4Fdg40ljpHKS!~;Q7k^&h-r=m|l67%c~2kmHz-c5jErh literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/site-packages/pip/_vendor/distlib/__init__.pyc b/PythonHome/Lib/site-packages/pip/_vendor/distlib/__init__.pyc new file mode 100644 index 0000000000000000000000000000000000000000..0d3a75b0ac3b14d7af6dbb96bbbc877ce9480173 GIT binary patch literal 1455 zcmcgsQH#?+5S~ra^ja;RT72`#mmpZw7ez!w??B-wk|Jsdgj}+1_nIbgcTX(%c0T%- z{8je@&TqD*6@2mKnq)S!vpX~2%BuR7@I_2(GIiOn5XI|-& zJfI6fNsnZY&iW(+whxH_h)Hw+KS` zWy$!jr0{}~)zpSyv@9B3?vim`d2r6=F5ElpA4J7}V~!bf%!gtRNZFTMDtj0IHBQbT z6XSKc9e_b@f8cbXQFck@4VLxCO)VW$HO0bJz=f~}^nA(-EpsbR;ChIeiy`9V#T-P; zAY-n5+~t84cDNjOU5CJ(^V{%e*nKE^cq8rw%SftbHdFP?HAjY)(gv-LzU^Uc+xo7b zoE^9C{jzPeJ=Pi{+t@Ue)0s(o0+VPj4%;0-b|JO93G%YsY~EAw?lOA0zJ6XYR>N1@ SO)vEB`Mwy6fwglv*+$EL}enQiIA`Bc7uv#w}h zzI^kW`EvMmR-PB1&$jqIBf0Oys1$HT@hUhfp2r7$>{PN3$#uaK*wmtT(B!m%r#-Jy zgc%T<=uCDHu+AoF+F*!erZhv-Ma!6?c-c#H zCozoRrj@RZUAHN7wL!8Kz(S@*=Uv&6S$aSMPGG{$>i;o4gcFAfz7FzrR zy@_k*>VeZ`-Ar8P!m Tt*ds=C-TD0pyBpNIEfYC0+y1< literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/site-packages/pip/_vendor/distlib/_backport/misc.pyc b/PythonHome/Lib/site-packages/pip/_vendor/distlib/_backport/misc.pyc new file mode 100644 index 0000000000000000000000000000000000000000..2087c7b2039e7b78ef1a47428fc549db7de6fa9e GIT binary patch literal 1376 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 literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/site-packages/pip/_vendor/distlib/_backport/sysconfig.cfg b/PythonHome/Lib/site-packages/pip/_vendor/distlib/_backport/sysconfig.cfg new file mode 100644 index 0000000000..1746bd01c1 --- /dev/null +++ b/PythonHome/Lib/site-packages/pip/_vendor/distlib/_backport/sysconfig.cfg @@ -0,0 +1,84 @@ +[posix_prefix] +# Configuration directories. Some of these come straight out of the +# configure script. They are for implementing the other variables, not to +# be used directly in [resource_locations]. +confdir = /etc +datadir = /usr/share +libdir = /usr/lib +statedir = /var +# User resource directory +local = ~/.local/{distribution.name} + +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}{abiflags} +platinclude = {platbase}/include/python{py_version_short}{abiflags} +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} diff --git a/PythonHome/Lib/site-packages/pip/_vendor/distlib/_backport/sysconfig.pyc b/PythonHome/Lib/site-packages/pip/_vendor/distlib/_backport/sysconfig.pyc new file mode 100644 index 0000000000000000000000000000000000000000..e8ff937adfa9ad7a9b1c6512fbf5016a95d62ade GIT binary patch literal 20509 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 P)RljNvR_cYu)qEv&@!KI literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/site-packages/pip/_vendor/distlib/_backport/tarfile.pyc b/PythonHome/Lib/site-packages/pip/_vendor/distlib/_backport/tarfile.pyc new file mode 100644 index 0000000000000000000000000000000000000000..b303c6126fe24097d4f1f346cd361fefa94dbecb GIT binary patch literal 82723 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 i_sE?i|9RwlM&35^7w*)^uOq*E_ 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 LohuP^j+g!e%d=7j literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/site-packages/pip/_vendor/distlib/locators.pyc b/PythonHome/Lib/site-packages/pip/_vendor/distlib/locators.pyc new file mode 100644 index 0000000000000000000000000000000000000000..9d54c6be588136727137857cf4784ceff9c07ea1 GIT binary patch literal 42636 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 q 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 H-YowQT|>w& literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/site-packages/pip/_vendor/distlib/markers.pyc b/PythonHome/Lib/site-packages/pip/_vendor/distlib/markers.pyc new file mode 100644 index 0000000000000000000000000000000000000000..1cc88d51c33306c3eb66cf776891665aa3f8c341 GIT binary patch literal 7863 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 Tbe9#M!H)icp}%yW>FW6Z*<~h7 literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/site-packages/pip/_vendor/distlib/resources.pyc b/PythonHome/Lib/site-packages/pip/_vendor/distlib/resources.pyc new file mode 100644 index 0000000000000000000000000000000000000000..13ba45c6fdfd8b718474cf6f54035cb630b2fe05 GIT binary patch literal 13903 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 UmrJmMPgygF|F)X#&Y9-_01zM`L;wH) literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/site-packages/pip/_vendor/distlib/scripts.pyc b/PythonHome/Lib/site-packages/pip/_vendor/distlib/scripts.pyc new file mode 100644 index 0000000000000000000000000000000000000000..863b78e1d9b5ae1c917c84c2580d63d64b35e8d6 GIT binary patch literal 10967 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 WMDtY4Od=94WrxR#+2M(N_J09H#JceS literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/site-packages/pip/_vendor/distlib/util.pyc b/PythonHome/Lib/site-packages/pip/_vendor/distlib/util.pyc new file mode 100644 index 0000000000000000000000000000000000000000..5f2fb421d33d331ba815e8bbb96059f28fd437ce GIT binary patch literal 58360 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 w+6@^)2d}HR3 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 literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/site-packages/pip/_vendor/distlib/wheel.pyc b/PythonHome/Lib/site-packages/pip/_vendor/distlib/wheel.pyc new file mode 100644 index 0000000000000000000000000000000000000000..64e5b1f4e70835e1d0e17359171d7399d9d80c2f GIT binary patch literal 30135 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

    nyVmR~6qPrTs8n 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 Ky73Ite*PcCbjPy* literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/idlelib/testcode.pyc b/PythonHome/Lib/idlelib/testcode.pyc new file mode 100644 index 0000000000000000000000000000000000000000..63d5a1993f9f18353db7cf83ea4275e42fee4123 GIT binary patch literal 1289 zcmbu8&q~8U5XL8enkKahiXe&)5HEcKDS}tYVS5myplLSNt*I^DhOQv17iF5#f#RbY)9U)$aZ$v{9Z5?lWo@Zuz~)AtPmOzE%r&CGtRi- zx(wOd0ylHR#f;kD0{7^KOBi*y1+H?#q3DnP!Xevjsf?sRe#!)ejOufu)yU;}mCq+S zAD)29gVyze@{#gHx|uoSKI8uMxIfWV_?$^YiLKFPwqBX1sl+Yv<;!BFt<#DWdgT;> z+S*N#eue5%2rs3rkOGCJEBT6)Db&0C?1XC*Fkk5BsvM%}>;X&PPvRt4pMDa21KM}K A-2eap literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/idlelib/textView.pyc b/PythonHome/Lib/idlelib/textView.pyc new file mode 100644 index 0000000000000000000000000000000000000000..c6f8430fdadfdc51c98afec4a3b07acf5bd56f15 GIT binary patch literal 3724 zcmb7HTTdLx6+YDi0}PkJ#>V#MvK_6gopm%`RH0)ze)w)6jI2 z?ivG<{e<80l;=F;k3`CkO5T(2J3WAtl~zvUs;N4s>fGv_ugZ;oF1I@W_)9OA>DR>X z7iiVr&?O>==#3-^`1qqRg0gb zQC5uJv&+X9GvI7+yA3$D#b`A}7_srOSm?p!On zt0SgB8!52LkUdApdgJ2EcVp|1($_YxQz6a$$gkqE$g*gF{5VVV1gp+cHwNR=I4dgq zsXv%FSLCf0kAvUN&_5}XDD#U`mlnBSS?9aLe->qx{oJ20x8f-G)7;rIid`+Pfa-Fp zp!)n;mXgoX3b{G97vN`^Kd}BJS9>7!2c%$?OS5ZH^ok~GO^`Znz(VQNxcN( z?;j@T50jtkzw}R@Ncu0tJ!LJWC=;oe!k-NFtH;06&+&{7UWD7--EO}d9_;LG?;lk2 zAU+PPo0R#JdeW`p=+r(LfuWyM%`S3wud@z{5c0!qFX^`>+VhqHyQ`Grw@~Lk1)L8IIgCW?Q9&&Vw`=Sy!nME_GQg_OvWq z5f_=R-#>P&+|#JExl^q?A7Y9cG%Vst6(W1w40Ry)ba|R1gPaa)lXd6zPVedFZg*RE zx-!bE^h)Tcj0P%3U5VguoyQ$2SJ{=#hQTe&0wSW4Xo=dcsjS-S#OPp!XjeVJXyd!x zbnso8WH!U^mHiv17XhX7*ehMUuxeJlwplhm^A^m4*TQJcESP0)4ZryFnxM2yOn_~m zF)OyXd#i>sAOqkF_zMI}Q2fSwizz?~SBH_eo*<%tof^-8Sws?rEqHTj8kmN&0ylte zz%MsPL<6h7Hl_q5$EiH_8Ws9i%4)+x3DmAD6s zR<9YegsaObRDuKSY7@JXRdH)zc#2&$sDW`ul3U{LDtjI5hJlyUP4|>~zupAYu0=ig z-VPL3uX7v0+|zR`aa4Aw!?8_AW0(FNNgVtb3-rXd2y2KCOXB1tLfWxBTy$(TBXwg@ zYI;%V7$P!?L9NHfxvi=c)H;jK%IGv;5(LaW$LzYO@$^bGQ@ctNt4TKmys3D5ehR&v zkGP3d{H%;njm)Ut%e_B#YdcLSnBz3Ay~udBsSBQna1hW8Y|2T`f4SKXk$v-NaW zE44NSEUh`3(r4OpaIhb2-&h{d(Lh0j=3Ed%9nALqHDHCSN8qsJELq z1sry`=>}u9+Jc{uf%YMIs`VL#j9$!h!VeBmPM)OdIAKAMz*>S{>$rk zPR2#R2kSp9{S6IdhYo8c#YJM{N)Nj@Mdp#QvtNs3;ke@$wb0GtT;o{bv1h3<_ygHI z8(i9nO1wEF1q|wB66(a}P=!a2o?P&Pd+8icgs%MmXG!T_LPB*1otTDcqCW59Qd~xb zw#=fZ@{##bnulTaF&0hl+71397b>^GPP0N`iN*8UmV=^7-9^fhQvd9E>guv>fP}|e zhX)WmBcJi=AL~;x_=;4fl%{P!<1|RY4o9!pG5OT430_ZBt_o;k@SLoB=)P~Iz7qrd pfAGDO*MR--J31+Wb-wc+xA#Pek|NIJZqAT(vNtYyDPy|R@pb6RnX$k}diU1Azqdx)!El{99QJ_Fjw12vM z-*;x_J<7C6*`_#`cV_N#?%B_|cU1oA_UfOXd1;LD#OjxvFb#b938Vd(_R1I*;#m z>D_iWx81dOxVas!jc#KA507@b2#&{(s?)f>~54&i$TfhK&il^g* zCVRTKc)EuGM&oKbQ9RvCn4`UVy03UT!DVD4+*CZ>$CX9<)OLUI^d{nJ?q-(ZEi4;1 zyVpH82S9IOqq*DoaCY)G5@V|3+{yNGH%|S`Nf?Ig`4jXJ5nl0<%Y z!A}>PiQn!vR$7sNx!G#@?eIe6H&cJPnQ3Dmf)eRfX&iQOizH3Cw5sFUQS_KGa7MmP&G4khEnyvH*x@6Ng+sl4* zg^;pW8pR7?JxVx#f9q=2I*G!#zQ~!vPNSGLY@P4M&2+InrN>wYme;?OI9hID*lPcf z{=!P9o;JH3zg7bf0H9XmQo3;?ir25-Poj3%Nt^Wq$kQO!!B5gKjoMh`l)r-aEx*&f zOf)Wri9a7j9iND6)>m4o2JE)yn;pYw1ccU8(xQjkJ~$S``h{f5Z#6-d>v6jfciaB6 z!KtJ=zv{;Z$@KE-6d?EGC`sdHJq1;wD^Yz#>ti$Cp%F;&OdstV(Eo;;ZC zOc$qp|77YXi`|u01IXuS4Igw6&BG+B8rTcKQWwwSexRZRfPP5p%@~bHkK#?&YW(PP z&@ksw@K6YjA*1>POh5uJ91_f7aORi~AyMgKw_zx#S~s9UBNj5E5yAB!MWY#mak}y9 zgFbN5y%fc9Q=(@wt--2Y;JgmH#F5P-Bs8KlY_`b4y0xhYjolXmQ+Q@D!c?`8RiYVe z_cA!z@B_@pU<)l$8UXweHppF?OtnPRWKLv|j%>RdJ*7 z@;d&{76gK7oDfoc8M;Sc_6Z9Rdlbv$FnWdM_MjnZYWMc|T>1_pt%R-Csxb;zZSVrC z_w}=;N&FU=(;60x3FVmhmm_F<{4H>xspCk@Niwf=teQ_QsR~<3w^|7N`o7H$1e1fR zbAH!Mlc=?TX~Y;A&sD(zA(det71=GDezG_J;X*r8GO0px+DTJGdQF=9m5EXBWY%E4 zRw;y&i$iaL2~7t9O{gazvy))89KMYh0%B3MZfO$?+Bi&Z2ayB_BsSx2AF2hs{3bOt z4;56jrF2JEV38Y9qnh(^*lMP$e%R_t9=d4WqH@MGkWlCeGuJuwGX!K-9@BSIYW+^w zj$k-|ehL_kn)RDJTy3u;DNvoR#8f9evvVnItxz~=uPKYLh?f_kM~Eg_(mKeCp}U>x ze6$#Xs?Z=IECcP(^z?K#5vvD!7LnGd)1|hXl*Iw1>LGP9RXLgaa%g}1c!6eu+DEE8 zYxeXi)MI90mH~YfPah^vRxeA@lQXe)h#=*RGMRB>{{o{pp`8cV#%YtJUGx9&Gg*S` zl+vNS9LAmH)%z}_1KCaT0losDO@dXpOND8Vqc*g!SSN$=zUdF7RdfOb^$V@&Qq*d4 z_?dJU%A;Y@tQ(7-5)Y<>cuGb~(oxjby<&&Q!%ls5-P7^)!{nTv?kKt!kB0FmLq!U| z(5-Z`yC!bjWEn-e4aKqAiL=j~n3+9!dPeP@e!ez)`q|*v3BASLvC~gIee%?a?$WdI$ zM^QxZVLit%!O5{ju;9tDMQ~731(88n6*#{Gstmhec9OWObEy0}#vuv9RnJ{@uBO0b zb`k-Kn^Bn(C9swR#;8t0Q%ME8QJKVLMKXrk^tn^b`Ey2jxJ|Z{TC>xHllUawC!E)L zb&j830)ew&{v`*uyf?W`!TW$j++;Em=6saaGH7RTo6naomwz{1vdzk-nsqDdQDAfP3ZIKpWt&w9k$eXzbe4I=e_`hbk<>C01(F_0n}3xo;MN*ED2l~pHDWy3dse9 z5l_CmtxH&PfE-EvQ^Axp=oYq2wl>_(W%r^(Q_7Cd-L}MkWOY!VqquliOh$ z+{8C}&0-^F2=?IxVqTZ9oAZXe(bD7yY8jVM1=niQ1hq{2;+Bl@+=<}m>Dd#(9@K-q zEGAg&XTd>x^QyMtd*K;ST_#w5VZAe(hG-~v;LIw?3Dy9O zZj^KmrLaF?%N(itVpP9CLxd1w+N@XNA2|Zc*rGuyCWAdD1bv>}x_z3|Xh62(m#1oKQ_i+TZc zjyfA2E6L(j8rqJmA>4yzJsZXX=Q_Omj&PtLf@ZN}Bht?%$j{I?6`>LuVByU)g+tr! z!UsVpcPZ*L8MUW~*=eQ^A+BT3J}gX0GjYaNxHJIa7c?+S5iMm zt#wt4!@{{mTSl`C$U3Ey>Y5^Zj0`o40ulw?q#Fn zFCK7fWoeg^1iI|5mE78ZyE@?F!z^bn9(HFiL@wE!PAY{Vj4W&B)YZ7clzOOd^*Ij^ zz@9eZx-^Ema71u{?6ua~6Vr_(RF<=EiWuD!nrP>ZdK2DuZ?`w(M&817q%a*`u@=g5 z%IP5q!2$f0NfDfH4?}PV8o$hr90GQVgYe=ykKszFLV85#)8EMH&93fqX~``C@1RSG z)B)0G&vbUX0ifkV)y2mh(s{)C**??@iMM0mltxY{kk~`cj3u-duwihJjc9AkVL1`U z-B=!m))w4}H^E&fHd&>QCTqA7I#5LK_EOo~2NV~sL9t#MQ9~})gf+$o$#+nQ_6x`s z^gGK&U@vR*v+ElT=8d#yqIL$&0VWMWKwzcyn@KHOcOYz#_?gdCd+PM@XHT7wuZ3n7 zQ_FQSFDiR42c?ILP0(-%<9`;HOoA(ofy;P_=!C35!g1Vyp6AMxDG1TppnLh|9$Kz~ z;8;3xwGb=H6duHnuv{upGHKWQ=}m^RRg;u`ib0}MZ_(2dX2=dk)VooWWHC~fy=0}3 zw`OOdyUAkTj}g9z%NC1;mc5%xLvZrwn+CN0!L2A{Z)>$iw_dA>3gS7*Mc}g$krr^U z-h8TUB+>y_8sZY84UNItl9qDk?x2e8^X=HXBW15_m zolKUqf)w|dDoAYaR0X;0U8*2`y;~Jztd#(tLy}rK?>Xe9mFAwq6v}MR?RU}5ZVuUK zrL>WXj&5^Hx4XGJ=rGWeNq&MtaSe@=rEz-+K^ajQtt^-`Q+9L}4gkz2&3=f~^}HF; z)$YprJQg0ruwHq3v1k6KWSpYu^V5t1+fjU8`RpPygM6u7~L!;hfQA$ zFCmJT-B;R`zDy@fVbc31%#9kI;ru$rMbjHI{c^2mi^vovAXHFv=@S^!=9MVfvLgQo zI{pr>1lLzz&>ybqmkOqa38@4bsD zW$_iKWh(f_rvDjC{q=V-eQ*SwZ){5T_{O`KQg&1;HfwTYvoi|+=DV4l@d!EFCa-np zmyn*mF&I9EA%4GrVF0!Kl4y}z3m%90f<3xcUgslSXM_?ciF!22L3%bc_z-VDh+-3_ ze*jJX09Woh<*@MY4Z*`~gp6Xn+g^ssYP?g39>hR@^j<(jEhLBaA&m3K z8vw+3Q7EGO*&`X;3fV!JLb#Riv*=%lMP`C~(b7CWl0^nN*vV(_jCvA(EfKo@0`d&s z!dN*asrzzj3QQu_G8ot3NLqkVau=R@-f%|9qUWpAjjRW@ZAx0$YIZ*Rvu_}Vf zdKyr7Ubl#p7NeoE{q{^KH!^JGf!4RtFY|Xsy-@@Y`?efD1oxn?C0>+2-n!*s{@^>D z7?-Q(#*Tl5JJQ-nyw2uux*HEwzKdROVPwb*HV>RobIbDy%X~$mb}c%x2yGcLa8LgT z+gG-LZH9Wagq{DQ0EQFfmloYqMFtG`fss*`>0{G??Sufixl7$_n)q4R6LxSiE4kX+lC=4OQ7g)-3fp!2vp39ESFN%E6tQA2<%YFl+VDm-8{dTGFhw_h)U^~WSL+bNWku? zVpcnhVm>SLr^wVY^du)|vrhSnYuN)y-8KSe?OAtYi+MZscy*b3zlw{e{4~r$Wae)t zn+pWy5c0wEF(TYM59{bq9>)^f`E`uQIE=!~EgT;+Zyuy{`3_oI-YZjELpq};w%ThWTri6@{hQ(U7npAI6L&M>6ytnyVe7R3MSAzbV0Wq zWwY^*apj&OHBo*EEt}6r+1&DcZ2XhAn~&a=t*>7>YGqrUL^(!AW+KBs_svEm^=<|d*h{ueaO(V9<6tE-8hL8Tz0Id}2o`kZT#n9bT1 zx!I@Jx7#2$YrzE#tFgrUSi7CY6pJG)rcv~nnmc)m>#bL(#Nof9g*oJ<-N>}^Y7$v> z@;;+1PO269cnqO_q4Fe{INJMeOnl%cY?_V~eTT0}@-NJ;>7B7r(4cmQUxikFfdi7dvik*j*h~ zig?7WRoq%NZ=om-G`c$C_SqiH>OJ|piW0{a?agd+SMdwLHP`H!i+_l?$yQU<-oZX> z9e8+p78kS3vkH@Dq&%9yn=`smHygDMu_mFG#gm=$`HUwt6fK%*rNs-*qL?HJ`a=J^ za4YkNEyV6+Yy>GZOf3Jr(rPjP9Nf)5%nt`8vCJ>uNV*lA zPA2U@-Bu-_+uYiyTifogZrAM&w>IY1cDk$huvbVm4ZHYHsW0QNunfd{x3OTaKT^f88qeC(tm;Ix3&#Pp|vcEl~Ar8Y9xcDc@FHNf^Q)Wp3Wd}OS# zRds7PC{u-7<8BpFjFx-c(jGVP?3vE{xzSAX zff4p<;=LMruhMjX?_JgH!&v@n*yr%vS#+J%X`DWTlK7zdOqa(_b%HBrBAoinYymVu zLhe2a4}HCgc-uZYL)aWaN0|xo-y}KB?3UDn&s(VniJ#QS2l#B7g>()hKTFYpm2tq* zY)=%~SwwQWp2Rp|t!7z1Sz;!cRCJhW9%V>s0f?KQM`Ah>o1m0x15SS2ot*w|7P5I# zNH6g=WI?g~b-^jWS z;0?t$Sm12DYlLYi#TYz-JEEqFZ345{lL6ik{^CO{`)~>y$`<}&H(B9t76-%3Vjme#b}%3&dnO5i z;d!J&PO>xASwOrlNbcWHEskbkV->yasF#lqdYVY9Hld{FS5h1bE`-h+@PsoDB}q@0 zF*mPc1cWRL$A6Hn zIoclYu}zqcqdrf*NRQ=GDdN3M6`g||W;)eV*KMu%Z-QZ_a3L@?ma*13^fX-9%Voy{Ef&CFHgS8rx5 z)J}BeA*|*TO3!gB_R;j4AeW8d3cmG9sb>wb#ZJwer=%;>7wA#(ZZa=>z}yz|l50rc zGA^w%LLr#?O{vWfi_ae zF^p?Rr+0*D6U=ZDn=c_sD75s`8TkPnBq*-}9s6)&{ENLIFauZsNO`zVf3c~Nw*bA5 zmp_fSTY$*E?0LD5qfwRQ7LdSb^b~Hbq`GJW1&fp(Xa;r#S0?vSyW+Mc&l8m;qz!Nj zcNF!CUYRr?>44`(;Nh%`Rwlj{=XRx_i^t9e(w zGo*{b@tsDPLMX@+nne?+l_4T{1#h;jgeqwK3Q^DtZ+qlo&$M7TEgi@*{40mWD4*b;!VgAiw<6LvgX zhqs7Z;3L@CI&2l#u0XZe6`($NEZ4Wjg@`wip2s()_GL9bfz1+0(~1M?6nn0J0GGHR zMun6|2^Nq(XO0d}AR8clo}__9okP}7=^Wz}#BvC%@SMTkfJ;s>3Y&$wK+t3&7#sRTQ`JJsGlJ{E%DUBfiTQaw!u@OjPcv^fkMed;N zIw#0ks583%v%aCf*&Esf9UVc;hXf*gSAeA$9FXj{BPLmc9&}H6<3z9NwM9bp}1b zt3Fra7>`4pBKpSD{Wt=C6#bFpL;tU_zs(I+i@)T-MT9h>-2_yv(HS1ZcAx+ ziDSZ$7AD{=hMA96yKoKC?(z|_X(7xHqTADwkzD!@9ZU}Oc@y|jgd2TGIAN0;$5rQ( zZfhk)x=B$|^6*>tm+#z|;*nN5C(HQH4)DsU`1{FdRYL?smQvyY|KoyobOxV4Vl^Vj ztiJYFJADFVuA}7p3+zUTTfT6fPN?cI#j2O_9G{_X;aExV2AY1AV*NNO&fDQpphqFn zV`cswz$aCevJ6zIio0>d-n?V3d_SV}Jtao)W2lY7r$TS!Ipt=KV6*{TQU?Ek3gins zO7Xm(6{upWPjfjT7-jG|1WGjs%Dy|`ns<=?(jH7hG6NZmKc#G(vJD6&rxebme7GZDE_`Qgd)>5^Nu#`hGs=Kh#-RmNcoWDN3uh8Hxv8{ zO0m24OA;#FgUK`!S$p{Ux>$ictgj}eeW~~*IhM__4~3hlIZL#B%AgtDe+jqpd?jE_ z^{34Uei<*sa~G8y`XamGvSLGJ{yDt;J5v1~wgc_PKv(3aLBk<$0)OElJM4|*)5x<`$^>6QkKor?$QS!6 zYa#~MZ^R&yh4|o6*1pE#w^4`=ZPH;A68s_>{}V|-zl+~4Rw#IG3}Q8|0A-ISC0r-I zDNTiG{T^Elo!&6|WS`3~bYlG6m{ z;&(Vce$PmBC?zxE z&bMattrG(Tihrdhe}D?Gi>QDs42&WiVH!SnTw(Sv-e1u2L!#yV?kq^Qiu8Zkbx*Ja zT}5?%BZmD(Q2j-=B+}2)NinSpqGDKVPeZ|p3+UoP)DQ!GPVN+&n!JKftSNjC)ZrPS zDY}6{zE2+&6%L`j2f4m*kQL6&m}km}A)vC5Cmei(H5ygn5jw(?$8RoklDJ5nJg1b5XqbN3^7DfAiNiDVWhROq=kQuaL{2d3?2B99A zFn}r4UwFGE^ddtPB1w~s=o)Cq@+i<_KnZjoJkJjcf54o6K?m43$kDa3H;YG*rHu?> zE>!zLOQPSpYkzCs9UMt=n+=og+tUsO-$EgQvM;`hG({jSCTE5W7t8XHG}caA5zJp$ zZslvJNtG?jq!7=WVDeQonE+z4FD&Ui?3Y>Dj<|LkUYb1K%G!rnhy`9@?F|+*Ndc9j zNwA=O6}P= z6!1}zXHjwxb;(P{#RF)aTI{C(H6_b@L~+20^#&@0!CdbRHH*62ZcCQ8?=5D-b+FT2 z#35&NrM+IAfBC}|9K$8-0%o$=dLYS@!Jn|GqUcSe+J>{K9cN=#SF$dm3h5)b`G0Z1 z8MQ4OxvG`{VOu-Wd=G11XK@<~5n5Yo+j&d<957_H!y!|wO|#GzK$$fz)i%&5O-e@y zt;QeU<}G(ZT-**^_&R literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/imaplib.pyc b/PythonHome/Lib/imaplib.pyc new file mode 100644 index 0000000000000000000000000000000000000000..3e5bae5dd7bae1be39b52c12b0d37297381041a7 GIT binary patch literal 43871 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 V`V=PbtnZ?qJE`*>)G( z8|xGJG(L?l;RERZWJU}1LLA81Y?AZO`S>OLvC#Xr@o_Dq_6zX)1jF8d$%!^$1?2%1 zf;KS;=?fMEUdcQ31&bY?uk~lx=_bt6G~25y<773Edc?CrZ%5568CChXP;y|Zk-QsC zBK;HJn=FJM3v@A_Vc4%Qj_3$C3OWhMUM1(lI1%(&P>J1uck%Z)q{$k&kd6>i$Wfhy z^!&qPI_}VPnGfwE#2L!FbQJO)95(hJQU`*2Ju;t22*Kj#SPkOXdylb^&$2Uou1(ipR^E0~4)x=)GbhSpU z(jB!b%gRZsoPhoOzEAEP{ti(?Oze|g;dSMKj#jPk*=|i2EwA@iKR;cmoV8&^B zfmYkGw!h8$=9TmDPWs-BjlB#LZN1jpTYrGqN)laamn2a=bqm-}j6xj`RKogPCwmcw zf<>_?=EbrIF&4z7AY(!~4j!JB6HL&dT~8`nXiDyzy?&M$z;PT9;=g?r`E&Ql-Bl{f|%uEW;&i_ zH&)7qsYx@Z%zt9oUe?H8f{z1&CcBI4?Tl0$}Wk)3=l)d6gweyojSs=p5IZ fs#Gykd>VtF{qsF=77v;b9{Fl>g57XFn7i-`7?52F literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/imputil.pyc b/PythonHome/Lib/imputil.pyc new file mode 100644 index 0000000000000000000000000000000000000000..80e10c2c0d73b5eaaaec8b0f1be1257823177bca GIT binary patch literal 15053 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 literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/inspect.pyc b/PythonHome/Lib/inspect.pyc new file mode 100644 index 0000000000000000000000000000000000000000..d3162642a59a8d2643c580af6ab43506c32c79b2 GIT binary patch literal 38962 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 E1@l^_6aWAK literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/json/__init__.pyc b/PythonHome/Lib/json/__init__.pyc new file mode 100644 index 0000000000000000000000000000000000000000..03736b742c99db33ce02dd285a41e203e6337741 GIT binary patch literal 13930 zcmeHO&vP8db?zldkXV8eE!m1<#!1&k$qwYjS^z0ZK}42ilCGjtAyo@1P6)7e2Q$6c zA!cV*^MfEn;3VggDqVBWUy!S>x%res&bj1o@WE9%<@;Xu%;YeY6@!JDHyyI3Z&{ z%SV1Z!1JNDawk!+7n^}bBV}yzuD)MzWE5haqc@2k#|L`sqigt>u=xzlKqFO4v%PbT z=^%BLb(HAO4vG<~uXk^D^iEmSqVi^tjwjIW4u()1=>4b|O)KA!F4oU}D5qXfW|>Kf z_+Ukk{Jfb*yGb;R0zWDA#AKqeBrw_!pW%|fYx0gZ&rBk+Q?y;?QL-yzODCKRKh}4e z9A+Xzf&iUQj0ww04#nR~f;8jrpFjg4kgKQp} zo&7+2d%Lc?{gQewS^x6kjRj?SUA{+>C=Z#~LNW7~bvlDjjt<>{lkAHysi z>&*g#-o5{@Qhjw^*NReotFGl)(VVJ!S}-elkr}Kd%r%x(`$9k^$c6Uwj%#Tas z9>>hgJ<-A(H1E)y;WLago8QMQ);jB*>zxJAM<*_xtaKxU!+-n z%WHS=yU|{;J#B9}A*~y&jSoAmo2?B+wF1< z%>P75h~;|g#>swb46y3?3lYF4*>#M6dX7QpkL2{I*}QAqdZf4hreR>2V%oRLYQdFm z#o@}yC5J^Mjnrllr+%1w#~0vP>u*Khx~0*e$e{h6Dy+3_7o)7kwmeg|WqCgT;A41$ zlTUve`#!}qru;0gQf7*-Y=EMY%A4gwuT}XsuIOo_Ts|r`Eb_2n$&2x#Zsxk{OtALT|rI+&Py zS(avAW+s`JuIL}@76D0;7S;vc_=J)N+Ozu(>z!`93~>hfn@H91hQ^<*ZbP3yR0{a=ai% z#NJi{pvC@z=qm8Cv}=L*DqV4%kot;)YEh7P^qsP>gb9}2I{bu{V%Fm zP)Ca@K~HcI)g(PdcaWi?J4jLwB~Lv>7cQzpG=51PqS+;Nhz6VL@Ul8wR$r^7*(RP} zQ-@d7-6wCWqc_wcnun}6*nH!Q|5m?5_cuK%BmXaGchk8JqXz?+`2cwk(=Z8bHr*;< zZWh^b@eBsT2`YKM*!E!1-OsQvy_LaWH7{WhnON;Gip^>q?HM{YSn>)|2Rgp{LkOr0 z0AiR`A+#|4NN^{Nf&y1*9k}Ed+Ru!5Ih$=1aD=(Y@gSwh27?YBDwBwIYEOXmZ6QvR zU0ae+VT(IhueQYGVlc1{WIuvm*g=8_!<@+4$_wL%%;xBTxe9%>Q@ddddS*1U7CbW| zk1ofV-bzQqhB1(2_0!Ee_wQ>iO~7I%r-<&TDT6{bHbFwhF`GQ_*%e6u2ZQbMAMpd} zx%r}mnKOx_^I{vB$>GRt=Iyj1(yCa*%rlR2nHG%bL~Qku(_m+>din zaGt^m1*0lXQjQs=Zab`*|JR1>_J97RXjWFY7UP=Nz@}ce|$0LD{OkGA3 zB~*b+mQmHtE$xpBTO%2*v^5x1>m7Pw0x&jEDD^-xp{qYnkhatdM>WF}ifHEG6@LH)a23EZ=8cx-;GZUj6-7#AC<#mlgMA3n z0!w3GkOeyBp^<&$P-bqe*1q>-x1*x&1eeD@Fc++ZIh|Cv1a1JcD(i_f4(5dL4I(9h z%r%xX+`CNJxF07RfXBPC0z3xqJ$Yn z3QH+M`$)#50}uQMw%z;5FiOC_xL!<8=M-bZkkyJWOFJ>UU~ZlnG+vlpleyWI?)h1U zwP9j2mgX>7(i`g>_1KJe=nJYjoy8=T6A*W38`UugoVcq$P0$pRNs%QNsgn<^9Ik8X z0RdbmW}ol?Ox9pvJ)d}9c#mLf|LI&jp!94QdQG})mjrciTpFjHf>c>t)2)Z^EketRTNDs>d@DmiJm|Z?f%Q&nOP9GzhrW@LEpQ0yN zA55BF`dH@Dh3B6dP!2{A#wm63X?ioAv-fL?=Y4Bl%;eCwD(Tq31iF}n*ebI_9Xgu> z@yxmBgp$w9Ku6X~i-IwCI|l?AuE9q_6w`Z_c>(rpFqp}6IDzF(5c`NFp6Tv(HIRc< zONyaqQ3&a1T$%(jsIu*bC47txnNOw$Fs{cn2}167#HyOyO^jc)3Rm+#~Sr5lr_8oO^`$Jz~J#6&wU**D8PD z2~;O?r>`ikqR@B4>PyUpOQ963AeWH!FC#;XiQ#7`>cLh|hUMx_~3n1ss9T zZ9;%@4eU{_lLnN5+ijwNvTP|au|TyarSM?j{qD6Jz$K)c8h&?0gKw1pf&(uCO@!QuaRU==6vKmF)&{O^F}bcN!AOXFam zus^{wb|wCQf$l4d#%UD9)h z2K!3!Tnu}SA^#8zi8v@T^BO}UQ54Ad8bi+R7}Z$qHHLhRA%%o_jUkm13iUMHb|zkX z;1M*J7jY8O3$S4p|Xvf~$ynPxp{Q+;Bf=>kt_TItW-xuYE@^^7i-3s#Y zd#SOABVnHq+%^@LeXD{m54rP+A7!~*4FHxD5j5`#e|!st0?1IQrw#R$ykJCV_7V~o z@K696(An3Gi<=%r=KluVd>4tH&8Y|l9K(tdcZb4nB3CPJ2#KFWIfvfDG$=_ofUqK> zbMKAVaZQ07^Cogj!b>23bFBl?*?DsuB+_ro9D<2O{!~$KHYstahbcN)cb6x{U=Whk zwJJfwUGRO_&A>RZ_cE8r%HGBp*_TKn6>I4n@_6^$s{_Xv;o07Jc^QnzTYr9Mb9H@% z45|p?{+JM0CbWF1OJvc&en#@q4o>RMQhii9cDRO<6|Wj7(m8C>;Z+!$x`Gr0F(|3s z9I6vhR>gLA32CFPHWtXKvhO8RnCeC2bI^0$QSaEZK-BU}EkqDslVqqU?H(gl4GA z3p3Y2Le$qmJk({0ZX`DFtZY}h@+Ghvqhstw-OiD)8|Q@Gu#GIK>|e=iSkmMZZjD-L zxbg2S^Ts(PH*E8`@f&g=ys=ucr($}g{ zZ>PE-eHEd4K1h?96SpcGk&F$eW%o0&*|92OeXkaqL9)0t1KGBjiZzhc{E9)^1|=+2 zuGceyG}ni0481f)izLQr*)IJC+{^12 zn(NmwRM5!l7=O6ldy}3&hIInti$vlVeAO@-)iJ|?vFTbNaKccHF8nI@$ptbA@f^kc8z4hjo7k%OO8koTR=c+-xU-j^8718!4?YY{r4L0HvXbvxsYY~W_kK~ z;F0Q(cj)?kAeMe#U~j+gwtR8Uy~TbX@f&60OO#9Od1mgG8>);?>RL`Ao9-9NF0P{4Fmmp1az(dJboE Xze@{Cq=)XwapSGV(gM!@a=Gz;59cwL literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/json/decoder.pyc b/PythonHome/Lib/json/decoder.pyc new file mode 100644 index 0000000000000000000000000000000000000000..386e699722ffedfe583ea26a4b7d62da47e48170 GIT binary patch literal 12034 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 literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/json/tool.pyc b/PythonHome/Lib/json/tool.pyc new file mode 100644 index 0000000000000000000000000000000000000000..d2e584b19a534e27cca26aee0ceaa6ccb381e1fd GIT binary patch literal 1264 zcmaJ>OK%e~5FYQQuO+2G1raB#3PC_L5|2{^2!wh;sE7tA>O;#WHm%cLJM20@L~^0r zk@ye%2mTiaj_{2Wka~bsc6L0EZ$8i1iGM67-?v|PdNg|?d>`Pg9zrOh9Y{ecqFm4p zl&K!kPDCoE&j^S~*GSdqD5CNn>6ng*ghg6Jo#q@vofSlnTv23Jt>?yS>7C0Vp9It|f{2g=aJLy@n>O;C;l+ zx{qdg`~>wQIu0G@&R!3em?l$KjV6NZ*OQS^m_bHH^|TbsWK180yRMPlb|utmo|yfD)|NKFY+3WNkrTB64m??9VJx$Br%Ce z0AdV!AugX)hdMCHTI3c#CF}#v$DSrj&Qotr$>5Jfg^CN($*Uu zluy{J2U(eUS5}x4(T$2rv}MJMq{)k|aPp_-<}wVP%jZDhZv|Wi%gTdym=+9P;n;I2 zXkZe&IAb=H>mXbg8z0Qn&Zj&CM6+!NTDVbRKe`DA1yP-Y*4lewx_ex9k1tmX7mlHd%vkPqbp?XNd9ftwkQZk1 zV$=`|A{MJ+1-1ovmW5wLWSVkjnudReKq5_*>!s-y6WZc#Z8acf!F^@MQ<& literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/keyword.pyc b/PythonHome/Lib/keyword.pyc new file mode 100644 index 0000000000000000000000000000000000000000..ab1ea246459fb60d43d312f53139f915c5d15d89 GIT binary patch literal 2095 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 literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/lib-tk/FileDialog.pyc b/PythonHome/Lib/lib-tk/FileDialog.pyc new file mode 100644 index 0000000000000000000000000000000000000000..b38b60f3abc83411bcfb48025838fd3b8abc8c50 GIT binary patch literal 9394 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 V(sid^u9m0&IJ0-=SZz<;`7d0S30D9B literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/lib-tk/FixTk.pyc b/PythonHome/Lib/lib-tk/FixTk.pyc new file mode 100644 index 0000000000000000000000000000000000000000..af52d8cdbff8d249f1eae2ffb72e25650d1dde2f GIT binary patch literal 1956 zcma)6&2k$>5boKPB}s({2qU~nle*`OelGLm*&p4ECK?~EL| z%C1Ub9*F}Fz&S6$IVT9RsUmnk|vF!IA zQGmaqh^TifE9xn_{5ZSvsOORPDD)}JQMg2^8$YI;&XX?CiAUoSC0$ZV1s?s5ILj25 z=tbZ!4q8!Iq_9MqC|sc+M>mMLLJNJF^a|Z5vVUco%yMB+p{)Kzf}s zP7V|VwyY8`n&$`VT=Bn)looBRQ?E|?A?Z4W8|>8EqyV{z6X)~h9jKs4dXqM|L0cId zs=Dpq76m0vhSA}f+5mkS=x-FmrhQFoZF%plwJc%YzLUVB*6j=vwQh@9(}S?6bp>cm z@BFR8zkA;D7+29@qk@?-|KiskDTvwH!U$t|l0oCIWQ=g_NHH51|JXrsmt-$i5YvRf0 zYH*iQ>8qe3*ExE$aeIH*SVdFX$e8GCII`w71jB7NK5tl_ur`B)cZ2wH5J| ziGwI|%-dKev5vm@9DM_ci5@uJGLh~|=Iu$W9nZ!{E{W z;AnuAXQKbt>~^?ooW0$_Myjr=s;u(LmsM0{FQ?X^sj8w{m(#jeRTZ3TN^smLa-0)C z$7wxgDD@oe?jP^(J?%W{{49hV{cwBacLUbkTlnq8fu5%>doONnxEN>VjSu`E-}NI)1s1ErCa=xiV#jrEX|%K`ozrBzR!(y z=?qK<3HP;t_=BMpFP3$DVUkHK`Uu7u2{E|s@XIf8P#IrvbBtw)vp#lXAnK$eJ>z-e zHvROhbGY}sEoJgogh{zbgP1v78#vS5_MT4>V>Hhu!7S2WaunOdwpsB(VGRUU{NhKO fYR&sp)xDI~hoG_!ino0xxvI9*Cu-fVs!abM-UV^P literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/lib-tk/ScrolledText.pyc b/PythonHome/Lib/lib-tk/ScrolledText.pyc new file mode 100644 index 0000000000000000000000000000000000000000..37f29e7599ff3c5bdac8a3859ad4c5f26eed936a GIT binary patch literal 2589 zcma)7OHUj}5U!qG78tk~Q~hDulMeNXG|i^Q9HQ&(eetJ3KrInuj;%`%f|Uxg5G$FQpHZ&m35#TWpe znmpfx0S>?mKQ#Qp>CC!hJT^%kCKF#3iCmu_>FLmvx~#k|jRA6VvO18H1;a2xg{9Wc zW)KIg38%Kqs_CXSKJ9%Th7YT9VD~09U=hZd%SmnYIB`xK7N85c>V^09lR7EPS?;XU zwsc4g%y*5S8aT$67l}h6bW$R0Y&omq<*>@LkTp#qIQ*sxz3^q_ye^C%R+-aCGit)V z*b-q_#vjxbg2UMh4t=A4Ow!S&ep*{(w#>pG^CZRfGZ+S_O=fG8GQun~|A}B&O${pB z3;iH9? zE9hU#_Q4N3&r{o!*l6RM8SAn(n{3-ziSo>>C(32Li=JL6Qw^z=$H+X;b!u|x% z3v}ET)ipY9u>j@aPpo|O^GiCJqho~Ap$(n}Evnzie&K?=IFtRl1T#ne`dLVGbQ;iU zi`1|02!F3K)VLcWsasMfCX)yQo9F%#^heDsNUNei_aTKS+2NQ)F2_u5A(E6k7K>Df zCmqy?liGA|z$W6BkX9Km$s(?=+;;$?h%iQvMGPHr{|VY;oMGsAwspow+z!YQ${yR& z`Z$hw6LAoNuv1TrTyb<@&9p(stPx>kj$Fj;8gau%()xTbvx9-DO_>@A3)dvx*CJzp zvfR*wk2;eN#II%qp!0}EQ!n>}H!)Mw$k^ z_QpriCos5%$KAw2YE@lP8^KL=UENY^?JMezS`SuKSEZaye%OVFc-#sWX2uy6w!8d# zt1CH^1o}F<3YF+1%@UrE^h<(@W9REQ=3|awNo{pGnX{6VC~F)`HsZLbvPsTc&f8X1 z8i_3W47>AdKQbpcL+rU@td3f~ma>Lp;%<@X4BPlQ=bOcHx|QX^)Fa&HAw&f literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/lib-tk/SimpleDialog.pyc b/PythonHome/Lib/lib-tk/SimpleDialog.pyc new file mode 100644 index 0000000000000000000000000000000000000000..f712ac77b8e64912c8ab8d54bb72ebe3ba295f24 GIT binary patch literal 4174 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 literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/lib-tk/Tix.pyc b/PythonHome/Lib/lib-tk/Tix.pyc new file mode 100644 index 0000000000000000000000000000000000000000..2642bd6c400fdff68d41e5c9a7416c8cc76ce0e3 GIT binary patch literal 91067 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 J@4U3$_&>(VdA9%n literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/lib-tk/Tkinter.pyc b/PythonHome/Lib/lib-tk/Tkinter.pyc new file mode 100644 index 0000000000000000000000000000000000000000..0fa768839c1757ff8ca0b38f0d9041a612767a62 GIT binary patch literal 189968 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 literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/lib-tk/tkCommonDialog.pyc b/PythonHome/Lib/lib-tk/tkCommonDialog.pyc new file mode 100644 index 0000000000000000000000000000000000000000..ef5a85265b4d6a46b339bf18a042512626610dab GIT binary patch literal 1426 zcmb7D&2G~`5T0Gwqy!Sd;K`vdt{@&jkeSAI8E~IZycRTK+g-4(0bkq z)J=`eotmoYimIqpHRPFHoo&|OkUqD7Z(DgdW?fExzUYgv@b<&gS!uT+8Xg^~Ay>zT zJzs~#VEzfq3KCY@IthLBMObwHB)0Pvw#NbtV% zp-z2G=Xe1kyhI~_OVj4@5_MV9ycP<6XwQxf_dR?y;9KEa@Rn)B}LvDuQ1l4$+l_`4p7D8lStuzVTTVPyXHfewq z;?^PlO-;D}*cq4Mz>P2*tE5Z1wpej0&TJK=m)xRG6eieRQJ+7GRJEDc@to%kuNVrE<}F4?@3gW*wfyzqSu$GJm?)S zdP@>b3?xhzy<-whv9Vv4=!RCtC8}s;LZWGjX5=OIpVa!S)~6(zlW1P+HzZon$rXt) zc~Oo%>Hft;OR_(s8Z1kDR`zG5_rpPRPWI;{o|D$RmJ1TC$b~0{U5nbaBp29nM)uO1 zQi_))UXi9J$5YZ>Gk8)Xzlw3(n-blXLjxqt{!QtvOMFXWbWT&;{;I^Q(z;EY%wBp& zurRtUkDtV|(z?Um=#H#DenMfccso;>l+C0ayIv=@RUa)!;qJ79 zKAt!0xFk!hn?U`uxc9Kz&APc_CG^<1-K^qQw6JTaeR!~)JUeJ7&+fb919$ug!gG~B z?DX6XOsF-J7k#PUMblEU7~i{VrcHwV561ysK0>%K#s=2M}Ch4J@LC*t+`m<9PD{zi7J9T%YAlptmaUr`DU5ZNU zCvlbfhb&as^CUWqomRWCJ#D*?rwOMy&b4|1{9e@rTul??!bl*y!sVvyRXiUynD$EM z7Jlcy91Ly<0|;iG`bUZWLE@+nJ+Q|?GwTNRU;t>~vLJ(4HHbT|0Z#7n2zV>sr~=;K&%?rR8dX@nRF=|0!@?>wb{4jTO;B=>VN^D-<> zrxE29t_~5s8ZBE8XvuU&*M4mEG_GEz`uF>4e9|yXpl8WCgO^VPdcub4<$`q&|u_l2S_+vmIlbq;AwHBLkUeC-a;`n=>Gr? z+4PDr?Mw7&?2z)53GbrS;HFf&fap7D5Evr`3;XxxxAbCF|K)849CL@YpJ2%_d<+aR zKl~oFBGQg~3Crjfz>17K!O{}C2$<*sGn{i|W zj6b58r?vh9?joeMgn=&4SDCVnN&!P3fG12dkYBv`CZpBX=WCijAd5AMjApJt2DiQW z@}BG=`@q6HZS6bqpCEOB)Youp2vh-+f~5TDU)?$JayUncN6d6`(4QDE$4dV@2QQH? z52k8+-jnqXq($L-sOFdR2dL#Sm{WIE@NsCNWU=W(*HnLky zJ)ZwxIQkRF9w2`?^Xy;TSE6YVuoRl`eF)8wEAY8C6#PyA6vH6)H*{PkCpz@2@(MQv z^Yx*c#a%h7oKlNs3-n`#Lc@1hynP_=SblO0A` z3AwrDtzK`pmAqC>{+?wXxS5@{qae)?SIO;1IP#B!JW7(7`Inr=ehrwH<%Az&N|hn5 zpOI}MiOkacOE*NfXu_-4W~gRW48F|)MwXDi5E9PtBNpFh@dFl1C>+BjzJv7F_Htin zXN@{O%BhZxUB5+d+TN@^*xuG0JZ;z7_4F`Fo0+Dzn@_hM?mqmbj{W?klXabbhicB_ z2>~;gi zoVT*Rva~Y3vOGD4zZ;c_%6w&Fa=cPTTJQTv?HA1o-co77_-5A3pd2%c-a={8{0Bcy B!y*6x literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/lib-tk/tkFont.pyc b/PythonHome/Lib/lib-tk/tkFont.pyc new file mode 100644 index 0000000000000000000000000000000000000000..2d0daf3d5c3a90fd8c231620b18b3ceb4879c29e GIT binary patch literal 6815 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 literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/lib-tk/tkMessageBox.pyc b/PythonHome/Lib/lib-tk/tkMessageBox.pyc new file mode 100644 index 0000000000000000000000000000000000000000..df1ab0679254005e9948a264eb8dd125819eaaa5 GIT binary patch literal 3729 zcmb_fS#uLd5bl*^`M|b}!R9hy0|CTka*%_BvN1+6E{GJbOu5)1rK~k;vyrsx?2HRs zWuD-b%0r&>KX}N$$`44s?wtigIUxp1yRGSOj_&DeM#aBIhF-4x+-#Hm^x^j=Uj3&- zr0_V@CF(ikJLISW`2|u%@{6QO5wEOn#YEKl%Nn2FM>EHAwy-sUh-*NF5;m z0I6Z}he?f)KSFAh{Ly@Th5QPsG4jVq9VGuCsc{M&T60JpqUS`8PJz;w z4$QF-LiR_bPSLXhE!=@o7D9*z;#vf72n~RIY>^TWC;{ZOMa}?$9zZ^^$XOsz1;{yz zoCgAJfK)AV0mzgf7c(S=(=Ji7dKq4f{>G;YPm(Ev+>U~7vToSNVVWkXDe;(iEinUV z{JI%x6D6_f2lF^c<0xJ?V`vAf7@CGA-HO)Z1dRf~q$87(PCJO(Vb>f0CSxqmLbgI3 zC(&tyUcL!dA-+0co{*iQ4Qk%ko<-m9%ZU zo%DJ^3{T+mn&>I8(+}@Os}H-;>J`&@XgXGFNSWT)@(yCab-bD-mYs5;Ee$Zd;k(@P z2go+U>lE)}yF{ISZUaFZ$PGAoyGZE_Ati113?tlK$hzTPN|AF>a)zSQ`!?!B>-{3&}|MT2q`}ZwRYRTII0tjxjk7B4Sz* zOJ+q{hDEcGWP?Lk%d|AqdvHs(5UVzib;OJ0jMIp`W&H9xUZ^-_r{t6hZH_C}l@$}8 zO`^f}#N&{`14|a@1xzOyC=uGk@@^2joOF3OR(TcgEYD^uF4n(q$mSb&vz}L*_RgSt zFFP8*c-|08TjDnBOz)vOZ!J^ZwS{39<=Olzb6$P1zTlll`$M(oio)7kiT9a(-wjM) za&CJmeY@z-fmHLnhPN-;4_fU-+Jg_#eH4@DbjJkL&kIxGs3W=m-bVNoi@fR2ckCI5=Ubchrm=?i5lGhYW{L1V z;|{zTdFO#7Cd6LlkY2;I|JdjZy8q4Fa5Wr`)4_Tk#}>|zYkXieITFfQBybMv+aP;2 z!ezIf#1a$P{h%AF>3VjwaP`c>f&C^qU?ai>FV~BVmlDg%?4R{GKXdD4igkc!zC0jU z3d7DY4vY^AncP~t<;`ly8IwluOr1Bw=mNBptC?3@_8wT{a0wKCU&6{7X6LOC>%R&v zd)Mj(QH%=}r&Dty=;;a?we@v(5rS`h?B#Vt!#rZxxcdOwoiJ6_ZRm%G xf7Rkfb}63W!lUnijFoYb+ix6K89y_-UVGP+xR3 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 literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/lib-tk/ttk.pyc b/PythonHome/Lib/lib-tk/ttk.pyc new file mode 100644 index 0000000000000000000000000000000000000000..505fd54ceb6010932a9db5708c1f2fbbb7f35f8e GIT binary patch literal 60597 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"EGg{vwB} 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 Hw!;4hneAH- literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/idlelib/FileList.pyc b/PythonHome/Lib/idlelib/FileList.pyc new file mode 100644 index 0000000000000000000000000000000000000000..760958ffce258445b54aebd4170af16c91f0406e GIT binary patch literal 3783 zcma)9U2i1C6}{E-VbAP%*Si>4B2ZdL3$sM)2tfi$%qp-;5(yaCo|U{rqdRJV_doY)R6T??o;}zC1#|#m-SvY)g{1j6EqH zi*0h+WU6r3--hz^fA|~p4aAboTO~*TnojJesVi3oc^Lc%Uzeh>P;8cFc`|JXHZ+M> z@0fIH(Dz1;+Cmv-L56*hVHMx@?0duO2`n*Qt*}n!Xq+Nor8W8OG-9Ho|h^lXz0#F&TZ(_`>s=1M@*Pw+WpqtOJ;e<=!{-3fkAk)`V@TyY zT!TK=TsCCLT{Nl#*M$cRfd6q(|qI<;66PoDG=Xk{KxTnHn^Y#`a7xV~E0*<`V?w>){OJd7rj zFh+A6#p8X9>KPUD5@6Re+f@>1IE{P2d5dOobD0MNTJYpBds&*O7vruJZ;1i382Q`Z z0kh!~fUCH#Z!6F~K(SeY^Mguqkq#+$A%rU+G7STF5ADM|d$aV%Sw8p6Gtk9V()aV@ z5tw7&_xtM6-6~!h%x$dw#4eOG^hmFd{P_h=B^|4-NwH&h1T{))qc(J;9wSs08{dsBZ&nU`(7@2A~eFa{D^Go`(0` zUxXKnG;q}^cVnLB;z$G9qRfCJ5sb9zJ78AW+fsg3dcf%(b!4P0Pr^{1$68|e-&z|% z^<2}^n(&{c_9l{#>%>ZXOAb&cQ5^vHL|I2mPPKMNOAgZyJ5(2x9@L5}(`foVv$(#T zhxLc&_e>KEPh{N%unhW7Dwl?u=z-fuAU6a^p+tSx?O@3Ol4%tb2WSMfW{un)uuJr^>Yy5d8u((|i$ z93(`X-pksJU9Z#bz1VB@8lA09uj9vO7MWZ;4HV$>i9)fkxzxWGlVA-^rYm1n=d(tr5%3(7~}I1m>ko_IkC1}*(CGEep$4-8JsxYa z=4pAB6wzFxq^Ln5ep=-~!@nvx(-vZ;fQqS=^Kfj(DU54V~ zN(5RQioBme*a literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/idlelib/FormatParagraph.pyc b/PythonHome/Lib/idlelib/FormatParagraph.pyc new file mode 100644 index 0000000000000000000000000000000000000000..2680d6c3f358c8bd8c2b480b730ec88a46da446b GIT binary patch literal 6912 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 + +- This is a modification of the CVS version of IDLE 0.5, updated as of + 2000-03-09. It is alpha software and might be unstable. If it breaks, you + get to keep both pieces. + +- If you have problems or suggestions, you should either contact me or post to + the list at http://www.python.org/mailman/listinfo/idle-dev (making it clear + that you are using this modified version of IDLE). + +- Changes: + + - The ExecBinding module, a replacement for ScriptBinding, executes programs + in a separate process, piping standard I/O through an RPC mechanism to an + OnDemandOutputWindow in IDLE. It supports executing unnamed programs + (through a temporary file). It does not yet support debugging. + + - When running programs with ExecBinding, tracebacks will be clipped to + exclude system modules. If, however, a system module calls back into the + user program, that part of the traceback will be shown. + + - The OnDemandOutputWindow class has been improved. In particular, it now + supports a readline() function used to implement user input, and a + scroll_clear() operation which is used to hide the output of a previous run + by scrolling it out of the window. + + - Startup behavior has been changed. By default IDLE starts up with just a + blank editor window, rather than an interactive window. Opening a file in + such a blank window replaces the (nonexistent) contents of that window + instead of creating another window. Because of the need to have a + well-known port for the ExecBinding protocol, only one copy of IDLE can be + running. Additional invocations use the RPC mechanism to report their + command line arguments to the copy already running. + + - The menus have been reorganized. In particular, the excessively large + 'edit' menu has been split up into 'edit', 'format', and 'run'. + + - 'Python Documentation' now works on Windows, if the win32api module is + present. + + - A few key bindings have been changed: F1 now loads Python Documentation + instead of the IDLE help; shift-TAB is now a synonym for unindent. + +- New modules: + + ExecBinding.py Executes program through loader + loader.py Bootstraps user program + protocol.py RPC protocol + Remote.py User-process interpreter + spawn.py OS-specific code to start programs + +- Files modified: + + autoindent.py ( bindings tweaked ) + bindings.py ( menus reorganized ) + config.txt ( execbinding enabled ) + editorwindow.py ( new menus, fixed 'Python Documentation' ) + filelist.py ( hook for "open in same window" ) + formatparagraph.py ( bindings tweaked ) + idle.bat ( removed absolute pathname ) + idle.pyw ( weird bug due to import with same name? ) + iobinding.py ( open in same window, EOL convention ) + keydefs.py ( bindings tweaked ) + outputwindow.py ( readline, scroll_clear, etc ) + pyshell.py ( changed startup behavior ) + readme.txt ( ) + + + +IDLE 0.5 - February 2000 - Release Notes +---------------------------------------- + +This is an early release of IDLE, my own attempt at a Tkinter-based +IDE for Python. + +(For a more detailed change log, see the file ChangeLog.) + +FEATURES + +IDLE has the following features: + +- coded in 100% pure Python, using the Tkinter GUI toolkit (i.e. Tcl/Tk) + +- cross-platform: works on Windows and Unix (on the Mac, there are +currently problems with Tcl/Tk) + +- multi-window text editor with multiple undo, Python colorizing +and many other features, e.g. smart indent and call tips + +- Python shell window (a.k.a. interactive interpreter) + +- debugger (not complete, but you can set breakpoints, view and step) + +USAGE + +The main program is in the file "idle.py"; on Unix, you should be able +to run it by typing "./idle.py" to your shell. On Windows, you can +run it by double-clicking it; you can use idle.pyw to avoid popping up +a DOS console. If you want to pass command line arguments on Windows, +use the batch file idle.bat. + +Command line arguments: files passed on the command line are executed, +not opened for editing, unless you give the -e command line option. +Try "./idle.py -h" to see other command line options. + +IDLE requires Python 1.5.2, so it is currently only usable with a +Python 1.5.2 distribution. (An older version of IDLE is distributed +with Python 1.5.2; you can drop this version on top of it.) + +COPYRIGHT + +IDLE is covered by the standard Python copyright notice +(http://www.python.org/doc/Copyright.html). + + +New in IDLE 0.5 (2/15/2000) +--------------------------- + +Tons of stuff, much of it contributed by Tim Peters and Mark Hammond: + +- Status bar, displaying current line/column (Moshe Zadka). + +- Better stack viewer, using tree widget. (XXX Only used by Stack +Viewer menu, not by the debugger.) + +- Format paragraph now recognizes Python block comments and reformats +them correctly (MH) + +- New version of pyclbr.py parses top-level functions and understands +much more of Python's syntax; this is reflected in the class and path +browsers (TP) + +- Much better auto-indent; knows how to indent the insides of +multi-line statements (TP) + +- Call tip window pops up when you type the name of a known function +followed by an open parenthesis. Hit ESC or click elsewhere in the +window to close the tip window (MH) + +- Comment out region now inserts ## to make it stand out more (TP) + +- New path and class browsers based on a tree widget that looks +familiar to Windows users + +- Reworked script running commands to be more intuitive: I/O now +always goes to the *Python Shell* window, and raw_input() works +correctly. You use F5 to import/reload a module: this adds the module +name to the __main__ namespace. You use Control-F5 to run a script: +this runs the script *in* the __main__ namespace. The latter also +sets sys.argv[] to the script name + + +New in IDLE 0.4 (4/7/99) +------------------------ + +Most important change: a new menu entry "File -> Path browser", shows +a 4-column hierarchical browser which lets you browse sys.path, +directories, modules, and classes. Yes, it's a superset of the Class +browser menu entry. There's also a new internal module, +MultiScrolledLists.py, which provides the framework for this dialog. + + +New in IDLE 0.3 (2/17/99) +------------------------- + +Most important changes: + +- Enabled support for running a module, with or without the debugger. +Output goes to a new window. Pressing F5 in a module is effectively a +reload of that module; Control-F5 loads it under the debugger. + +- Re-enable tearing off the Windows menu, and make a torn-off Windows +menu update itself whenever a window is opened or closed. + +- Menu items can now be have a checkbox (when the menu label starts +with "!"); use this for the Debugger and "Auto-open stack viewer" +(was: JIT stack viewer) menu items. + +- Added a Quit button to the Debugger API. + +- The current directory is explicitly inserted into sys.path. + +- Fix the debugger (when using Python 1.5.2b2) to use canonical +filenames for breakpoints, so these actually work. (There's still a +lot of work to be done to the management of breakpoints in the +debugger though.) + +- Closing a window that is still colorizing now actually works. + +- Allow dragging of the separator between the two list boxes in the +class browser. + +- Bind ESC to "close window" of the debugger, stack viewer and class +browser. It removes the selection highlighting in regular text +windows. (These are standard Windows conventions.) + + +New in IDLE 0.2 (1/8/99) +------------------------ + +Lots of changes; here are the highlights: + +General: + +- You can now write and configure your own IDLE extension modules; see +extend.txt. + + +File menu: + +The command to open the Python shell window is now in the File menu. + + +Edit menu: + +New Find dialog with more options; replace dialog; find in files dialog. + +Commands to tabify or untabify a region. + +Command to format a paragraph. + + +Debug menu: + +JIT (Just-In-Time) stack viewer toggle -- if set, the stack viewer +automaticall pops up when you get a traceback. + +Windows menu: + +Zoom height -- make the window full height. + + +Help menu: + +The help text now show up in a regular window so you can search and +even edit it if you like. + + + +IDLE 0.1 was distributed with the Python 1.5.2b1 release on 12/22/98. + +====================================================================== diff --git a/PythonHome/Lib/idlelib/HyperParser.pyc b/PythonHome/Lib/idlelib/HyperParser.pyc new file mode 100644 index 0000000000000000000000000000000000000000..ba42c645b7def38c5edef388b3029a818759d92e GIT binary patch literal 6520 zcmb_gTW=&s6|U;J&yKy`i*Ly$=_Fd>&2A>yNGMAZ0^|lkusH372xmjno^IQ1x4Xw( zHM@3VODLNco_I&_hduPYtbRoqo^ zLw%&wJ*B?C-cU(X#Z9&Asj?U^ZK?H^N?K~Ct>Tu7QFhclt#uAYo?2TuL*{=)v04^) z(m3&>_)e4$lGqyN&0t_;ux$0vwfg>~>hBfCW{3V(dIuBI9F+GW3j#j=L9#n63sAvGoaD9| z+4KiRoPf$S2S*`_V~AMfQT70_E{OTYmZO0km5EBA|i!jRK zdavq}#tf}QITgrCS5r$i8 z2^%G)wz6Gy)aE+uc=5Qy{bI_(F}mw&=ZsMAsUs}xas`}q5tB6sXN34H2P@W?eugf+ z+fnAvqzg9mFgZu><}M%>81__oS)&AnWr&sIT(s5c z+juA$Ji>2ii25K#UHgB zM$a;(o3zkak{-bICAy6zFn(Ou)`ts3UIPRzLMijFb9SE~B8I~fTNo)w% zk-@FR+IcM91jlfzDB^HPbi{a6TKf=2!i`ay#o=H(D#JAALf9?b9OVO{db7wAk)Bku z!p>lcjkdyJncOL(9Q3INvLlq0(OpU{do;Ef0zGLTIHppV8fKB9Yf%O zU$^myZtC-TNw@WacOLZ_uc^EBNAyf>uHMmSYc=ndH=wgp<=oM0_{<^%!{Om!78tGS zWBg@*o!EqPwRG(9Gy{Wov6pWu94H)pfbIeYKh!D*8MGlVK+7R}OC78VZD6otGRE8` z()f*xwW}FK;$u zL0q)Q(2m)A@X!8afuMw;XS_wf_b(eC2L%}oG7a*oU@|^gE2wi*B5d#o)&)E&;=Tco zymLWf*7u@pl)M3CEiK(h#7gt=furk6S9OpA;!*G@iWNFb;IkmO1Xod;PkM7COu_%(dGb zTkLr(e9LLfso#YUn2k!D0(9CVf-;F&UvUu4WBP;~)2AeO1ka!&=%ZMX{Zl8wH5Q_2 z>Pe!BsOS`m5wu9n31%XFRuVTmLlEX5lbv3o`JJ^zY(IWEKgBO{?A~d?$08oDa`-isW!&X`b*Fg?W|+gaN51fQ86Kfth|%-aH(*d!TZb|sL|;cmAy5WRet zH?}p>?J%3pUlJbfX7(8pR5T&@(nJcRx{`=PstR8}hSh=ucbwd>&*yjmA8y7qP zx4m+0LZfuj5=`VGRLj<3cY5~RwiktGnZug(WXVdcZL&Xr{Xh`Ey{>APXpNFBy{S2GEPIyHn-i-^sDP0GO~`o;u!*`-|60#kP{BrWY#f3 z{U4zL6d-tAC*I&V@?3t2X_o_{B}tbQ;~%>x;I!Y7TPGm|$Z}9EkjW0%DaE)Wem54rW z_-PH<7@5Eobu1TYg|UPHJoQ=0{98sHHmNBT%Xn$wUeGU{ zlz0Ef`kgTeNLcOsPfoNc<48yrRefTQBAZk0GTvZ#fX;jSkvHyYOV@4h0C^|$@AMf| z!%jBHg;nS~G2vzJ9k*-fXcc?rM~W`gH`L?qLCkyzN37yrROO)l-PF2U#pDtHjGlf9um^izpT3}B2FKyajX5>dzKZC-&GyjxGP zGTX%{LqN*$%!y0OAj&d4OKiHZOiC$UO!?j_Sz=$XU(i87tRD~vQ(iRX@nhv(`FZLI z0q8Q=cy;t$cVW3s4Lr?al1sbP`YQV5TF$s5ZxfvSn_kVU=_kDz-O|3-)t%aszJ%XdJzuMPO?>m1)5X`R z^=h;FDU4k7>L@vK$FL*S(cFaFJJ#FwAlD3`0>x815DEC_^*2f(dd{ z3wY-W#4cZFjgJk%n<&I~?xG~RiOe8P!wmXJkeo2?$LUsTP4F^Te3=Ce6x>8{qA01E zOX&NoH@1LxFnLU2s(@X-(3$VFJI%9Ko8ColrqStCo7s!-;uM-EFspj4>+?5+qu4%+ zaGMYM?hQx65R$45WMcME+|vox!E%XLVHg(!Xya{k1UwefTTzyGIFT&)4u{$(MtGGW g8*x<%bK0E>m6x3vUZD~tXf=^3^zgoO;qUzY50w3BB1)nzmaVZB*_2{3wwxxep(v3k+LkSo%8)K4n#y{)J4-IP zJF}V@iegF?h~*+}g7lIE3EVVj-_q6vil%7$P$Wf>OC9tA6b;a(eQSZDX^ZxuK%2Mp z`@S=?OVUb28+{1LJv?*fKezw<_w#T5zx#{7_1#a-R89J`2me2UPyFSaF*W=-rfJN4 zr|y_}Cu`4{`CL}doB4cJ?=kZ|S-scH_h$7zGvAlh_n7%TS$(gW->Z7gGz(^yv*t~+ zXj(-xUo;M%drWhmX_d@;$v7Ja1>9?zJ*L%f=KGB^7aTS{{(xC6n&=zGahw|F>NkO7 zu5FymrWrKzgT@~;D?=*xo7x_8H^Z0j9-D4;i+M zm|DTC=1g?M*?3sP9VSezXpR!1$E+MN{vmVM;qd!0{85d1JsUOnn%TIde#cZkKv4F? z-*L0L*R((BppF%y9(~TSGY4kp(6=!3gT{ZzV1jyHa~#cKl8uXRUsPx4f7&wifBwj! ziO~}p*J9)l$0bIDl|yF56;?3nUbFJBsqNDi9x=6&@r$MoD(N?`8^T%j<=JPSj`Mi^Uw`ta z3I3U+7eytmHX5p}H-e|mHaJ0i3dP4>aTk(>`i(Ou$In#5S|eC`<(UuNVB?K5qpyrD ztdHM#@9AU^kduLZ|B@fal_kH5CjD@zi}=K+QTRZNn2PM=2p8a`oGM_XyehrMn;Gq4 zm#0u%4(egla@S%%a+Bps;#LCJPv>%LezjSNDoG;@+(zsMzF+fe<5ljjh!4>)flvG` ztOC2;G^XsBBxg1q;Q`uCH=EY zamxdT-)E8%hp$04U=+u>(_=QlH2tLbWPpqY^xZW%Cm9kPMk@-g*KGEh74Ysp653|Y zjF5%dw!JTiFB!%Nd8a$mfQ83weP*+7XAjMGfU{xMclMagJzF5s(Q*#v6@m^5ZHG)U zLO||gkVFkq1_h_caq@TenoV$rUD{!CL~?{=T{~!(*69pZx806n_S~I<*)06%ZXEtt zdRml@GovFo&Z(FOd(QKdwJ11mA132!rR|>w5{;RAseEbj%H-^1dG7MmrRlkN9~v*e zZ`z%!L;*-RA#o-C?IeB%m8mcoyD&3x`LbIN*Mi#P?uMVZLAaC1Kv(XCTFtGv%|_s( zSoJkd+^G3UAI7N!)#Wf!TRjYtg!-i#u0;($YM^Rja`8!b?97;JIprDmRLn=)rO|B0 zuL2?o-3|0|>y4&goLCOS*mtL2bkQ7FZuwvV&^h0^l^FetleI=-J1qHuA61%e*d{x~ z>H)Z*ns!=GHxF%RrdPGRnqRN1H50r1YSOsnr>kzYDnU)n{_QrZRv=K;Xuj5lmN5DN z*Gu{FY^53d3DF!chilDR*~hXHp3-ax(R9miYLihICaNqpFg%BgbcSU>0An1f7M8~^ej&!|MuK7(r@yifUwQyY!XiORjS~)Qu8r3ieDlI=D|0lo$2fR{QOlNOb zs;hc6JAG9mbWQ-1K@x3fuZ;jgCef>Fc3Tlf^GH&9U&Rq)EFSj7wIsnIlaQ`VK0B+* z#p&7SEm}jn{{g%$125$ysswQZTO6fS5^(G{>l&$5i4)AqCF88T69nK9HJ`Nq&f0%Z zY2-ys8>?y20xX^#1+-BSA46??;Ywq1fzrQ;|CgsP0%0Kf@%Dz0RxUS!Mp7COsms??Nt;t79fO5GOR?B7YgQ#l*9*61fc{k_gaiA;sNYwQ?eNN%g zLSEbF8c5|jfiI!bIRR)@=nItY9mm{$l0x*-jZ@}Mj^@J()EeGH`b+mgsIL}G^q{$V z^Ff2ZIW)|q3eYMEC`bIk5bZU0ddO!yOCff3@~V6G15b??i!Oe=N&^D%N*J!LwI`z} zjNC?j`#_M7)-3RAF8IY=3s!@0Js4N_m}F3Fkbor9tW_10c3-w|-4%`QMXTgM+-^dg z74T>!cNt=fSZ`I5>ay4wO2jrTMd4c8N{bN7h*fQBxe`-bR&EK1j2|af05oGO9;sox z^PHXRLgMl+pwgw9`!PBNV!G70?N^C&buoP-;Ba#A-dv9}2)@oc`y}V~LOa+hbmbn*{>` zuE&6EdU!7bB+~i)#vi6{LdT?_Ua%sHs=z(jrwVM2k}5DeWRA}t%}nuQG+DTw2U2T% z{&;4IKS*nYuO8B>w32z()bIyG{}HnUZx5AYf`P@45ssVJu_V~}532D!ruL93r)ajG z1g@&2E`E5l6ZpixjRO1!-Yl!KV(Zr26gQ@(CzwqJXBkE!M5%pcO;A~-907dQd1Xye zId^;o8?5unj!?)31lA=S$}lB6FfcJu@6TXhjnc%TOqq(0qC9slZ2Q5ORk>sJC~S?< z^f-S$rp15m94(UcE!qz6Y#Xb@89dcm3SSM|8)IQT8?_5VJ$vq4J8A?;XV6hjBtc4x z0t@lTh29ai_MqVUk^`ueJG2W0S1YTX09@j|0Mssl1b{Mh@S(R4LKwV}StF=2*Pd{n zJEkKf-+3R#I~g{_Q|6|qLHo+A7n*`QhS2*_l8v;Y_X29WW_YQW&!dNoOlWj)_yhPY ziPs15+)VeMoNlWnJyGSBR!emd{q#pVBUpkO8+(iRAYpE$y!E*G&$g0BTMSv@LYkCu~nm4(ORWfnYl9a+Mo<>AXDs4iE6CBFm8IP?z&xh>y)A3v zOxZ_k>YAqztH8^>7sOMKd@c#DVEAs3vw#u4x@946Lyit8QwE}YixrmM9Ez?G5FSK4 zXtvVeewv?>k;}gq3H~wPaXrTA=%~(_)zOTjipFSSTg_un4lOC0g2U~)drk0DSsiAf z4!fLjIz$O{wgkf-6D^7mprJ5nAcmjO{-$JpSrdzE2xD!wT}hTj_KmpKh^#oJ8J2BF zssL|f6YpzJ}hG&zvI^qT(^QM2)&FJV& zTGjDmYKJH_2Em>H`Z~u7OyKC3(k{`@8F+lQJMaYz-p!j5TG`awsX=Ul9MOuv62dfA z!rH*o&98J@iSFR2`ofCG3k-sw3c^S!(sQup(PoGHXT3)Z6U$SKsfK7O;=8uJ(+{4* z3=WJN`hj}fb3+Gp&agYIBM|g&pPYjzls6?Q3eE0E)-7L*{K~4wlNv3du(Fdjb-meu z6-=F5iC3w{dGtDV$gE0|SfbE5OAvW40#t5TGpy7IY^65sgnC$Ai|K(&=Cvvti#{cd zEF5WBk(v!YkjiLdJj)T5@SrIK5c%!q#;%D<3wjF!q~3KYM~`igNC(u%fG3f!?a00t4A4U1D!;ez*Y2f!9x^90urpm+|75Mx&i0aCXZ0M1526C4Iu$LU~4GWg^u zD3)4aNI11zB^TXh?LFa_in;XmxgR_R6;oK4D2;yA*h;$WI4xy}4^>B^! z1Sar_AEsD`--XSJfT9=8#^IF3P9SUomI2Kmq%s!_gQ@IA)H95Epx4YbbRrK(Q&N0x z42i=u6nJwkIEPMs3Y5G7PRxT75qyV5j2i+4SS%xqkgmlWjO&9=(U+G|;O*!whF>5c zF&`d5&@*#4-|8&on_LQ>uW|AW&a%*q?&s1a{|DhXcI zHpL+EOT-z-I`Q3#`?94e7oiNqZEUQD@tVtw&fwOjUTHMr$6ZjCJ6mnK2)VkABz7T? z69r}n+sN|-NLFh}ee7wGhXTAYqy9G9Lm{ug5MoCi&Cs%UPVvV8HoG;b^w_ERF3gSt=^xB^JrS_7dU)DeyXWhc!I@xNGqYLteY z*b75MNxa@jmObvkyTuoj;3-n9X`8)(>I8S&tXJ-dh-QmPc9D~MDMT#yV zxNwj4A;~RVF*gza4hqt#Esj49W~a8TH$cE7&bX zCC|BoN^-eHCH9%}LtQOa+5>_1QFa~?NNDhu#dnHL+%J=%kdbk-+R-;Fi2pC#%Em0hB-+Me8R4VQ-MK zuv79Tn&!Sh8hEtrRQRwgU@E}vhY60pU`u!s2h*D&x}6pk)|G&Ef*C<~0!cx*?fL!G zohX_W_yE1K9jrTn(S+8!bSL^@8bM6kE1;>&T#mUTKd6m8S+(~vl9227GPy?w04n;c zH*Pl(l+_gpW=LanBrf=e-Uh*F%+Y77RDElI6MGT}p5#D`$1VEz5+BK;qdMMkJ}$B# zGkTy2v=XC5Kyp$Y>z6>bPzLA;I>2G# z93rGmfCS0bXv)|;HRO790HGyvEz`5W=N1R6Xtl;k91z&e<$~SeTrzz}l z!=`)_9qklfq2!=iM-B=V@0(U4gP{I~<_aVS2nvJ)9XkRV;JG9AfOAiIOF1wIF~t8u zkm!F!C3Zg$`i?oQ=)^t~U1!Fd-6;oAo)uPd-N{z+GOf_=l-5Yzw_{e?uiHkaEesM| zQML_?2PW7c?Z*Z`V2lILpH}kBwq8ifLH5kXcsdx;5U^AlGeZ*0;G%u%`gJGSPe@EM z7o6!J?ccT39ZNxX82B0D`%L^lavPAp!~GthM@#&JE3q|5=hUG^4GwHc(|s|A>n)vx zwVc3t@MN(yWD%jC&8NW~n3fwY=j>^$;4*BG89IP*0_6VajM$1)p{|2%-O@p8AVKqrZ)3Z!e~y(A>OCaAXl~tW2))f>=my0 zUg`ujK+nssNrWj;Pln=BIdd`OZ@}~{Gs8|DYDy%O6a^3ktyU?woKL$Kgv80GCy_=2{m5a3-53ukPG`XF<;(3ZxleF5&Ftb}-j z<|xIt8Sn!%vvt3niGKtzXqh_;kU)@c7)bIJJOUw(1jNixg*e1I9227_-a(M*Q7ga% zY#X5LqwIxvLl#LB><5_(Y3k8OvBBos6pLkL=%s2F|Q zLEa%QhAD9slN`Y)oc|CL5|P{p$#cLH+#twfy~96%6}jk0s+vJH^1)$Cru5L?}3g*@+96MZ2^Et zi0B+30I5KK=xjqC5XTd=sgd$WC8e(NB3*u{jAlL3$Gv2e{#-Tq(H19_zLX?DJA!?0 z1Cp07U70K=t#(;sw&4%o_I{0UG_szvDTfmCy1yQ)hDseA6QCr#d-nXJHd8G~lxMRY z5Lf!NdQB9cM5#4VQ&^$pj{3Ke-iY{0vKG5f+&*>tbTOtJ@4%(=F_p3?%UN&I9`V># zQ050i!Qf(ckq$f@e5+?*CniiW<`~Lol*G<_op7~k-Ep$r^ov`Z8cFz$8!s`M_^oy~ zD7A_xW~=R$(b2ocf_9t}2jYMZN^YZxH4nVW?!<4JsMdZmxxiO)hHlKE#VM z5XRctQiHH|BL$PR3k8vEl(#WB_R86-!#EY`K9 z*~x3OYM(`pumXayNcqfof}CN>-3!g8ZTGm=DhZgHfu}WrPy8ARt7EK!pR_NczW%$*pQ`8d5ad9q=;uJo=npk+Q{S}U%`Hm1UMv!sq}(S;tR3{Z`qge zE}q4dTp(FosTxNNwqw9B7ZmCqH>x7|^pTiRuuKL+nkCFe5ezX#LQL%h5!C9lcx%6b zAQVoMP^AUG31~HuDm~gz9>binmmrSe*7F!P$Savi(hYBk8o4-Pcd>%F+9E2ur>SK? z9|Uuyce;l_C%6hgV$2{)Ax7#n53tVJF~(!hE<$J=_*ZDawgA2IRdAJiRzPsA9e$B! zhJk*-D(r%D);Dd~U}OCslLsXVNW=JPHz?99lEp15MbbK-5*x3g%{#}UibA{vFSoj0 z6W8jZs2f)il8}6AZ*$t~wcX?C&oTN##1jvMymx>c1tV<;zwlLmvI(4VHXCLov3cKO z@of|$VUK%*zQpDzquUWh^V*EV1 zocU42C_2Q;Zay_Nfu%YK0hp(ty>8%Bs_kW6xw-bv&0bva(#^%a2JSRm-eyC|K@}ij zKHi!E#2}izufruGFYFWxjmzxa%|3aD+xr9teLuIyU6|aI2-E6hd)FdH-yv_kZvfUp z@`&ywa4iT2y@%)>eH889PqTQ2#RpkP*-A6d^KpTNwDlZoyd<(LMxL_a%NJ3TtiiRT zf>5|yrGW$Uq7CuntrLP5z3i#Sq3jv*jR&<&XBTeb+PUj|Y_aBALvGDx% z=lHx$f01$)S1e%x%BZ!L0x5Wl5FlKa9`8qrP|)6uw}{)3+VJJ;uX|(KNZEvrOs5@j(+S^eEAMH zw16&?omsfn?4u2B(+fbN7>64q)P3@{?YZ(uZK?>9M9TJyV~M}z&|84mJz6L|pXGwN z0@J-9iOIdjE*G?|Nw@=I6UhQ@-I&b+JQJa5oa;T?D9hKhpmP^!pH} zqCt$y(_RukesgvlnaRY+?5g$A$pgxfp%7?Q+R{IC+5ZmDGWz6$E%_mwG<-vi@YIjq z!+gKWf`VUhKiM+vO2iB4!)TOwxZbECnUeBm*>5Z@+b_1=mbbm(akbX$d4cd;SR?H2 z_&%GJvruk?WoAXgUw@kWCSj80`<0uqqSi440>1x z`OB>RAqu^NKcH{Ccwc4ncUVCG7@ZA}TNR1Ao`|WOu>_Wwwy{~h$Art^i z-6cDycM*+B_|OW1X1R%sa60GO#>Dic$(hMno9D{aOu-|!3;Z01q!#{}N^{M&X;Dok zh2o4-Lp!k!8k%57oK?lSK zsdZqstq4D}EI?FXl_(>3(z3teEg7uwVf_wmuYRsncCL2w$)a&F1QvE6_uNX zJt}Hkz##ihga82ogq^Sm5fLM6SOSEQ<>uxlxmkewd~a9;L~DQl=l?vf|MPmV3CX?Z zo^!tEp6~Z_miMJQUH7^pNXPd(UEQBY5abhN|3i9j3;mB8poXX+Z}|5f{98J-v}0+} zH1xO5?{t6l?+D_2$ro|1Gx2>8mso9|ia|1wnItB6^;BC;D2ezpkh#TnB6XdW)Wli| z0=}Bap8_9S5HBq>5jcvhE3}6bFK?JpDDKF#qV_0kR&qIm z$$XK(ac(7_KYv)M_!PKnJ15u}M7{n4YQtw&>)N7v+ynifVl8?A*Rx$x8;5rQ;a;4{cv zU)r>qXWkw*tr_)Z%fYlj;mcqeL6XJM9k{8XaF56XLAX4nHPvC-;UlA_Raela9k?=T zT6Qd$cEn@YG`Yhx?w)c?9S5eVNI96cC(~hCfoJrd?Zc);J4~y)%d|J9-MMRpc48Vb zW}1_UWFXVsM=X23&>lu0|3w19GJo1K*#!ZEMCK1$wtCny6j|oF>Kip`>{Et|MI2}jQdVa@%{br=OMv_uhjd11tSC9ts;Mbek|rJ-S)5vIEVJU0cRk-?*H`pcTool&)oUT|3^wv)xT#k}R(iVm z9^Zg?`zL1eYswS^1PLsUjV!e4Pm$&O+@5xR2=Vn!s%j@m7J*1v$diTmAfIgZ@qOeE z+fFQDLNSddvLj@DO`q=WN!A=#O&($PHlWW1~IXOf26eL1qSleDN55(pJ%L>Bocep_lX$%`v%T7~?UTv0;-AFkD+7!t`u9xaF#$6N8n zsFH>f30{_3P%YXoL@^hL&6nU#YW+>1NopvyD=JY`#6R7_#GJbMY{aD{g1{Nr{N74_ zvbZ|iLx5q;1u=fe!id%ug2+y8z_9A#VsTVh*wr9p!H>8AqAJ!X6iE0r!kE(_c*z8= zk_!)BM5XyrXOOuU3xXp>Nl8eaL~#Bb;?yZ*AkHlMfWrku(cl7!0&oF&Zv*WD@eUX0 zR*twpNTCW`Kta0zX#0GAr^5xLrPh8$;UpJW?0K@oPB!L@a{&RSpk3hk6<*N|BQ8+b zLz=+;#qnZei4`wdJUbbGPe zHH{(sZsmsHKRkIN4O}3Wc7YmZEJ^0skDMe;Z4MWZqAz{1>c6xLBv4d6zGPpiC zI6Ah6?r=CBhKhXLpP@ZKMd5Ye0k|wPHoG#mT^lO}52)Ptvqy3Ds);wO8+C6DbD-~lDz0Y!sb);m0) zOFH5KU7l{i)!+ej(Ze3Fr2?p2g21X#Mv1^9KD`@#c#vMaEk8rVu<@Fvhc46 zvN4v9`_SvXzlUDGXr$K{L$6N@O&QY@4*EiSKkc3Gq8rSPx-+gba*Z1{A zIC_1`onHUX)sbz(y*`?Xzc4B8yZz&%d-wW|cV4|;umAXs^^Ukdxz}gVy*}>USI-Xj z`WT4&j$V&7#+1;#UXog{_T>%Zdp!rVRYb@Aj)=q$Ut2lc>*=^Z*6R}!1)r?^9^(Gp zy?)JKS54~msYSnhzKS;z_vv1L5nccCJC0s|*3s)f{NzO+y4TZj-)-f8laSqxA@Q_3 zL*kKv8T>*~7`oo$2Q8w8f9^j2{^%)3f(hr}M@O!@^UHfI!JT6hK8>9(oN##T%h>t5 z^LC^eE#UpJD<*vy$>1KBQ)6u~>9RXthcmcm{*>c<(Vg^@KRIeR`QZ5P??Vpbzu)!w zHxv9;25|n~^@rl%{C#WiAm{Iw0e$`b&c9Eezh4dM^Y_W1@HfsoZo&O>a9n?n5=Jkc z>iYLaE}ZiE;aW{dG2zxuI5YAEb)YSpx6hRAvvUVMrGDg3VF<#H zLuTiQ>d0mjc_}400&(FBWf)3M$7FKMt_(%yhlw+hquJj?#BXbjCN@N<6P_@hZ z`u#~KLI{%*F;@cDIAaR=X%gWFAj|)EG&TLOw~^Nv>EPKssTfKx9z@3G)I{ z(O&NDx@ptl_UeAS-D5~hDj(&iPS$VUmvTKkyIC7*o?t+CNT(E*sGLL zke?E9U5(6&?m_B@{wQ^+Cu(CGuiBDJ4iGb%kJE7-40Q3+!4M5mVJ~ttSYW z3W@xYX+oJ@&PB;Z1mE4A?T&Kf!BVA+&lmE!A|aH=fSPdqkv|GaCC0XsvS2Tcw-;xn zJMtKZ-NhCc3zZ_F7$Zr7#0a@RvP3|dbYbxIC)SIB8<58lWC6!JUdpY#BrJqMIFoS3 zF_}Lyha%+Mev(AkUZ29ab0zXHht1{6`x(&K1O}O*n3J&B51FABSBvu_``S?2h%5UaL2*Uc7Qm3>&%x zO3kPzsYob{uG=>V*V_vv7Yga(F{rA{&vo_UwQK(=ff*c6Mp2h2O3-2_VKGAe_fNK< z{{4gr!@%r$IMyWSt&n>D@)tM^HjC-+&tTWTSj`~j<1jVDlw5H^-Y+k{vmLSq3tccZSB{cPSFJ|Y zujj5^zdlCHhba`~i^;%7VPdQ#lE;5>*>FXiF;c=H7ZU5&?i0K7xbiBFq*=~O;A0GO zwo=09yKyD5bt_rO3{Q#@n`B}Z`E*$o7MmsSB4GJ~G!g11eo0}oB#+N6kYiq}AtiVP zOg^C(PJ^3YpoHaDf`KiRi0KxF)ewo;OW3T$A{IkZ3ACGxZU{sOo+%e9p_+c!9GOJO znJa&PiB9;DqnBCeOn^E73!@3IwInIF!V2Vnyh+U$D4yNA31|Q*4B0f(d zr*9b)MldmiU}Mvz5@9U(E#@p&3w@Am@mqMYjq8g)*@@CE%QLiCE07mcdnW zALI!Mrt)_?tibGqS{e~kEra3+g%pEjo$2M0Y;R5!3v-et_#jJpO1A4JnUWMk!EgsL zrBEyplcZ8yA`uGMGBpF6ro`kJ%%Ns-dN*#|Bv%qB`IuZ8EW~<++z5$GC>BeELNBgN z&BmN~0ygqoHS?H1Dzjrmm#DcuF7}d6N*j$eR~L(85Bv9OVM@%vkTf4;iA2hmT@r$| zq=Ki!=zK6GTPWj#DXu&r1Dmc^D%BVdyi{JyrE4dKRec6FS1#jnp`Jp%yT8mAL%@w^ z$~(PCSf*FAuzBj{Y;ILXu}~N+s-)|$ZV@LX20(lvI7(>IdCFq0&`&6bo0-U_8&)CY zpF$S7lM)G31QQBHLZ~e%5(}T zbyz9*JaSka)G{Kfs@E!YsDlvHfiE3Vhge!2*zP2#gETf)5X%+up}bLb;18>VG?>j{ zv)$`C)Jlgsi0-I^(xDECBkHi;|3y?l#fqur9Cmay_ZnA_H>wU&e`FD@4!sa^+3YMz zIZrN>y3^{=J6Rnb1$E$qIuIOA_2R{`l$awKQHL&C9i(m>d4dsj5Yg(uqtyX%USDt0 zby-8$MJ?sI1kqlf2&*fn{yb|>i&`|S4t!Ed21EBkC@HCojHUe9Y=06fj~!MA*B92W zn6+#Ltq!rE4$ulAAY^pibd(#L4eG$Bi>G6k)X#OrthFm&6w~U^Kv58v`1Qd|S{-Ud zk!;`b>QE!(F7;pYj}>m?)S;dW>L8Al9cHtoGBJ-gULB-|*{tcZZ1EV`o(YRsL@ zUJMn!#AY8GuMT21$BX-zLmeV1D%NiG2X$zcA4a|WQ7>GT+HWR6333H1FZ95{0*++FkbAR7mulfm{tc$CKtQIO)KX}WS|bQ4s~$f z?7A^nBK>&TusVo{Tp_4KNjVlRkavu#!>z>J!fLNQuH4*a%wq+l1h0Ty*b#NeovaS- zUT&^J8K}do5p|G~UZd(D7*PkIm;3jza#|f0gF0|2Dop9$3+fmpbqVxp8Jjr ztHb&cb%^B^OjZY;m%D3%)S(WrS-g;cPjzs22Q`%5tq#=@5tYO0Q0-6$j@N;2{I7sI zRFA5|M(H?p;EPKf>L74;-_DkfszW5L4qfZlZ*-``d{75ItqweiR3H|k?k?YRrDN(K zq18bO>LAZfq((w*C@-f;xyMtAoJRYrCtv zzZBE~+<2zE{f;`wvV*J6v0eAL2_>WI5IIpD_@EA+Uap(jbi*oyvE$W&4;n?Q1K*wH z>b}dN4(t261mI=uW9rb%*|QJL5S&LIUn3t=2cb|P<+I$_+gqmMaKGg4x)0Pr>QIL;SGO^Bi1tUvsYBhc zI$ZjHSRLM+hfI@BQiqwNa|c*MUw=<+NI|G|Ywp&DqET&_hD<|N-A5Z>Fz!UevXBL` zCA=wwVHPb69GHYW4(s0!%h=+{iZGK_1Q=Zt0my9k>PwS^UQ4}>59aaqN?JO0n4 z<9{(py0Z|cwS1W5u5wHbhJ*j6)g!@wPQjhv4~vLj=n`N@Bw#G|r$qWcI}-cnz|3GY z_M?ak%nV{tD0Gz~p3fXFYX=g^VAnSsoh z2VyriEuaHGx@Pr??c)PKJ;42*iJ<()d0ajr9-9+L5A!yzTRkc2`yz-d16c^(Fgh3D z^EmFDhsQ;G$j=v<<~)s$B#wo7G*Ohj<%Jg~hIwQO19@^Itgf!(kB{=)#Vf^;5an5p zxrj4H0{sC~fHmvH?w2M7`PDD1SPMb#V|ug>Qvi{cCm9a%v6F&)@tRj(q=URCEeCXv zZxKUxqNf0N1^Lx$R&E>(@^k4afCO`=2jUav0GHORUKJ~OkSO2s&O56-#zlD^B^n>) z1F`8|YgVs(pa{Qu^~y;R{-|U8UmX!MA;NE3^Ts<55aA;szXy%*t6kPUK!o4?!OFKL zjsK^J@EjQbuUWZr?bH#TGcx|?aRn>Zytwk-5&p=!6{|J~$HxCtMEEspR=jxM2)}yW ziq%{05#cwyx@!B>5q{;`7gtUZ;XiU){oJ{t9BD~v* zm5vA>599x6x9!Eq4#%#;?5TDg=(V-6p9f#Vq!;$+A8+rmi|_qmIO)jyy_3P22`Pua z+$+7e_Y{fgLsMLEkCelQC#Jt|QpZVj!UexK{ZuAS%40(Q{~OYeZ=p#=PyKaVg{Dq0 z>FBuh=%iCqe;s$h)CndXMekfN>CDt$$I`zy_4&Jwj^uyW@p~Qkz3E48!M(DZ;`sY? z5mOw$=OIUx?s;~K6Z8e%Qyjn7q2F7;|0wD>laHgn(}Lfb-uw3&Fq$5IPp;~e-+x#7B6M8x-^zb{Qpe{h%Xb{SE9rgHPo4T+ z_TDQs9G|K}_eqXSfeMWEmwQ|{TEu8+_eeJGFkCV64L+gcPTb?;oiy){U3rhB4|aIx zL3+1re>0t$qN*vUHU)!nG02MY_0;^nVnIP>aao2ye6y#tLqk1myPlrYYOtxVwP^@5 zY3VLhQHyQT^sFX>)n>7n+q+C=vx(58VRQx^)Ev#V>@;yhpT%Y+QS(Ejs!?swt2>*E zS=Q`)U=?XN2l*=YgQO+q|tzDd)r%@+j_M|nAVy} zKeLk=5Zd0h#>Q5K8aFdYj@hZPMnXN^cP%F^r>3>v zV1}uQuBWNBqfeu3Z*FSs*5D=vdD6@8nnn|-+ukLMWYL_=R zwREX*lLaNun3*PLqi`UPnvFFS3NlM&y%;=!fSTtS4Z7~zbvJIecBu4526@ixV{#_z zWm(ibV`E9C!yIS_M@q0--Fm&YLEZ-&P^1gAwCRl5&*W@Yc>orL|L~ha+suG?KK~Y(AtjoMf8=O-_V>Pd(Ll9Zan4RMRHH38O)eY5Kam z`*e_vzh#!yY8#|1@-8TlWj<+|4*8lZ74g*U{_DAdtjb1c8kBq#E+jCWreCGj5fGZ36>CIzww!W?p2JM8xcuROWskor9sk0B7j%5xoxzM#?nVhkUgHhCs zoHlH@rCu@OdQCrOvf2lS;GbDrm6*s6jT3jM%r@JQTHcs0$|bXNWqR|#5bVyv9b-Z> zx)@C+qrb`NTzeGdENO!lpG9v|^!4e?11RdN4Qrb?w^+ zKX~nxZ%#+n^_b;0XeZLbB4=5w)`0;+VIYG{3?p;|W9!){%E^|CnwKm2HKqZJMVHCB z9FcWP-Djm@k$I0SK#+wC=g)uZI5Tl*h-%E14Z*eVZ?I6)>kjRZg6a`J&5{7tHHh(xTMcUHJc*d3An5VcUkqweynYyjJ zAuc{PE&Y0v(g@AuYeb-FAUpHb{3z;ep_{w>k)UaC;0888iMaey74*YIq^NNg@)mg>MV^@BDx?MsbrnRt>RMiDw+Y(KYB8J4 z{-#A{lf?q9saHr+RSBZBj4p%GhzApq)ST8E7E@nIa-GdSh}s^u*oG)uZ+G*rNZCzb zDeOJ~EY8~&S(p+LomSV_V>VJY3!Cn)EYoA)IaZ6Yqpc|;A|)$0I|RyI{!m< zLe<-v6`qrwEUZ!ymI2g=5_E<&aZ%K)G;M2*D6CvNz_2|tP+d$YU_UAmNu~z>vq(b? z4ziK&qMPL!%w)5fS>OndlXkO#G#mM_0l^d1+-xBSNxjMFLuZIxG)GXg2U2f$s9Q7g zx&|4xrBqexpw%{DEJjvt+_~ZNuQ%`7_1*e|=hJ&2fSdFN3zK}x06pA)-#tyXoIgQ0)hps^M)K%nXUb&DXxgm-uE-cgaUN1<#p;dLu6aaKi zGtl{?@OY9WlSeJ<$`?p=mLamGI3i2|E=Afba6{DT2^Sge2lnqjhW?7~|Jz|E!_T{^ zlY4=~sWqGXs;^gFh!Muc^YY{Q(J_ga;S`Z31BlgE7^=74kzej5aVQk$Ch_J&N9RDvy#td=S74E zRGz<*Ule^gJ*Oh$x~z+^4^dW4ufgcZpABe4a(5`@ES1?%^AnvB`5n5Z6cyx7l6teg zfu-viW)x-YqNCdAAKNA#QRghm7cUoAG-`!G}S&)wWrWyCj$QNvgb=!u~~8`5JeYp(i5^$iz6tS`Qml3`tg+uVS#z+@l)Om^pVSoEJ;Q|_OYzel2#pDX(3Gvx>G~1 z_BWuoi@{J}g>20QHmkwd+g@7`!ntW-kn@Z%{{M&fGtZ+dp7j1FRPqhYm~COV(b zz7oT4YG|;*P|9p#fp_>AoN-+5i#r=`^+9en2|1vWt7NThNgNT}qxn|VP6V0ztdq;L z(~+f*Fp>Fx`C`!%ubN4&n64|iT&30Naj2%V zwt6UpTA<=%gBT2BY(_CB+5#ERvxU4qbIzmClMrO_e8~5+Gs|bciZ}l4uYW+^JIO>* zmvrcZD9Fxqi-mwV!G!+$2#&Wm#qK_MzFezT^(|R7eKEyTkIySR+^VyQF!#r z)t~P`zgy*>R^F<|ab@Aa&;{xtWA?!U613MgFl6Ng<*QNhORKuwO4@o$C`&Rj=W&;R z9ayyBFR|@41>A)Q^61xrOq3CralOC4swO`wzDV11t5=KLwRn##ODIgd6q-?&^O4Ud z%U=5A&8Pl;=C(?u#q>grolDIa(&n6FhH9C%>4QCqK}mWBlw^aDXt7a;9!0*`yI}4k z)4nKaG!xwgUe7phWr9WiH}%G<$fROHiM-ovAGDhrM0_ES8=g{Fm>{lJ1n#QtWPJKp zr^gm8-4J!XrM1^@g%b!Q9LiNsiK9oEBfxrK;Vz?ya!y z+Z$&td+CKopM34ZA0z5cE3Buf$8DC|u|b#36qQn880c!W4;XH8LX<4>3n)y(K|bC& zbMBLi{Cg|Y&I&WLK1HT|e}M^wF@60*rKADJ>aOLR;&O8@#ftMUdq&h^Egcq%QB!na z=RaTl`r9>c{_UxSk375T&DCoT`Ag)dscD^YXVPs9YF>Xt=b&Cr4%#%Q&d3<#Q)Y5t z$aL^IWZ@F$O&3_zih{iA@SH18P5a>l?J%oC>q-?CQ%nB&l$smXfg8!8SFSZTY6yb? z#?821-N@VQv3Ze`(?d@!oH_H48~*d@$N%_GKvv}`%DMDXH=CNvlt8C~9)gFSxyc~^ zV6js}1bd6?mY;vFyw-qQyX4;QfBV6UpK^jupy(sEukv@;CP=rNow zM^wEo{8fB4b+tINVuIFw86`4|g}dTh|A+cE%;Y1;|{QsDXL zp#j^_0LeDbCCP$p(G~=G_}deK4Ad#Hi5`c}Bs4ZF7zPmx0wG<{Qg{juM(o{9*K*>+ zE}mh0zx?qBL^z*!9j|$T?;%9&+HD_$e}?W z^P@!ePp&_`_vhuG1qVROvBH~7Mi@U&HydG4l}q)QUa#$Izf~#DOo z!6lWEo-CNnwqCrs8wUmw4Dm5M3s&H|{$9CEDk;tr#>kc2>gfCCKZ0gMxg}6F#T%U_NcZ z^kz+ejmTCQtzZz&l~+NVP#kWKwqM!Vdi$odLY#8=#jUZ&_HO_FtM#9)dHapkA4XgV z1ZzSw+0;Y9ygnO%$d;m!Ff`HkW7gzB$PB*7Q}6aA&!rER_Wt&=FEK$MmG#}G533y_2+z;Hc8&wsqu6aePfGV8&G+=}%B zMuoXE=+tcp|7s)6ZqM-@3v=(HTDJ!gv%7^rgkp zz{FAglNhE^DH_u@rty=acozd%$98Vo_StK%{i!N4fN~y^C9)}(e{&QtMVM~n1YI|p zz>x13FaEgBg^CFn_1Tgqrz6K{+?*Blyl&X<^QB;_plbwli!Z)=&*j|=m z)yu`{5s_DOTYCFhP|$L-*@9#88xViN)#qgYP5rT%vRO-uN2fU9sA;|O@^Xe>?pJvRMK7HEs<=or7 z8Nw#Lwkbcq7o+D_CJS&DlCtb9zrf)VF`c@hP?(&Snw%almZhD$6rWjI8}RSHyt8b_ zDcVCa!dcXu#BiC#ZnNeG`FEo*cYRe;&w6#$lk?X89XT2o-*QvR^Vsp@w>!epR2E(N z&6>Kn(2~eDwT09vI;yTTR+mOswW%EO1)k#7byXH*rKIxX6VuLwhMtcWmet+L{CW8c ze+fAN7T)9xKyi_p0h?JK_BH+8nEuHppMDW~YQwF<4CVn}PMm;yqr0{DW^UA} z^OsAnHMVNyiu}uGLb79{ng(M1%{`U)U~wN9DQ}+ ztJgL`S>{u*Y-(1g)n?M=a(xtRScX_r7A0rL`ksg^x!I*P(qep@ zA1!Iu5mplnWg&){&A48X7M&2EP+pdkks(OoU+_H1OA*&LE0hiAzkKAiXTIT3PK69M zHM`Pa)$5Bx0t*QytmQmyGQyqc%}j2;)horjN}{-t+>r9R8@XBwEH5(gX}VsE#e^DG z;5cE{>iTLc3*u3)$fBmw>ym=poYd5Wqo+a>bE_M>`ZV(Boh#p1@Er$&Kwv2gruqFA zeSc#@P!VAI5(5eI2oEKs=U>%RBO8`_P_kfqyK?ohRRQ~sM+>z(qd}Q2ud-tjME(2 zjv5zQTJsYEqs2FMxXNI%(4z`J{8i}HgvFp$w<)mpqZjL?G7Tg*V5)|cifa``xw*p2 ztl?66`!(9WoBnS+|J(;B!J43cCN+Pc5kyRtb&^MGqruNO*VLO@eqEt6L05(eKoI_S zJ+3aQst~nddRS#un@uoe0%hqfmt3zZ6X)fmG0w+kS2VQusx(@Sw(k7LPyFp|$lV?p z!2}~}4J6s0fBH0mnh*oaxX@&VsfD3lW25U1bgR+8fH|NKK0~kXJ}>F$NA)fQp~qSJ zXS6DrL{d{;BFc)s;2)V@c2iDQU#HbINH#q!{uqiFlKL{K1@>}#2FMj1XjJWWWfkScdD&NwpNYw?YEq~)IvuK=p-~kuo;$MhH06|io%4g-P@}Rt+2S!T`O0Ia4zTFu9KO3a9{ll7~H{M7yx4!*rV#6 z#_|eD3BX(-d%{wS>*;R9(9M9`aO3QpH-ahWF5hbm>W{YQq&kHvCor{*G~x98$Z9gS z^mL|`WL*dq>BUu@DyTmj_kk>@L9O**$s$m7ReNn|Wm%y(EBW~8xZG>aJ^fl8Q#)Ow z?oNJX6=ZI^c#c6WvtK-4-lZ-LOsIzyXbjf#pw>;%r!K@q+)_awg~tqh962-e&QNW( z{t1YN?Kev+Bp`zsyhB&g${JvGUaQkF=&UvQjL0((qkMW$>gjx?wDAd?rKaW-@$3GauL8C0wX}Vjg%PLFr!MOs@CFIqD252F7c)=44 z+PZ}DGt^QtBoxMQHq#MSL_#3Xhu_!(EeFw;gqQ*M7rMO!PMTB<54ibbN#WZ&R~{My!D4eX$(L88j@a&Pu_ zR%JlGR$eCLYdySa=a!S`4}KM0vi5F$kC9{<{9#oBEJyVS#)N7jItI3^t%PwRUR0*m z!!4B8msFIAMWU<0`>v!*T6+4Gik_}cREuh+YkMW_d97!uMc0F<0ULRG*GFIZ?fUnA zvAngt6YIw;D7ef_lR;}Vs`OBM1Y_uZv8M`4isbzYy5{PRMoC#&aeiKA_`#6WBB@yB zqh)HQX{%a0pw5d8ti}PWQ5X3Ap@aWf^Ib|ydrPN|CdI(t=Nrs~(PF(_TU3*hsCD#? zWqNp$S*OK~q>=U^sCjEmxuhspBuYAdoOyr~!0%^i*-+_Q^(t}O8R{sRxuaH($ zmKTeJ89}@Mv*Xu`30(}WAC%Bh*`v%nL;ZOuZI0IC^mRW?16c!pZhbvhI8lLz=PkNvuJ!=b#Jo!$MmL3@ABjRY>Ne2T;^DvbU+C6E)U zUjeaL*LVABdUlOOR7t=wy}?W`&0LpAN(zheGOsc=Zr{i&lPI+uFyY2+O&^%>+(29y zJQEk-du;E|->f?zzNP3^z;e5yFgHn3-__Y=gZPE&Um{Ef4Q^1k08pNq9V3*Miz;Eu zz--j^lopnVgvF)hVsTzpTFlQU0;B5NRHrmEbZxc0dXel5^=0d^Qmvx(;4j~O`Jc~z zDZJI$*#b-MWMvbq>BD`XhgI>nqW;6cX*I%t$w_#IkvrgMYreEFEGtp25f&ZC2uoYXq0QZG<1XLz1xv+~YeWO<$BRuT|C zV7R8&8~XUAJvgRHO+B)Mb@oy;H@An-T@%#wV+`FAvz34);|{!#nI(}_6hN0s4d3Mx zcrH9%g=;luv`)F$dFo|#v#MK^&CiMs;GPrr&>7R6T~Fj(H&h3oV{yVoC0(Sh0D>C# zTDjn+0o6TYP^jvzMR;;MOL8S;*B~I}WTc?3d;LPI%co zpA+7K6+(y#Z(^o=MO)aF>y>>5YfnygJhwU}Ik`eu)1}wx+A{;W{Ol`vx|}PyWmQ$; z-0U1deodcCPGF{j<6>y%_-*+&nb z%emeOf1{`mha6iHE+$uJ=VYj~IieCtZMi5rOT=gHIu;c#m)58uOHC#$tzS>?QcAdI zqDmk}8kqV;hTfFAn(Q;j*tujwl|lv6dWe%4j3J&b(nzFX(Y5(EGcOkvU8^q0$;!#% zZ93x5xpMK$jq_S(?3xUW?uqF%$l^|(E$D~P3q~)%dkXT;1f7;N(K>_cS&-F|cA^{{ zs4)B7x%_xRUX`>oFFPye>ZxB39zMZMzjjVL9rUyRR#6BwM|Yva+LIT^%#mAR|@WFdvZcrJAA|fRJd|TZt7F)>P+ zBgpQ74E3j4t-7jn$CB$D85-dUJ-oXYD&`Agjc0Z8yvFddyxf$_IZa{bvhu5{N^-%> z_{(P#i*EMxHY$R&b96dQ4?Js|UfgWtQ4izjZL{Ha%#p})+FraJY6#T~(EX7f0O38UUqg4KjvguTHIM)YO0?W)y+~Xnv2sj$~y-lsJYm_YkG5+ z@aWkB9A*pC)Sd7gSb*+Npd$uMi+2`;T)J9N9?kFHyR)(i#`J}v>|9|&h}+MeenBzS zDi&QkZGUIII4%2HUo16Oy(>#?RaJ6M(?wWPARASXwZ9>+YHTrBJ8 z?NSXlV_Koicwsn8lb3&smFP@A5PKc6MDf=#yuTmUSLYQ(1)e>YBq?u&xsh5&!m>hF zZ*OIBbvX>_L|IoaFe3RPxa(!Wb!3#wZ31eZJ;+05G^xs%=SxX~ZTPzeugMI(l5(*q zB}sTq-mfLVKlEnPt<3zq)U;M{d3ABVNR*Qq?{UKK%;o5drz30nvZ=XIt~F{>TX&J2 zr#G?;59>QCE{M(tL=?mNJIopA5#-YfUR<=#74gm6(!!cb7_8-H3Yb47#zseFmNi>N z)ZFCn1npM5E%8WBFUd5_!*O+*Fr&N&rkb=*Eu{x^I8l40s8@%Z49z8#H_Gxwxk5ow zZfRabU6UrCdPwx;*#;}#D>`e9o>l6WZ#)h#E%*4BQ1ug$TJ6BaDh0*@>mRK)#`0e!Vz5 zEi1pWzM?Qsl%5S`Voqic$-@5#1Iw#dFZ+cgW>hx8 zgtASV8T!i>*w1CBl~&!VDG}#nUQOgx!uEAGrs=K<&4SHmd^tVa)8P%$g1WXIRd0(l z>*Aq3M_EA^L%GLK3M+2Zl@(@Zq^DgjtD;^_>yb+$In{EL!DuoY`n&pd8g+kfb0z=6 zv7K97cluurO^Qqo+<#bHdgEGgZhE>PHr8B4{k+Mx~uD^Bt87> zA=h8N*>&PVWJpFiqrMH#Omf(klbIpp_68sva)Ib(TXx`SE-xZBDK#^{w6Y*QSME#AEvvX*UtL63{YvU>YC-vh_#{D= zxTN|zgvH`Me`;<)ZCx$hA{lAPZMUg;a&AsZb=~de8=|ypwm@o5cB8DONR*wEElg{K zb{5=dQ79X;vO7;vvol*7#HoVZT!E&EnvvJ3u1hO6oS|k`=9cDWWabw(Q`5TA(rO1_ zJE}{NCy|JZEfj)iJu^*+$ za9G^`Et-r@1GjC2CR0pFlLbRr<505Z{|QP)Ghi@9Kp`s{CwpiFC(}cpq1h{p`Fn6O zhItmfK5I1TM|m<>sexvC1UVD>FVgRwkH?mDwj_Wf#&rEwI%2;8+ zcz8t#4i-{P%|N982RZ2A$}0Z{T-g(2T-kq|K0S%DnVz)+=i&h~hJ4pKdHhe=vPD)~ z?%x0Y$UL_FyI(wxm0Uk4q^xo8zv2bCeuTJlQ1pMwmo2%OoE3JM7wH#q*`tBVZ=$Mx zK$d$*t%@+$uRKu3{|aFSfK3^rs};SiWE7y({Ic9axWhqGlI9-^dc*12sztI!^#WVLY}-{eZ0+N)ff7DL=P1ogzTqh+#5Dye*MEwUw<2Y57?|1U^Arw zCFj};+6J^Gl~FH#_sgsBr>STEY#FSw4K^j^Udy{dmC`o65`BNzY|XM&>skF5x`qP|0pOQ_< znhhv{HS1!KGaRhhj>j0tC(rxW_ZSBU+nWJ3(*<@7T|NQ!{1$4qA*bH`&85h^*$;ij ztGy>`mLC+|1E|?;ug9PE{OoP_unvj@a{U&dX4SVvv5v67|QTAB36HwT1 zp=R5@Sn<>+U#x!l`Gxc5KJxr?&;9Kezq?VhHuHd0bLw;wi+pm|V{?MqD5Hk5)QKCr z#JSa?2AchaAt9}Re%bKL zC)4SHaP@(?i+42-3=RMj;vmg5hKhvz`mBQJ~QKvbKI_a)7Kd50#=rq6YGYRzkZ zfA#Nwc_H=OIMS>s4F|4`Cd~qp;DLV}bwaidqh@Bp+>8R161Crfn)N*>YBqhrKR$bp*Cd+HB@n$4a0 z_2v&hc0q>s*ZUBwmFV8 z>$yK^w)mex->>`EnlCXWjb<91P1 zXFLvhq2556DFASFkY=^_C(TxDIJfJEufd$RSG~02udjvQAs_f4e%%j z+dNwycI9F~X|vxR=w?q2b7plVz?q$oxfuUjoSElE_r2RUt^Z`rdv8Fq-C&P$W^;W< zIJ5GA6V0d@0nm)zsxOA|&hN#{f-n0sJof$a{pTP3^Yxcr`lDz!1 zWH6Hi&dkX=z@X+A?DPUl#$jgM-^9$mj0g(}4)i&EVCUDLef8!aUszN=hMCR#caVan zgN#0b!|UnEBH%XSV9$1!J7q+!4;~1}C_UfTzdIrU51ZrZ?aZ<-1Qm5Tl6N z{wu?M-ofJx2W7@f&$vDnW!CBQ?H6Yf`Bzd3sxFOCW~-lnWQ;OX3T0l zcm1?w>*il}`P3$y9c9d3et7#7jM>q42V-We%c#AkB(iELyVWAUDXpo@O-s(h&HXfE zR{I-_S%{n4=1o8S=(_bgHgAkEd*;bIjM?l+jooHaicfm!d`+(!jokwSgMHjwTi+eV ztfy7^AdFeTp?y%+51W44zUk;4#%#f|%5jXD#cEV0okiPyOg_eSR$$D6&!<$^Y0SWw zB|Q*h7U#dubN7}lKW+Zmbv$FX@VWV8j9CRvYBkB{1Ji*qV;lbfw1|=>%#=Wwl{yHs zG9b(}^j;tkX4uq(*-gfA@BO=XZr=RUfeD1!is@s7*&KeK2~$aUfmcl?|53V3nLCLt zW8tsS`|HDi88HbkD?8xh?cuR!+fS|&0kh>Z?*L|&c9^r@3=51iGvIMPws9fZM#E+K zH??DM83RXPqrg$ll!Tdh^WmW5o(J}9-!zFZTk`N2VK&=Zt=Ab_E(cwr88BjmFstht zCCnK340<00Okn^o*FP0%7Jk^DbYC0 zn>B+{825n9N&`LpPk8Oyz452JU^C$z*vux9nefhwr+oWh!4bCNri9H{P{asqh7H4J zy_ttmhL`7oU7PQQ&901t&58=TbhwO*wv51LFucPAom0bRD0Hz2tXcg9Pv2ul4({9W z?cJ=I=O}A7f5@C#1gu#YyA=L5q6M`*PP1l(t?=ljsptNzS>_>c?<0o}?%jBQ)-173 z(Ju(qZuFyEBBQ8Qo2+8Kx>1~kb`*jK(ooXMj19rJSEzi-zs2Y)Yd#s)4Fm@VKa zX)w$QHa90gXFcUdJ&$?p-RHLbhu?(Ge%$dhXCidwi_ZbpgKh=7J(zm-MCMEux)(jN zf6w0S8}Be@oxq$iG}9&_XKo*V<-2p;9psD&J!94=at3IU6Ksp>eI`O@#YenOcpljA zwr%q$bjH%SRJC@}oZJX=7WCsGkN>@#qFR2U4muqZyBj&H4?ct*Ik11< z&aK19nR*mC>o2$qIoosxIdg!l4&*GIH-enebmmmZSx1V8_wl2@?%BP0GIB=qTK7cG z)J8(yR2&1y8TSryHqU{aRW|UiDS!h~XYnGdT@X)be_w94r_S4tHtQiAXGbhdP z8(_Mlu-TVWz-GdhZ8Ywr>2!!J2i@B)LYz0oY71HEag3)i7+P>vO-Ku5!j5T@J<14b^~y;1ru>Ih{kUKZq^zWcD>4h zo8=7SW|GOcSxB&lx8J^7c?c4Wk|8~bj+-$)F+>Fj~5#F0}9e}gr_XEx@`tD)-?Qz}a zwrA7&2L#Se-4i&wv=ikV+p%@W-fdfdCvfIVBRdm-vnz-81^Vva`pf>EKmKwzaF%lq z;7s4$W7O;YbqKYh;LcRQou!@`$DNgVGQ2%@ZribM>vx|$IClmQ-_yBH0MC+=!+nxQ!87e?51&JO zx4Z7$z3Hdl37%oqd4)81mRwQZsvHNNCG7P%v47XL9s9Sr9(@q-Oc)yG0MD}S0?+CW zc?G(=ZQH)bZOae80iK;713)=$WAEZ1*VLEXQ$lQ7rYO+?cKF?SJ-{Q zGd+N386)6X%`kX&VE6yk-hD?v#f2bmY#(rXBEl8Pur_V4lfQS?ewrC`YYoVx7 zv1~MIg2(_e$SOrqk=SFD5DRDsiwTL*ByKdI(T&Dv0*Xp;kfzD*X8+H$d#5sF_ndum zJ;yg5&z-qHaByZm_d9ELWv+QMX?gto^$x z?b~zW(8;XjQ&+6tov~*5qQwdEYwW?Zg&3X{9NepeXUCVp=OAoMPJ$atIAI;0ZO+Jf zpM+q40^XmpglAs^Ji7<*Y~7~3 zeX7;?t}n^53eQ%*lb5$~72L^$Ly^3(r2!SifZHy49r=c=mI_@^$Yfx9Q>8!>@X+USjkQvr#_*KKs4xA=(YC2U7c`swo zET!uuUC`{#y`O%7pxF}*4w_|jqKTcK5Evk1!&MT`$tXftsj4ezpQVXb(%KK zbO5a%F1g{R+4n!eMJn(@d!e~Nt2GL=ZhB_h;Dub1pqVK_b2Mo7hZNdhaXie_pK1A9 z5B(X!C$G0>KWgXruk0DwGJ9^?GV?aH%r<)>VGHE6`VA=Wre)@H|Jrj~Ei;JBtevn0 zc}_p!SjudGm6TZ)>NUf$fZ32!&#VT_ve3)1J;|0?_ho3reE6h$c3hkQq3J!$mPu`8 z%h0snRS0eU{r7x?=Jz~Xc9)th8%t)((5t@}A_N`!69`3E%a#p;#~jOS8N@w0j@ZtY zA<@}5xSM5V2?&M!FS2FG)!Q8*cW>`r2u10#WiK4fmQj3}hc;UVzN{<@^&T64rN^-{ zttuOO^^}DwgIL+l1=+~?O#4?Um&VlhJWw{wJWvMVmgikBAW#<3SB+d;Z`}1s88-T$ z164ATkM+e(vM#bomeS>cJ5ta0y|s1_+*g-`1zXUc6r29Cv!@-hUIsCi+U2V0d{i}h z4;nf7^o?$EW3EqcUcL7W7uhUi*iZ1&zzt;Beug_7s(5cS8RUrz1s79;OP z-LR{H)VkLv*eOEYD;GJxz0xHec_dijRRxu%9k0PuUUi@oUx1D~UOC9Mw?K29Y*(vjOT+idFHh{!1+QHQ8(Y8ct* z!fdJzH&lU5m1O4>uiA#(5+Ti%3P5Jl81Kl zTT{xvT}q5ZeLVV3v1Ov_8Xs1v-)n@-D3~Y}(w4V?LzQHNI>Qb0F11ggIKJsMmt) zjvP2KR?ZvuQlCD3M~)aa7A|(C#J2hxVp|}fvM+XlSanJo1h)dAt&2FcwMfkGtwO@^ zb5(U+_8ME$=E&Tgocav$baNgg7mL_F#9ER*4cu}GcMou5EB!P09`C~RDP^G-8QHq= zZl82C&?&YOqoN9dpZx5aX37lpU+7OdK!59bPE_Os9t@TdIpe4>lPz= zf;aRsGT=d)ecMs)u^FQ)_fxr3S{)Q&aak+9fWn>Jy1GgxM~=xrPID?9 zg-)IxbKVG5O87h$!_WUH1v({P*1%2RrdE1`5jr`yo{xl2i|Z9q;Q(;*af(_W8LE_t z`7D2i-#HRE73Kb-2Tqw6Iy#$lz{&aRmt8WEGx1|il)5_thKWOX6;ORb!HT7 z!wvBD=N6NqY3KgO`gYciyZFkGEuAj#yyaXr8lt}WdD+ptlFxP>-kp0e|Jc=MZOxwx zko92Jx?Rc3m%KJ3GDOa0G8o^HkO_iWz;SUfYx@tW@SM^W4qol0MuWZj_w(|4De-hg zZ9`1|fdgi>wq0Sm`&tWS7?GX=T#Te@l{LPIROSh2amowCrCkKk~t`qN2QQs(}3Hw+TPeX0FugW6$6eJ38j>K^`NL zS4Sb#d(ju>*l2&r*|TM(z?m>M>ct!GR&IukI?rT-Er4hedZiF~^iAw|aB_J6Ne|6+ z(Y#%y2M?Y2xT?Bhp-vYuygZG%$WyP2?qvV9LDk{ZIT?<$qOjz>g3TL_TXRHpNr66_ z4}5f}r6%nEq+?h4M^;9OAedcxca_P4KX~aYUltiQ$4R#A8NrPJ3l!gNkaiprMii$R0+6BRod{p8H=H# z_Nr9%8+|#9ae)j8N4%lfD29d)Dl}H9Kny`MvO|sxUS(*4yCbJj4~7mD=%Q347^=oEV%UjN9b3T) zA{hRD0bHdC7#iVe07D)ZHJZndbGECmZ-rLt(1&Fu_ii*?GhiWIj!K7xY~-k}#e_@} z33!1_!W0XQaVD|Q@mtWZI=&_AGn|)2@OzNe7*!g)?Fv`K!T;ecYE)&Mm~aK$40pOI z78>J9VxiVr%@a-e%B&BeM&$(MJ5mdgDJoT~P-`QsQlS!taC(?r%;$^DsL%*+BNg&$ zD}8k1K~+NLUL2!JZ}*0<7Oqhlt+i%9u-{C4VCGPRyWHa)%m%CY2g5=#|N1hq3aN&q8OnU2hKD#-9NG; zqXCQ%^svDQwVMQ~nx9^+qZlDWkg8Y`8XX!eA-ML9P~`{rT3Tz=%WsoLNTW4EUhU62 z$skoaAO{N~bS04&6CSJ(@#J=iP)7+Q0cwlZSK}NNg$Q+ZM}+dZq2a+3f`ox~h>-8E zhcOZQI1`8vHAjVs&^}|1O0(6nNA<;2L9|j4Eak}T8lij#dQ@poT}UGIgUT;#l0pIB zI}Q<{eTE#>3zHm`sx?C!Ny4znD1;iS!g&!PQkhT~*_{x2TPuWACoP4Lsx=FajJrZ6 zL8_W}0>eUO5;0%8riVPJQx~LihP#QwPFpR3P(!&~7OoJ81OkN_5c=ek8{Jl^Aa1Qq zQDc3SV$OqVR`^CJB?2LjAbF6jBo+9er4%28?H(klS|CaF6xKGCLHABcxoTJj(AWDu(Z-c%!*dT3>s;N@K z4-1z|#6+-TJ*r0Bqrx`m$k7uvdQ|7kdQ_JZSRslaiCD~W+y>P{kLt_oxJN~`LHZum z;qt2&E53RJ&o}fvs?r_oV5L+n5)xdU4cgw+tJxT&;#mz+0SJ~5=IEP2o|LLQF)G4Mrt9+cXo?g0v-6sVd{ z?%V&VISRV{df;TG1b-FedKA?)yS?y1yYCRCnPnmcii~Q8?W$ekb zMJy&E6~&Mq2_*A}J{K{k|lO+|&%ruZmdgX)8XJ>N{~>1dG9u5aEtnphxv>&p^ne zHjkpVrwWy<*|UU!Y^jhH*E0%)+f!SbN1IWgmA=uhgt8fgj1$o#3WVcR2&$YujW;O{ z==6jMvC%w#mW;=PrmrLIDXjy_ZW;F!ho|mWQNmMyk<5sZG5kfcfM5p!kP8MtDJ{Tj z$?()w2v1P~P?;biI+zo{QE>c2dIW%g1ZzwHkV$!}@pU3LSjY^NiCK}310apYP@dXm z34pe}dFrxKIZwf5u;52zbhiK~KhtV?>gL;wxS2vGQy}3= zZ37^Vt~_-Km#09rK>ySP0KG2>UmV6`5MuV!vK|4T8wLP$VJ_#5*JNzAlwhfB10X-0 z0fRJ}Ha$fVKp(AQPg@#AutY*`NhR1QSko zFMu-j0*DtVPn;#@`7;I5nN$G;DSVUklvV&4(^JI~hW6Z;gdpTS>jDVUQxpLd&DWol zQ2xpbQvqb2p4udsl(;~9BK(MQYXZoSp5k-kR?HCLyRLYXDuAvU(o-DbjfL<9U=X6n zTLuAi?dI*8k9Fy(9g`Q%R}c)AP`<@n0Ocmf2Qis^+1w{40;uYZAU{E9@L`Goy1$9b z4w+~WKo7pyT1^U|wc1a3R(jw+p?}c}&4Hj3%_K8ZGCQ*|lYUZ^rZfnP*P=!AKC7N{f2!})?$qAcJ<`~@8ye6az5iQ7=W-5o zu2U!OGu$IbICp2u&|mlJ*RxybpW*(dcR%gxT$bk0kgk`2d418`iA%9_`sa#^qm_Pj zDJXXH=FL-s`G3xgD}nyw5kJlq=s$n6k-NsOsI;K5Yd$IxDfhSKW>p1^t0IwZ-RNLe zT2*ePo76l?_l`$)O^t35wo<5TkJ zUs|4@U#|K6y&pe6zb~WEuJNnXPEjAzbbaG`59jLfm1&C z#qi%uk0}0DT3S`QnK8Jht4dX0jUVXM3?d;P{zUPQ_Swe0F2#Uy^%$z|)#KB{--}+x z_kCmiY1^iMQXTs1<4r5 zRsE!Q-HL2;KUA=&e6v)qDx!NSNV)FOrG9ExDd|W5^1k`~{QD)+h$1Af@oC?-t=M^P z4|T3EU34}QRq_=cRMlESANm8$Yx)B;MWsQs^1t=;3#b%caI%{)IL}SKx~F^W+7sN= z!tQR=MJKs2m-KOWT;AK=dqpodd&KeXiQ-e;JtNL{Gw&{N|1Lk>EuM6V%bIKM$OYz( z{`{kyGnCc3Vy%Z+&Q0_`^zeG=YMJLzWeTT&pr2? zTl&INZsgbIrf)R&;)^f3MT-`>H{N)|z4g{x?(MhVb}Lt|bRT^1f!pxOJ8tPW=2op* z0@SW4^G$%h>M>yvgu`qrqbcaBU{AUb0S&Uxg8ijD^r!Vr9*OZ%Y&-hJ7nf&W@TsTeeghc(@$gTV&cv$7*OIk}PSNb_AfsJ(TY*!bBw*=q0D ztZBp86q>9 z8cb;HY}fcZOO|DIkhXvMMm!gbQ(|$6qr}H47oOrC9@^8DUVM_f`-(np+Q^gKQ}-0Qt}iS0 zc*|Vh73TUY#vryBs`|0V9&=NtPIYtU%yDned)VEp*yAb17z-CJbg#VfijOfq{P07! zW_6|eW6+qAYV8YVU1L0Z$6$!c%K$Z0L=*VFh1>!z*l8n$jwzrN<@{S+a7JIBoaX6ku5z$Sas)JFa8<_6#W1Frbl9R!(8nlvF?XfF__ z+@XR)1UiNDyXl{kCdOji0|a#`@R#F`HiC@ty}kS{5u=;AucVbhc&4;G>T|^7;af*o17@*Grc!H2~W{ z9@N+ew!=HGzWS=C0U65v4LRuSD}K+x{r7slop#x5z<`uKt7tK1(H_Mr4_MeN)9{t2@%hs(+Wh>Z!T}mqW&z(E>)(#yybWz-2CVy#? zho=FbgACv+^dJjx=NkEIZ{UGzcn-h87hQlB@P_~B=)^CTRakD;Yl&I+H_f`frY-Bs zqG6%guSG-V^JeXzGb?-FZ2R`@_tgb?_3`-2*INMa4-jM#>V2^j>;Qc^>qE0s-ZAU* zw)hVXlEJaBnspWpgI1Vr-EQ{Rx6C@t^{Tb8uJ~`;whdh#qiuP6=|Tx~NDiK!KnFFv zM33NqB0AtZJV!?84f>DY)&9;S)KB=I{$7-Z6PKCw6t2gM2AxM+f#?GNipm=iUP zy5g@j!-D@u|Fs?&5adA({z1>tf8>E)p&Nk~Y#cp9@3DrNXx=0RX*crYh5gq7zyi9^#QNw@Q zSr>R0KNDa2uaS*H!v|)kiiVR!!&B?yd(?XUwOa0}g_u;G<(t--T>u&a1UeGQB+wF1 z$M@fVZ*R>SXAccK&F=Yop51wQFOS&SpPK#tW3%6_GW#twyc@G;=}eDc&-f(SGd?L( zc7Qz}C4IuCcbL7FfCi7h*rZ%^tqG zhfNxMg57^*Pfr5`{PAGOTq9Og+sBhIU zBWlp#@o(S0eYOAB8qYfaBY9xItOr3J*aP>$PQYJ&&*t5AfjxFj51V}T2{utQj1vu% z0rH>ciiZD|kN>aLX3!Aq85)8;5o{%%4z8hrGPCG7duG`2 zHs#vx_OGF$VaN%#W#c+qA#;X?^F)JkbaqypJ>!$G=iagfd{Q_0B-ZEPlYUiUc6b#3 zntsXSulRmUmo8n}D@G}S4*ViDIs+ZVJk-#_GuGM=m(j+0OUyuduJ|~cQFxp^EgGH> z4UdS1Ib$!k%^RdVbts>U&dVf|ZmiFuA;cKJnj3vNp82{?#a{&dKmPdRGm%9A>=nGh z4cr4Q_2FFf9!8rIz&7Y#M-`JeJhw_euU#$0lum0sM( zMqSj$iY~~v(Sy&n4_7QUXo!z7ygkb&Q4--VfA95Q_>>V3ffqD@6L@0}@Hxl?A0Hnd z6AwWn`u{>{PkUZ8JS!Te4Hpfv1?(9buxEVISou|G_y;r$Jkf6an`roJz7<|@lBWSY zi7{B8LyXZy>zm4t^dFzW8b%xu02<;U$b))!cJjjyKiJ~?2iW{kU2V#u$H+ZK(Xn|A4=A!Rx>D zx&&I#heWj0Mh7&ZTfDpWt*N%4q^r#n4YNgqw`b9SPYU+@fPB(@SLE4U1-SGMW+rJTvlfT+w_G%5? z=Qb6YYyG`d`<^b6LmBY|{0}sQx;9#B(!o7G0bAHpS+Q_Rb&P>M-x9Ou8t?5k{sDjH z16T_JKu3T;19fe5>`o@&gHM`ANKd~8yZ*(SSNy9*uy{r{uDiAErdr4N9Ws; zhrxfVEqZXs&KN_sK#YMsR=;@Xn{s_ikflpt*?(e-{xH3OY3tq#$bJZYy|A`Z@J}` zI-fs)zhpf|N1*L>eoz7(@SpiOS3vhGB?I`*`2ze7^aL8H>B~Bd-V-BXEA+3>ev)Uz zNQ?n335v-7_Cw^gx92~M74%={$(h_k1H8xn&|mNgF*Uf;hR$Q>K_=h}{^&gRf~`?5U5m#*=qYv3 zUutLw5co^Y{P7U*qK))(It2;-M70{gvY+%UX6de{-YQ1^4M3IfIsx3 zOXxcH_+@Yp`H{yTe|+3ez}@4|9AW>fwWkcdWDSB2Y!E)-Kk#*|M|F`2e1~py2V2oM z%l;mnVLa9X`GAM(*RQ{?d=c>di^wIAgMt?Lt~vI_ z&+No_*DH^I(0|T<;1jSrnGoL-{~#mQH2~eB22cDhJiuPjckss!q>m43`k$&Z@f4&Y z>u~-lKT(FLG-S2@!^UsYt zba?#_I!;|v&%=GN+xQw?=bk>u0@~p-G@|R$qaBJ7)=E~at9)azH)|94?WyQ5xBNE< ze24JA14}7QblZzE=fvM2n`M5^5BhR^2`um)X(OOsj{^zUpHH^mh(TuNk`LooD zj{G=b{GS`|FkVq?9*frXVs-sk-6&Q!kJah1Ixkii#cEC?gl|1+zDv#!^b%Bmr^S~$ zbuWD1(%Jn zjQG23x(a`$m~)H#?dMtxzLZ~DslC_4Awz}?)ZRB={f`#3SG=*|BIP*9lW`W>OXs)b zyvY|Y+hq2pPUZCXOq8$GzqWFieE1~IS%v?^N3vf62LL|_;P2&AcL+Ag=Ps4se2#(1 znUZfL&qaQPGjZ}mZ*MkREZXak>rKZ`j~qF2z#Vto(H|U$o!EP_KH}F|i}2ONvcxI0 zaZNc#xhis=_FF}^k7HA$>^eem?&6}Pn9LW3f4FqTV(A`5m-#boa?YH|hxx(bPr`w`C;4-)kHUdm8#x~IksKAdPV$6*kd3Ik z9Fs{p>$v`AaM1AK!w0f90|5tO4tPRrJ*BXZ&-Ia?;T(~|+yJ>(^2g--;`NblS;*0l z>m$d6K6ZTGzq&QdPaG8Ti>#}}ZXtdPxbOz&%A5sG(s?F1U;WLVjgXDS2l^BS%8MkUZ6ly9)N0GhC-U+ZC0{ zc?t)<=fNh(*-`@i#1+?EbIqWlqN0Jsc0j;`a{zcj;e4H36FClYW#pO2Z;&S=$3$*} z92xngVSkCjog*(caPa!5ylcpPGhY1s_yB;|28hQ4T#*0#8}p2O*E7O_GfmFM$+4i1 zrjz{S2Qc;Cvc=B!|!0bg&8XOyv5=lNH5qV6rnRqj~&uHTV15cv9_y z(ups_ULfoZzyp9E0C>PBY{SRPcj}{Tg8Vi5cyHk!n0|Nbe>&qRA28s72Oj7T9;~(OtKc=d2rl?V_yR8Q z0Qtb1O>0-$8xti8{jqc z-vR$L*|7rRyWJJfe|--+VA7;X{lNqMhCXy2S-=nc0qY=RLo>R_T=<1xt6C?vUwY}K z7fF||RE)Gklalk>)1J!DueI0nANqs7v+i&mbe?zsyn>GaH*7W3TC2W0>ZqfxJOBLi z$7_GSUURb**i%V|*T@|RybrQ~ACzz(+R;h;0`Gtiyns*mOz^Czs3_OO&Gt08+P(dc z88c?Ugb5S8{_hT#fCqiB0rY_wkvIu|!FP!|3!k8Iqkr_WX9T?e4gQDmDs?6g@9{a% z6le}}!w;T?GhX6lzTwAaM8kc1F*n%x`GYQGI=lO z_VY8(%{Sld{eL1nLL7`P;*U7{Aui<134QztbNl(BIjq0v5_2#nfX~C`ux;pMK6H$I ziT*CY`>1`So4G0J&|j19HTjPW@V)pxcph6L*Xum&CXK=Q$-Wl;)`Z>pz5w>MC;wI} zUfa|4H@o$A`G2XT7i+ICaCHFs(LWyYbRVEd*MJq*>F;(k9HmzRYVAo?+&$w~p z`ivhxe%i!|6Spc?@zp~QJ#^dT$&+{SJIVoU&={9L`skznx%xDauRm4m?c67xc*5H) z_Dn&}^6AUtry`%G@1Hqm{a$0NQjTpi-;AS!=<5{iLC#cM$9Ii++FRYLeW1$BFa~|m zX=1n#&xCy?KIJ^^o7gjPhOk6o%`y6}QzgX5ZpMrmelBz$zXYJKyh|CN?FoC}nbDBU zKa2frQ9T3SgdKq^YYDo&c+P`%>*dkd@Gr6b8~aE0uk01rt8~&{X{_*44$<$)!5#f) z-hUOI>SLTu+JoIIoEd|?ID0S7BG~t_@9d_1Cuh_lR={sj*u$`gn)=Vb8)L+mFTRhS z>2Qv~o(EV6-?TY6=^P)G%BE%T1Z}GTr%~~GbrN+;5CWHLpU05T6 zj|3<735?C!P*G7)6#qVc8XaUDbV=>ro{%fN;azx)oRo{%o1!D9ED$-&?OVy#)g=YS+a>GmYP{;RgJoAQ;~>CmQ}C~VJWkiq$0#EG24WV zn5hmctIJecW+-JXE8Zg664$n>N^9DptxJF7pV+6JoDa{plRU{GhlTjwj>jTc#889; zC(wfv=^=@9a?%mxg1`%e-XOxk_)QSsf>B@i82~6ABm|fy!Ym1Xg}`qzOozf;1T5Tx zxoB95hUF-b$ABUhlyRVX1RGRP$Ajjm2_SnBK&v5Sek43+;Io+ctWW;gE&eaR_~o<_ za=!*WDGYjAOinH&C6@-KmItO)1V4LAOs|Z{t_#a;!RK+w`CY+9eY7f0eSLlD2R4Jj zU^1DFjg3uBO)M6xwY8PaX1BGqwYRr-baZey94?p3>NTHMwa<}{?O2nKp+?$9Tf_NB9UlpY)mW`PfScq zPEJluO`#|%kx1s}=NA?h78e(nmX=_9dS-cDDwWD)GPzv7va+I3C{|Zjl}hE>+L}tG zQmfS(jb?Lm6ZSXO|LC{2wzOKUPN&oB^*cK|ySuvvgTZJtnoOp>y}kYY{ey#p!^14|NJWhZYE0$1Sv*5j|Y!Gfnb!#D_6&CMff|JtRyxlG4p)`aF%8u;`Tb}= zS10FC9mTf6(QVV$#J4zEXpOORcAK$|WL)#Iq8k}fuYwbI%krXd!Yg6pQQ;Ntq{p_k vKD3JT9;}5;J~OZjqm>q5s)-a2?^x85`y*#VP4=+79M-LZKR4TS%V}w$kQc4#hp?QcrlXlhlYMMP>q3V0#s8Nkifv81Quv! zz`((f1q@lju*7L#Siy)5FeT0a>nx1g0{c94y8y)%ICj8vg)w^=cL1&fCy3RH9jGWs1drV<(R4>G0-8Cz`>TVr&$*63~>&MOXgBOZ4n!Q4C1+&jtq z<~?(t`({4LX1*zAzNuz@X;{B>>@A6hSbPQ+{|MusiSf_E1Z2C!KDCS}G>?5_6jyIZ zcyAcrgw+9?&<02?d_#dD1Ci> z{r&w^Ds^CBU~q7dMx)W`bOwVlG&D3kJUlWo!ela8EY|4gD4WgZa5%8s2f}_3(LhKC zAp^v8SYyHZD1*B|<1R8L1gy!qk*NjRCl21c0nak@Q;%v(p{EoQoNs>jDlJFHx#~$!Q<`HbhkPL+k-sKJw-3J?Zrf=&mG=f_VSQxecPsw%+KDoyYv`x z%PmDQY!5b%mg~s-alX->zp}joxx_`^sbBIsr#FEPPTm(nwBNduzGKUM^|1LNk~~^1 zQ_V6*j?rzDtFhh|Pug)z_LndOf`~drB$_EX?U-hy`Zqbs?F%TE`d!sYO;I*k8d1U7 zu9KzFnj|8I(@+nH?)%a&xRqXe_%Ke%bE~q#M&YSf(V}w^*Tb>ahHivGoZN0F1U7X- zqxe?`0g+m)GM=bN{?lqZH9`JJ))FCiTa}i=73LVX7nK@Euuu{7>>?{#i0u-7(235F zl9AUP>T)*v96pzFNNy&92=_Ga+C3(sSvfTYh4d KW2K}JsQ&=`vKO=f literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/idlelib/Icons/idle_48.gif b/PythonHome/Lib/idlelib/Icons/idle_48.gif new file mode 100644 index 0000000000000000000000000000000000000000..fc5304f31eed32d5f7769e471c3817b58edc10e4 GIT binary patch literal 1388 zcmc(cjXTqM0Kk9dHQZT*lDm{)vZOl|iQCCyo84wNwp=u>93GW(C|BH=#WoYehFD(a zyk$q*4jnz)P{x#(>vT++=qUGCp6NwBeXstC`}_l+=lOg>vB&-V<9r|==p_VUPUnE0 zU7!yE`aQvIAD}{kI|snXL2&N~ms&dS)%QbL_xY;6!%SsR;Xp{y&}pF}zIH55G@jXbH?wIhqj^#w z5Y*Jvh{fWLjt-ej*5BU`w8h|`TCmyxmfFC-((B!t+TIDt;Iw>nu3D*+PAm@&4r(-- zsi~>)=|@_v7Hm#0E-tRFu7b^#l{LdN{f5C{0PkMD+I;r`=zn7O8xtc4qCu#S{*O-} z^Y;u|9y6bHrJ#^qK&4WOu9lP*Q79y$kie;?QL!`}1xLjbaYVd;LL{}31bEz0Le;fG zDzm(|j7q>aN(mGK4jT}tl5=r1WdpCgNFux;Xd+?*1u`}Be(^Y8cYm5Xqn#7oZV-zJ zyagT!yVO3b?#?UL>+2hjVu_hGf85m6O0#t#Zdlb5_NUHTI4%Y8>`y+)|DyK0r=!Av z9`+>qi;l$ z4S&~Fa32-luyCWPW7?uxFRvRq5y+TVkz0ftbM^>dN{fCz4rAp?$xCyNl(0|4tmU7$ znZ9IUZNDq%V%S8zvH6~Tjze;o_4zVHdAZ5kp$|oOMx~_wKBgRGYp>)VYF(I!)Zy=o zl!NIQ({(4=St0TO?C0HKQIn@y`M1-&6L0yBO2%>rUaxcdI4}$=(BA9uGOXAS;~N^A zRT5HwPljNxMc$!y>r6DvQxar)%e@)_n@jM;$IUWUsxb9ohAmAyN0 z7!C8aES+^lJZ-W11bOGsDenGaxGO|Ol_-qNDeqGoJ>EwASnA1+Nn`K-En+y{+}q4E z*a9j^#lS3Fk`%lilC1_qcp;`<=aEBM zJ5#eT2NDB195l?quJw}D_FeltSav%}Xr+m5*u0{M{yCk|P-Hu)_P9h=ags`cb)yNW zUsH$7oJixICe{qjqLHb!ivsFp35af21>`L#$?H7>70xFko_Ab#O7duhA>pXdOAe!L zVo6YLh~-ArJgT|p3zv>ct{EH+=T(RBGPEi$hpkB83#<;?`CE)qHvb62W;{ZNwOwyX zcJFc@lUX9(++2}wQwXRr%6TWR%cxhwt`p!66 zeF6z%+T^|<$?zNv7`w+gn|Q9peE6iY@=X`UN7<}JjAi=BzemBpyrO>I0E2E6cGAM6 zFKl@gd=r!^d(QZj+m<*btYL2(8cuWFqo+>y%y175bZSR^(z*6*`w~;R(>=}$)Y5#u zV~*OLvi-AHJ}oKTG+p$;U`upLpj>Uoq)0PtW|!n6ST$XwS#+oh9*O@(G@$ms-kg#U R*>>0a?W$}#C(H#3_z(F5crE|{ literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/idlelib/Icons/minusnode.gif b/PythonHome/Lib/idlelib/Icons/minusnode.gif new file mode 100644 index 0000000000000000000000000000000000000000..c72e46ff863e4786a3aa39f0d60266f8c9bf2534 GIT binary patch literal 96 zcmZ?wbhEHbJC8HYheQaLXFCSSU0c>Eve3xbnkbkxQ4De$$>C8)+HM+ literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/idlelib/Icons/openfolder.gif b/PythonHome/Lib/idlelib/Icons/openfolder.gif new file mode 100644 index 0000000000000000000000000000000000000000..24aea1bebe8413427326f964ae8b6f9a29641029 GIT binary patch literal 125 zcmZ?wbhEHb6ky7fiA{5+57r9a@@xaKl9H#tW>S8=RaE bzBro0!*Kd>PT20+wB2&-H*#hPF<1it%q=nK literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/idlelib/Icons/plusnode.gif b/PythonHome/Lib/idlelib/Icons/plusnode.gif new file mode 100644 index 0000000000000000000000000000000000000000..13ace90eb3269a14e363ca3646b08c4c3581d026 GIT binary patch literal 79 zcmZ?wbhEHb_4N!434r~kKs$oc;LN)jeQxHW8aYux1CxXGh=i$}{=kJfFTt=qlYcY3w$^6uE})49i|YmaaDKA*1r ze!U0$dk+Tm9}b#$?EnA&4AcgSKUo+V7*ZK@Kn8>2gn@loLuylMVpNcin}d0CPg874 zke7?CMQ=~|L>D^?(`l*k;XW>wMwS*+dy*4lLId0#Y)qG@sw+#TCdG#Ycx^DF73XG84Z3WSs;jS~uBLc{gC*6+%Q;ogKu7b*GghW1 zXS>w*A7!PuIapbB4jMB)Y-|L&sG=)e ?l-l-FlCp7Tv>PXeH&@o_GeB2QzX$=5k Cg6

7%AB${v!0I_e# z8dqGwgSx6A03vtRWcNBgM>ABA#nQNDh7bM)KBOd{vio3js2WkEid4M7I=C^Z!WH{{ z8pRtwlhD{dLxXnIPXA5;XoWHGDQ$W)O#3OZcL1Nmi1vgpr#&SG7#txkk-Q{pmPEA} zy^)Fo?L=78KuVzb4vc@2y$B8Gb+>?k>&qd4ng<(RM@KQ5!9o}bOa85y*{+Phj2xHd z63W}*akA0r?8IP<@DQQt&G4FMXx9=c9Jh)H74s=~vyi`wf!GI(YiTPWs&WfQhmdN; z;35jw%h=+uaB$pyvL*Q0_->TN1ZQV3m={|ubSE)~0BAL%lt{QhLb6I-ptjhl`x=9r zsQ9@xJW8HKTPMGq{C@E@c|^;KsUG#qyc_G$#?tTM8__N*;@q|ljaUk z_a4%g$of4?HeD;KL7U7 z>U`qD0*PFj?MlS3FVOyqIby^A7Lo!qDOgtrEBk)r T-mO*kov$6PJ#la^`U^Nec3!k%H{jMzq-nR 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 ChpC4E literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/bsddb/dbrecio.pyc b/PythonHome/Lib/bsddb/dbrecio.pyc new file mode 100644 index 0000000000000000000000000000000000000000..43e28ba802745526679bb4b7996b8aeb76a82e77 GIT binary patch literal 5121 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 Y2ix`rn%$tsZn93W6ZFC;=(IZFUwp!oH~;_u literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/cProfile.pyc b/PythonHome/Lib/cProfile.pyc new file mode 100644 index 0000000000000000000000000000000000000000..13267b5defdf1e068b8b99c96f8be3265dbb36e7 GIT binary patch literal 6098 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 O8*2}nv(0bLd;bBrA|=NF literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/calendar.pyc b/PythonHome/Lib/calendar.pyc new file mode 100644 index 0000000000000000000000000000000000000000..37fa3745f218e0bbb12c75b99cc8d46d69176199 GIT binary patch literal 27394 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 literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/cgi.pyc b/PythonHome/Lib/cgi.pyc new file mode 100644 index 0000000000000000000000000000000000000000..25db095e652d8d6325c6f850d8ee31bf2505b10d GIT binary patch literal 32214 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 literal 0 HcmV?d00001 diff --git a/PythonHome/Lib/cgitb.pyc b/PythonHome/Lib/cgitb.pyc new file mode 100644 index 0000000000000000000000000000000000000000..1c50904402f6d3977d91075205d2b788c5622e3d GIT binary patch literal 11914 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

+ ''' + +__UNDEF__ = [] # a special sentinel object +def small(text): + if text: + return '' + text + '' + else: + return '' + +def strong(text): + if text: + return '' + text + '' + else: + return '' + +def grey(text): + if text: + return '' + text + '' + 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 = '' + pydoc.html.heading( + '%s' % + strong(pydoc.html.escape(str(etype))), + '#ffffff', '#6622aa', 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.

''' + + indent = '' + small(' ' * 5) + ' ' + frames = [] + records = inspect.getinnerframes(etb, context) + for frame, file, lnum, func, lines, index in records: + if file: + file = os.path.abspath(file) + link = '%s' % (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 = ['%s%s %s' % + (' ', 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 = '=>%s%s' % (num, pydoc.html.preformat(line)) + rows.append('%s' % line) + else: + line = '  %s%s' % (num, pydoc.html.preformat(line)) + rows.append('%s' % 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 = ('%s ' % 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 + ' undefined') + + rows.append('%s' % small(grey(', '.join(dump)))) + frames.append(''' + +%s
''' % '\n'.join(rows)) + + exception = ['

%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
%s%s =\n%s' % (indent, name, value)) + + return head + ''.join(frames) + ''.join(exception) + ''' + + + +''' % 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('

' + doc + '
\n') + else: + self.file.write(doc + '\n') + else: + self.file.write('

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('

%s

\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/PythonHome/Lib/cgitb.pyc b/PythonHome/Lib/cgitb.pyc deleted file mode 100644 index 1c50904402f6d3977d91075205d2b788c5622e3d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 11914 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 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/PythonHome/Lib/chunk.pyc b/PythonHome/Lib/chunk.pyc deleted file mode 100644 index a15f787b90a44d6e8df5dac5e98ab5b3b17e3f13..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5426 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

)$b z-8he!JPWLz!}ly&(~I7_Xi9@cP}Th`Tg*;JI^#~KUnGMJx6&#}?-5=GX?TSLe_agU z 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("\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/PythonHome/Lib/cmd.pyc b/PythonHome/Lib/cmd.pyc deleted file mode 100644 index 34ecf8fee3976252473b4257b92d86a7a1e680b6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 13724 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 I%3SUL062s33;+NC diff --git a/PythonHome/Lib/code.py b/PythonHome/Lib/code.py new file mode 100644 index 0000000000..3b39d1b346 --- /dev/null +++ b/PythonHome/Lib/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="", 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 + "" 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=""): + """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/PythonHome/Lib/code.pyc b/PythonHome/Lib/code.pyc deleted file mode 100644 index 427596e1cf6503e3ddc3633cfa3d44cf4fa5f223..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 10093 zcmbVSO>^AXb$#e=el*#XG}1_#@hCA&kE~`wu_8I;#Yk2%W@g5d*pvctOj)I>4jOnZ zfSB_&mnlB!w6i&SNmjTc@|vPk6*B#W%F%KykBi&R$5Irjl*kfKIoj;WLdp|pe4meYbx&Y^0iVwf3(c1dRdJib)~-B zWpm~KRrRK=9<3_fQ*lo{ZK>jyO0V*5FGJ5-YPWxmz5N3eU)dy0Y@&^yX&vj>x4Ey! z(=@c&e=xHLd3MA2NoI8sMmBk_-T9=@xU;pglKdKfJN*_U+4Cs2^YJ*$V*E^!R2OnD zau);q@|nGYdSA{Z%Bd4*FCKrioo6ObwOz*TstB-_PDt9qXy5E2{XO@;oo|)I(PASZAP6;i^=yEj4OMwVzhiUUHt;&Q5|t_1T>5 zqA>Z$nn@UG%US%?+9DZFt^TYi@3z0*Oh5oSY%k?Eu7VLEjec^b<_A2pN| zW({XskAIR3A4hqtw+b`(i{rAD%kC>Q1btkp@+kuE3}9hwvXoOKr>#MR*v_>jj3(hP4&)* zr=V~p*gOT0y~ZVgCkwFK=h7Mvfab*6Vj9_;O2x_J-yY^7$4K%FqrH*l5hn459~Muh zW1U&wOmvitsJfiAIDvkmW-&weYY|5WNp#>7N|>%R^@kcG(-Ghry9w2!aGF|($o&u| z;3%E>QK7LEaV?`ESyu3=p84y80jF*-Soe*#d>eNnr>?xo)kVEp2A;-w)Tq9bXSy*| zyNao3NDy7A+OSLVPz3DssZN#!MOYdDH#4*VN~)Fy$5|!TG&&sx)SaBtzLCtZTgk9 zv28VKi^18Z!J)8?q?9JpTilX5Q`arf`^%Z z5KbmK`(%#XTN?sir+84WB#ZK*(2>0ZEQ)KWyg`4%FT#XM7tT?uUqo7P@Ar3SnGIiv zZKZDCN86(`Kav|8TNr|Gq=s+dp!6_|p4OPF06&3Y0G|CJpdF?u^`8o34)P=SuBPQi zN5&fdE^eUm_9?>{PhiRQrcCxY$F$XhEcCN!Qb4il9-J~(ZKp+s&ItZ}{KzzxGiVxZ zfB!_=l*N`$oxw_KD5_q!pAQc)=a?m05-|c;i%S2S^FamK0(4jh6VVs5QHz1u$!wWruzHcqW_d2|V0UJ$9)I>Cu}$Ex1K3O*zHliQpA=V+$} zEapWQSTBPn`_l|9JBL6N0&#WY6yyLzG`!Ue(FvOek3wcsk0^%aq)9x$ilZ5rFVp~% z%+|!*BF^0DZ9Z}CL?Dyt7q*rGAT=%6PM_Q$xPZdai629%n70O$EuHDl$O9Z}5dVH0 zk1zsC$&>`78DjA`V`AZ|rDC1nJwB!#bSf`)tnzK{{%kzVQ;{GGjH>Tq8^T{8-HG}> zg_4u058B>`-j&vxx6tafI_)*D_J-_2O*&@hOK%7I)%j{a`&f0fV_(;4<^D>k>_%no z#2I?vUk`O#>5e)C8S&I>u+^WaAH!`5Pla_;1{P0!=DZf1l;F5T_T1v^AL#5jF!Csx z7Qm)po625W2p}A&p)ELpio{IPaE3POsE~=rHsPqlLK4ctpPDd{w9z`ze{Yw zR?@sRH2YIO%RzO*VGic%w#^A?8-L!Ei`ziPo#-66%fw{EvP>> z&q7_{=&*z^3W87@W6T$ilusO?>x9KIqb2}2#1na~MxgN$fNU~8baUJ3tJE-k|*hO~>!JQyq zuEd!Imnnhfe_o%rF!FI|2laFf@+_T+K8(YO*mu`8BG{?JHOdfz%T{Pwr2+Sjc_JN) zr{nQ#P_31y6v>Q%2HtFf-4bQ{C!GBGFOKV*gy2v)D95|B4&yq6-hdRNGSo2)D1^@U1>ThJdN*0_ZlSPhgAwz1E+tD`!QiY`2~J<&FV`*=)k>p^Z``R{4mQAA|7W- zf{Suoa-;1X$qzaEL&b8fxGCk>9J8Z2h(jBmIdxoyUr_|#Q%j{~>)~9McrX~}@iaxe z9*~>5^&_zhzRiO39nc5_TmshtoSeN{Y>D>DoI|m=wAkvMJAb2lrT1Iis}b(VUmN9* zaF{Pp=w?O=S}j>oW}%?8ZS@9E!2od|sVQWtkdbn!DWs!tj*Jv;E;A8DLu>v6#dey* zz|ZP@C6#ih55ngO7(84NuO;v;Qp%_) zL6F0uky|)!1N6h7B0o6C{jc%DZ;)7W*^_x%sScZ6E({ugQPog?$E=77$qY8|y+>15 z<*zD-HE*aSpDv9xlhx|8)&?_6b%XUf(!0a;>u@ZYE9oZbrazrvN#~Tk8AQ8mQ6S1B za2E&5TvMUpCfyP^Efn*`I4oeDGnI{!{so7j(yEmUuu|e2X`6YHTxy`LGiC5MN(%O$g@~@`1aWY5wJRE z3-I)OihUATixtVXfnhAF;v)~7i5%fP^`(bvTpV8DGjs(!1B_xn`!*)zJxRv>5aX0& zoR}i^_Ca<*J!F3`mMjB3+<*2B-nb-h{6*spkb1nq%I`Z}l<}bQLmcSWZlBOI|A6&4 z&32t)t4ee5E~OfVSw<3lJSFUOseC3G3`njOs$}G1s)WJR&F0x1lIGaugvtFSb%vPN zcfx8JCV`EEiF3vQ){+4vN>6qkJ+e5@Z470ufna%{ntj>)1BXpiJwM4J$K* zj#GhGYzf6K9np31GuO=u{`aq&jTO^IJGc;@=Ry*u9?K=qV*Yfu5r zTAy~z(IAe;p-^I)Xi~T+hchfqIDZ`6<{RAEJkw^f?SIE%$WGL1+gp`Qwd!{f5f5qS z`>m^zY-pqGwYo?F)aPZU&6XSz@+)1&-kv=zy{P$*b1ptx>_cNK#xd-LHWT_ z5L9!|2ZF?>GS$TAwSI|M?mm^ZOqpX9q0l$U`X%oN(vnyU^|kn^74zq^RmR#b#B>399y}&)n=l=a9!B32(HG-7CDzbOiDeG!00k za~oQ66m>2fikoDJwUc;LDml?}F-+vaY2WcBFMWiJo~u_0!w|T~(cBzhTW^a=^$5v1 z)OJadaD;tyX;G$>d6Q~R%c*u*^SURJ58#a5@{^H&`Ub?N|9gDM4%AY)V>-8+GS47Q zvQvbePi}~E2$Hq&4L3#6lg3gVvyWnnT+nw9FcQgt!bvT=U@T%WnY4b$E!*F^_^rPTO{cO_?8~vsLg{ zX7aiCOevKrbV6U;d;@JVb=>YmCF@gBOvQBvq;g?V$D zjE1g=5DA6-ceN~?DDwsbkRg62fY#;B@;fM!lz?D#jEm40&Qr~!B-p-`ITj8iK$nzc zaKBksw3?8W9toR*^W(Qr!Ow8_Onsy7T%*3pj>)+ms7w#3+zYUq9Z!0LY*3hF=saqw zzUZG6>$r4jL5_ojEuT=mm3(t0y%-Fza^Q#Tn+vPwqZOs4UeCKHXK&jC>BU`#se2S) b_)Xa20{eOeG^^X{u3h@OE7`>ld*1&66Y|GD diff --git a/PythonHome/Lib/codecs.py b/PythonHome/Lib/codecs.py new file mode 100644 index 0000000000..93c16c358e --- /dev/null +++ b/PythonHome/Lib/codecs.py @@ -0,0 +1,1095 @@ +""" 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 be satisfied from the character buffer? + if chars >= 0: + if len(self.charbuffer) >= chars: + break + elif size >= 0: + if len(self.charbuffer) >= size: + 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/PythonHome/Lib/codecs.pyc b/PythonHome/Lib/codecs.pyc index c39a3321e71c6579844a9db95d8bd9bc494785b4..ea2981c65406b9709f6f79d34ec937e680323da5 100644 GIT binary patch delta 5187 zcmbW*?MstU7zS|X)JX_J&sf&x%ml@@iY1!Zi(!pQY%dDA%}1%l+UDM*o`LBw7iufS zSa)U^1SWwAm3mW%MU=+uixkv{B0oj#W1k`jf?|Kdx&DA3*E#38cFxUcI{zl;FZ5|F z2lMjstWB~%s089(xii+kx3$A=Yj+%z?Qx|quE@uI-nd_OTvh_H=*d{bM^`jI0hK6r zi!1(Kyj}#bmC~?UoKd~hA+C5z%I1qR8rQ7?s(afMpwwme0ku%}6;RXLL*k0HJHDyJ z85J57K&1?y0TnAx0jkJYOPeN%T8tJzJF6v{G-_39nm5`2uc`2fD;}))gfzNm7mJ6{ z&MKhMoT*9xOJrwt8B(+UnjZ0;@sFAhNZ8w2q|+yMXT+CC1{2b0HbsD}T$fwS=K#56 zMp|6GXP^KGdusU&s71F#>-)a|GM$ikweC976i@vc5IEB%QFFr+K>lqw52)w?;0I3H z#*5-vJlR-)eDk?OaUjfm_#ZMqHCg>C4L`8{0!9>mc&ZJ!_msb$NmaX8HWo{s)$5Koxp@cE6xe=Jnn3-Kngv2W=K4Ywsu|u)NM%VT(dyd zI~VfN_PLRLEkdf!lLYp)=6MgOnXZ?B3d_hD=8B({k>a22z9+s)-qN#yT&`Ik@+2-_ zK#u>8|F!tW$QRfIlp`nu>P7GopmMX!SnoU_n?s|3`WQmqis>*`W8`9-h&&eG7q>>A zBY$3$#w!bfwB~_wP4w8sHt8V9zlXhfu>K8q6B zPryUz?v3lnsc1kYRoHs58)Au~=)c>ORZGJl>VQ--c z+c2@aMa;_fqInFIOK=t|_3NFOfEI1ay&B(p0%D6wqG0nS*q2agzZL>B%Gbau>_0@~ z`ifE9k$ie(m6KvHNv%dIta=8nuMU8XR^tK4*E)8fS&U`fL9Nmbj8yCJL-4ZWFV1SF zvrV1C{mxYwI=)|f6io0VpmXS&!D5ff0p7j4G-5aPy8Vvz+tTsx~^VgCilCj~yDwY~=16vX!q z2eCOdp?l(5&TN~*yCBcwt}xzSZ8sLA?MaGB>37d(FioThED^zzZja*kv7vVW*2)uR z?Rx~i)`!iApT%a_&cV-t(_%01KlCduZ4}?ahX-=tqBC8|MqIkeh*N{F0BLGa;+g9T jc}+L>Ks5Ib%^^l^eL(EIZ9|-;(>T+iJ9U8c?e4@s0?|j1 diff --git a/PythonHome/Lib/codeop.pyc b/PythonHome/Lib/codeop.py similarity index 56% rename from PythonHome/Lib/codeop.pyc rename to PythonHome/Lib/codeop.py index 8aecb7d4e23778b5b410c21727b7c9679222a711..5616d92a858ce3427ec80333e3b67f57b042227e 100644 GIT binary patch delta 1861 zcma)7-D(p-6sAS0ECskXf2*31s)?aeTWVi zNhgf({V*M7aUvL=LoSc}Cip!k%3n#EOO%h+d*j|qw)uK@pS{}I+kVeBw>GzS_YrIT zth2se##DnHZo&bkk&VqDm1-ng1J64W5wIa2_wQMstzH69ynQA33B6RF8f*)GivA7oB$dK? z6p0q4DZ=aVu%9Lb>WfpJ_#2a1WQ3I`kGC1u+PCmEcq6ieBPR&`DK-P(P^arUXlxfj z9C*%~Qdk+GRNEaLJa&sv!t_YsHyw0MC*7}E1#529xQunCZW~5Te=I$4p^CFmWCq@j zrQv5=N~KsxbXi(bXfB>>fX=Z)4Dwu`0#yk69D9R$wwZI}s#5hfskm$Zmp@9dXtzuL z{?lW{VQ0g$tx6>+GsKD#QDrbn;4n)ow49=XOpX0++on|_QvsEz0o^VXU!6*aDjsWb zjo-HCE!%0z^TC2Vx9Z9j{Fqka{6t)PIgpUnn*(thWraeehboiy%N8JRCYbFEzX|Pf_U%q}yV!2k zVlS7qCCt3wX}=Yw%mujyxhjfWYuk&w6BVZcxh!{YUHEt@Mt~fQo*x{NlWK|8%ikRNmgW QA-U2=wk}0ru9+6RzXEwFz5oCK delta 2510 zcmb7GTW=dx5T3KU+1QQ~hbE*XEw==aB~U~ILPAs}A_)>u+-Th@#4Q{g?O*v{?= ziX~esa2}9&qe8s!9}o(CHzI=iEbU-iT&qz z?zfFE%Qfo%M(|w5ihly}i7KFqe2eOeDvEZ90!6zPt$zM2Rcs0zeh+NwS@eZP``4*5 zLcUGDL;eWu*i>=Jcd0T;{wN*cxD5FjVY1|BY1z+_KSoCuRlvYzg8V#h_lPztV|<2R zAbLMouE`yb&ZjRbB)FHmKV-bvdHeqk0F-4BS**S`SCIws7 zQ1n@QuCI&YBv;Q2vI7Qxz`(s|;Lv0pI~j^b6==DWrF^uc41#wFnP6s= znTHm!+)jAoTdN;lxyU&$#YiFLLJ%^{F2D@f`MO#crd5sO7`dlhuE=ROOyX8OG%07I zuqBG6W+O0MoN~Kis)uV))Qn^!3R+Q-H%tN?oD@DXE+5o9h-!gh`8LqdsO|-+yuG*8 zOdY6)IM;?k5T)ngc_Z~Pik5__HT^)mVdlmuw^W1`35gkUi^+rA;no9IYPJ?zZ8HI( z-mA8^1cnU9RY>ADLCBg>c{QUlR$gVT2{mEacq=Fe&$)r8s~q*Bs

PN6x47Xy@> z00qfSdJbBGlUyotN(J<20KVDGK(O9k`B1OkDc#i{eY$>oQ?IVAu9fZ<`CKp0WSj}R zeKE8Pk#Rz~wfN)!yi|}rQ8AbNX4q&Qm|JP0!^TcMxYT<%eHy^2^MZ#*&FS}#e;I1C!B@l#xv4%#hSUl*Cz@Tp}y26}8URf@V zpFs7|$CFQz8e8+?Os`ImS`Ip23hz1I+;Yyc!R}-+_HNGzkqPK&pIf#N-TCLX95~bmc^idLtsK~B* z*O?6BO~4|Zvn8nQpLcm?66r9(p{`Zyb*)h+igO^OuBmY~sb*C=QBo!DeXR{EXua3; z5Abo&a+lVAv!=E8Jhr?Akh5EbOPhPJ1H4Vn1#(8QRKRgn);g8H87U}EB!bg z;fp8eVr&R5j=yt@Y6!geQ-|XAw85W8i>)z)JgKpn2c(=CC0M zW0bLTE3C 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, _ = 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)) + + 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) + + __dict__ = _property(_asdict) + + def __getstate__(self): + 'Exclude the OrderedDict from pickling' + pass + +{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) + typename = str(typename) + 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 type(name) != str: + raise TypeError('Type names and field names must be strings') + 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 environments 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/PythonHome/Lib/collections.pyc b/PythonHome/Lib/collections.pyc index 54d3ae98b552a6a01368061d0051c7b6bf1f79be..c947e2e5e010908d4f6230e319d5b39bd8ac0266 100644 GIT binary patch delta 3073 zcmaF7pYilr#tjDSh7Jr245?Nz>6s-NrAaa2`4xIz!Tx?h0nRc0r6mQWB{43kNu}vA z0hJ{g`FS4sxv7&Kr6e|ovr99Qu61)GhXNVeCO2|OO+LkWigXJ>Zk@cF>pU4c8#zQK zujPJ4mQLZxJ9(PO(kU`Ij&}l?ItBR_ld1DM-$XKWg2J|+e+d~nL17yvu!nS=n-vA; zlb3*mCqEK8M!JQ-q$jfZwD1ISEWH>dvAIb!k{qp|EXE}6Nsd-f*yc%0BFn47lkfYo zZdRA%CdXn&DJw>{%{5X%5T5)&x|A$ei%jm2Sw@CVQ2Gs(T||aXP#8g}*$EER!YloF`}MYLa39Lfta3{v@*WDsEn-C&xsd*2zB%wvwlF z^Iby?ax4X=smn-kfM8PNqNC$fu7-r&r(`9235PRYpz zT&J*Tl%DLyeFlrT$mDRIS6IY_C%5u8VG$RZ?87$!tGFWnVyxnv0u!-_OH6(&ump=Z z(1TJelP?JFz$Ul(tWY;Lj|)$pBXSIz29RN!SBv&wYBEfe*xVo!oukhrRrhJpl3`4=Hl5nZm>|i9vgiCVr z29vGWf#Wt0ou5C~Ve?sK%yNdh*vu9faClK(+pxtD;IU)dCBe&BigaF(p72 zO2*B?=FZLE<1{cefQqb?ggF=*3=^|4#1h$op_~|i#gODWY>Fp8NMzltk-~^A9Z5_s HN{a*lFxZ5m diff --git a/PythonHome/Lib/colorsys.py b/PythonHome/Lib/colorsys.py new file mode 100644 index 0000000000..a6c0cf6a46 --- /dev/null +++ b/PythonHome/Lib/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/PythonHome/Lib/colorsys.pyc b/PythonHome/Lib/colorsys.pyc deleted file mode 100644 index 72e9df8edf3c5af6a6ba466c703673f8b5f5b434..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3871 zcmb_fO>87b6|V7&$DUr>@j7GAB>bojK^hZhv-TCZODZo8+_Um4G{Xz}+UT&1o;7L+@o+@f+z%AHhh zS@~sk70M~)POHVMu%TB$4=$F`!Sj^*0j9%$MmlBX&PoTqbJCes?mg0}D0f~un0#6~ zrxUkCR6FRc=pH;^q6ZussnU3)?w0k~V4#C=G)`i(({W<@k*AX=7;$UE zExk1uI`9ZWjg#oe34KpLb*6cy*=#=CJo9a7$yi!1tiKaevp zRNB$;An^OiU{4R6$VX&k!R4m4VKy?vZV(GuZ`TaqQ{*E!bUzZ5c1j zMk}x|2RlIP0WTm4*bv=#LL$Dh4!jmA7kE;CE89hjvU6sT5n%Y z?T5-0ec8b#ti(c2rHJkYPsu*CRWLyMn+K!NQmRYj5Q7gV)|O52~n^FS(2ER$lXqx5L0AE3OZ%$(`eQc35) z6Vpp-e^PA~Q9?ZKrvD}Rz1i~LdA9oU`FH-_@|Ul@@cMrmzip+af3*CY7k~ZvAHMfS z%l{r-p8ZSa{D+qR%hA`Yw_bd^<-heJdvCTHSXDK6kfZ<+iS$KwMed0VL_Tf2IVC;~ z(Y$sc=w6dLMVU57dp1p9pn00T!u|4hd#wHlBf`OONt_U`G)~mw*wEHpoIQ;ZwZ|h@ zJCOJwc-z?Z6-E(J4za96l*)l9OQHmM8PDfLIVnn@GOe~tD*72ahtrMnhA8vtM){g3 zv*}0Bso+GLe(~|&|77{e_gjAZX8*JA{ufw$wAKC1{0(67^Y^~|XM69TE&s-!{(AZ5 zEB|i!yFY&SrRQGyUzTM`<#~4qip_OxLT{g|^Y4R$fk@nVE$ZGTD>`?$s?)gp>@33D;R3HHmT90|f^ikQlI zA;S0TzRNpTt$_ zS)i6L4MP1D8VnKEs;sevG<9kwgTR4?9Z~WCjEu;XlNAw23(2}g2+ zIViVbkrTQ)Yan10I=cyL?1{~0Ypjcb3FFd%&>)Vw4P3vN6&X_>G>96i*4p$$^1{B#FmjCZbNrnn{!qbC z&*muH9(-RGnLG}8PQIPyWEP3`#*>%UB`%k)JdwtQySDG6s6$BF_Q&3d!B~Q`ixxAQ zs$d};RkRXX-DDLLKM%*hF!)rI11dU7HET>n5{J1h$p@ehJpLaH@{7AM$nS*Ujxz|} ze4If_V35h2LBMC}g-$NdAj!!;r;@u8hdqON_AJDmD8pvX+4n#o36$EE{IwUTs4YbDNnK};iI6+3n9~xR)8|Kaw&klm$(`TWl~t_r}PDxA7%x(oOJao@;GgI zy72n|hS#YwlZ402Hv$ZQ6N6033>BI2Vfq40$_$nmW((#8>5YLRXbWPuVV;-atyaLK z2+&kO_yRIiz{(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 " 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/PythonHome/Lib/commands.pyc b/PythonHome/Lib/commands.pyc deleted file mode 100644 index f8bc8ba7f050dd9c34a1b417bae8d94ef65d9c96..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2379 zcmah~+iu%N5S^ub6Ky5w1#sGzF4U%?&{#;~J`}kaEn+_uD1=r*VZd=<)8yKsMUg6Z z=}Tijxu4WO>j$)FhLq|S1}uZi;q1)r%$YOe#$PS}&)vgeMD=e0@9**01WQb`hgDJR zQL1R-(Vj=jcoa7%UZ8l9Zj@5*@V!LwGQ}%&(x5%;HR%ty!on9}k>XVmV74X#j9VhC zQ2c;~!9%`s!z0?cFj47@wj-0KI?5-LFpI4|OG2I7-ZY<@Ea+ds;e7Wkm3eTSq^7I&mvvgU&PV6Rx}93Rk;a-$+P?pTc14(^Np_+$ zbB?#siG|xFKQk~Y@`-jMGxN8ufF)qr$)a#-%QSSxiosE6lSl*5B6LZf%~6^rQ-hS| zXm>v7j{Zgi2CSV|`dYu(`uch2sqPe=889_^?Aj|#7zeWr>nzR^eU#?bV8hq%`nfYN zwN9Kq&r4)>WOSCGU@q5Tj2y}=;*bz$t`jcj6vdXH8UMQEz4w0dH-3Qvciak=^RURK zmz!hzD{FwkoIaC0E>ojNp~YP$o1>Lv`sYhG$}_#$d-h6~7BRrjmPgYfkBqgt_DnMC zkeBnBr!I`fsW~%g0>YAG?t(72>+YJBu42LLtFnkVUUuYGdyB_zVyT;q=vvX0qEqx- zgB&_*fo>Y49GYs8+yY$@dXCod41*G2I!3MJ|VycjLA4Ax#JyE?~R09Ts279pEWE>VJ zfk4JS9NK{O0iJ5HA3^Hv|CAi<&qJGD4%qq$9*KjzHT8)S5NALNh!0@ksKy6qem0b= z>>KF+i%(!(45)No0Fu}gMVBEnGI+SFnCTT@JcD`(Un3+NaO@S`I4RiO8#>!P!(-W% zJPDg~X1#>{JA^xHk3z4b`0G4mJ-YVj%A-?{ZorU+$PJOf2#i^e#w%0|c@AGMPzD&l z7e!xSD33iVruDamD{sQ7LB}2_#BF20#Zp5AY;KR!dywJw>q}}MwB@5_)4?%j1^){n z%c5WLhC#@!kU=K7aEIrGsANEhs-I^@JO(u`Lsn z>GQc-<3DPuN7Pag@AFyneq^q3O+b2}?Gdu6z&{1@fKPEnqyyQtUrizQmPiK-L=|r6 zMk1W%Nfz)G@-^aw8I=pMzb}5r-8UJ(K=bTCvV0LCe&G@y%FkOo_7Dr=Mu_8ODjqW} zghiMaLrfD)mW$`C*?!-x2?c_Um#En0oItd7m@q#iU;g;*3GMRMl59a52FtjlFGcN0 z<#qjPOJMt7wGU-;Uovc0$#H~(bu6N^vPSpiEja!Hr>bsJvnAESyQLl|U-bhXvX0|9 zIEeG;;6SFy0N*ohn5NK5Wh4YH*WfWPT%&&j5b5sWBeU*x^ 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/PythonHome/Lib/compileall.pyc b/PythonHome/Lib/compileall.pyc deleted file mode 100644 index 128f347593b88d42fec40f55d077d8797e6c12a5..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6986 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 J!0ZJZ3jnU4RILC2 delta 505 zcmYk1O-{ow5QWE1o1{rA6@;f^7Hu3=kfU9y#+hxdk}ohA7(imql^0uF8z$c01{LJjDjSP5a0w}C@=@O z1FQqA3-6Q=OSm9AP;?>bLg7N_HJg5FjAJ4j5BCLG#0PCOZ?@vdQw5h?_x&|BwSw0END9&j0`b diff --git a/PythonHome/Lib/compiler/ast.py b/PythonHome/Lib/compiler/ast.py new file mode 100644 index 0000000000..4c3fc161d3 --- /dev/null +++ b/PythonHome/Lib/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/PythonHome/Lib/compiler/ast.pyc b/PythonHome/Lib/compiler/ast.pyc deleted file mode 100644 index b7b05c104232696bc77de0b09cb6f93e529d0d14..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 66290 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 E1N;v)9{>OV diff --git a/PythonHome/Lib/compiler/consts.py b/PythonHome/Lib/compiler/consts.py new file mode 100644 index 0000000000..c60b1d0b4f --- /dev/null +++ b/PythonHome/Lib/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/PythonHome/Lib/compiler/consts.pyc b/PythonHome/Lib/compiler/consts.pyc deleted file mode 100644 index 4e2ce9ae2ddc3652a3384421704d6a654d29bcb7..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 722 zcmZ9J$!^;)5Qcy6OKitUdg!sI!lyhzQB;u`mk3P?Bpo$G02K{$5ReTOdnnLDAF6NG z7wC|78aNX8Y384W9IEqoI{s6BH8bAf$zd~;d^jB z_&!`8egHRsAHoe&&M4)KQ}h6S1UG>n!%g82;AZd>xI_3U+#G%ecLaY3cMLy=JAprf zSsc>=!ib=XDl>+!SAf>{=ZyI4_(t2&;$Zbx(?x)HsIend>I=MnEBXc5S)WB-jb(1Bzl{>r~2;pI~fm6XilGgrYrw&|LA|*-F}S! Spm|T|x9DvrMr+^RD#U+1L5S1< diff --git a/PythonHome/Lib/compiler/future.py b/PythonHome/Lib/compiler/future.py new file mode 100644 index 0000000000..fd5e5dfb37 --- /dev/null +++ b/PythonHome/Lib/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/PythonHome/Lib/compiler/future.pyc b/PythonHome/Lib/compiler/future.pyc deleted file mode 100644 index 096d74185b49cc1ba24ad21f093e730cf30dfcd3..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2806 zcma)8?QYye6uq{SO}yEprGb=!M9oL5tq?`6Pz9(UXiMo28dbADB37x4vz~38?Alw; zY??^vAHoChFuVpocorT2&bi)ADixw^;_I35jPJc?&bj00@74AnTfg)MGW#vy{v9s& z7fdeFhYchTWfaIblzu4VNcxckc_hE#@q*;|UzL23-D8oT`-_sdBwv$!>0}7~Wu3kx zc3JXR_Cl%u)HkW&y^Q3Yg!hAD!1vV@Ob;kop68*Q4TN~ zYzHJbAG$_}|I}Tx>YQ_b3ZW~@657<%HdR3` zfy-H87}`t=#5G4rmX%L(J1k0@tNywKz>v}nWYAN?z1cEn$RN+8dxxdZ4t}U>u#X(x z&qhT)6VPk0Dx%Dt+Vt#YPGySLIfQB6!L+Nm+$AmuI>81&y%U zLWO@IJST)Boo2;pR5+hh!(^UQV#{o2gp#y#_(oN7S~r`lnZ=$xbjmO#&3Q>ee4bh8 zumRtFihe`Uuj~>aYZcZwHIG6M^O6U*tX-E&u=k diff --git a/PythonHome/Lib/compiler/misc.py b/PythonHome/Lib/compiler/misc.py new file mode 100644 index 0000000000..588c7fbd5a --- /dev/null +++ b/PythonHome/Lib/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/PythonHome/Lib/compiler/misc.pyc b/PythonHome/Lib/compiler/misc.pyc deleted file mode 100644 index 94c2cfa64cbe2129cde70d50f8b522158306dc52..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3448 zcmb_eU2hvj6uq-{+&DCpCT-I2RRfAJLWHNjwWu^i2nZHhKLnzp!Szm(jqSCwGiej4 z6%Xl8;+0>(&*2BaIoDaQ)zFYcO*FGJv*Y`5&b@bURy zG5q(Kc12zoIeH+^MZWpUoPLB-sTR3Pp zDZkaE^e~4h^=alqC+oT}!?VLt--T;f?ese#xGdDL?uj4%` z>_sQPgw@*P&GgCR?r<qqt=7w2}ZWy;ob(2l>$gbd%H%YU*cES3b1Dju z6Btx#!c8nDCSY+NoS$XkDrQhcCrK8jw9~I*lmMvrWT4cn`ZPTl^*wj&H4rXA0m*WG zH$X!9TT>M_Uxk07o#8R2AJ{*5W7soTayJ-0b$6z;6Z*n` z^}T@uBmjU%0fPY`VIMWE$OnU?A{HvR8q+IH2rW{FqofmDlM&%xI2DcWH&L z&a04giUK_))J#2^{?{7a4xMhVi?{kmFCSs}dzh|JCs7O;*=Nhq`#9Y#is3jYKnNCA zD{;XD@m90&73uc0PK}16OXi2-*nlKYCJ6pndx-7p%41BTVg}b`6%*=DFkYJyq_6Z| z3$vL@3=KCbjv10=^j)Gr(&f>i-&@7AFrz3-6u-`M+Br4@AHS8hDr%+w;BV~l6?|8& z!f^EIlwRs9#w&V}eb7t8T2m_3e^xh*fiz3pQ5o###Cf1Y*6zBH1~;(wGi*qYw3i7RgFdl^%Mvlr0&$lV!X- z*p#iUY(c8%DSC5~|1QQD>iQXIB@t!K)VS#NJKn3pRJ*5uW~8L=yf9%g9(1zZzFVWA zA7c`9oa(pjZ+0}H^kYm^eS%OCiy5Tsu-cZB9U2`qZZk@dZ_pR^#rE4VSUWeg;Q>5rcc z^IkvoK~JgbV(@B1>VhqFD_BetiR!4rH!xbIq$b(W9)A4oWm?4_apIl$OH5Ojv6J(t aoyGh6<1gt~BubOBUSGVmIA4qExBmq%d?)_^ diff --git a/PythonHome/Lib/compiler/pyassem.py b/PythonHome/Lib/compiler/pyassem.py new file mode 100644 index 0000000000..f52f7d079f --- /dev/null +++ b/PythonHome/Lib/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()) + # preceding 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 "" % (self.label, self.bid) + else: + return "" % (self.bid) + + def __str__(self): + insts = map(str, self.insts) + return "" % (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/PythonHome/Lib/compiler/pyassem.pyc b/PythonHome/Lib/compiler/pyassem.pyc deleted file mode 100644 index 0d32efb0ded9d1d854c0d88a5d26a9b0370169ca..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 24734 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 diff --git a/PythonHome/Lib/compiler/symbols.py b/PythonHome/Lib/compiler/symbols.py new file mode 100644 index 0000000000..afeec50153 --- /dev/null +++ b/PythonHome/Lib/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/PythonHome/Lib/compiler/symbols.pyc b/PythonHome/Lib/compiler/symbols.pyc deleted file mode 100644 index 7326d1cff55d85199a283c495dee6bdbeee89ee2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 16837 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 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 parser +import symbol +import token + +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 kind in nodes: + 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.st2tuple(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 decorated(self, nodelist): + assert nodelist[0][0] == symbol.decorators + if nodelist[1][0] == symbol.funcdef: + n = [nodelist[0]] + list(nodelist[1][1:]) + return self.funcdef(n) + elif nodelist[1][0] == symbol.classdef: + decorators = self.decorators(nodelist[0][1:]) + cls = self.classdef(nodelist[1][1:]) + cls.decorators = decorators + return cls + raise WalkerError() + + 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_comp(self, nodelist): + # test ( comp_for | (',' test)* [','] ) + assert nodelist[0][0] == symbol.test + if len(nodelist) == 2 and nodelist[1][0] == symbol.comp_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_dictorsetmaker(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 [(',' | 'as') 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' with_item (',' with_item)* ':' suite + body = self.com_node(nodelist[-1]) + for i in range(len(nodelist) - 3, 0, -2): + ret = self.com_with_item(nodelist[i], body, nodelist[0][2]) + if i == 1: + return ret + body = ret + + def com_with_item(self, nodelist, body, lineno): + # with_item: test ['as' expr] + if len(nodelist) == 4: + var = self.com_assign(nodelist[3], OP_ASSIGN) + else: + var = None + expr = self.com_node(nodelist[1]) + return With(expr, var, body, lineno=lineno) + + 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_comp): + 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) + + 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): + return self.com_comprehension(expr, None, node, 'list') + + def com_comprehension(self, expr1, expr2, node, type): + # 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 + # XXX(avassalotti) Set and dict comprehensions should have generator + # semantics. In other words, they shouldn't leak + # variables outside of the comprehension's scope. + + lineno = node[1][2] + fors = [] + while node: + t = node[1][1] + if t == 'for': + assignNode = self.com_assign(node[2], OP_ASSIGN) + compNode = self.com_node(node[4]) + newfor = ListCompFor(assignNode, compNode, []) + newfor.lineno = node[1][2] + fors.append(newfor) + if len(node) == 5: + node = None + elif type == 'list': + node = self.com_list_iter(node[5]) + else: + node = self.com_comp_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 + elif type == 'list': + node = self.com_list_iter(node[3]) + else: + node = self.com_comp_iter(node[3]) + else: + raise SyntaxError, \ + ("unexpected comprehension element: %s %d" + % (node, lineno)) + if type == 'list': + return ListComp(expr1, fors, lineno=lineno) + elif type == 'set': + return SetComp(expr1, fors, lineno=lineno) + elif type == 'dict': + return DictComp(expr1, expr2, fors, lineno=lineno) + else: + raise ValueError("unexpected comprehension type: " + repr(type)) + + def com_list_iter(self, node): + assert node[0] == symbol.list_iter + return node[1] + + def com_comp_iter(self, node): + assert node[0] == symbol.comp_iter + return node[1] + + def com_generator_expression(self, expr, node): + # comp_iter: comp_for | comp_if + # comp_for: 'for' exprlist 'in' test [comp_iter] + # comp_if: 'if' test [comp_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_comp_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_comp_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_dictorsetmaker(self, nodelist): + # dictorsetmaker: ( (test ':' test (comp_for | (',' test ':' test)* [','])) | + # (test (comp_for | (',' test)* [','])) ) + assert nodelist[0] == symbol.dictorsetmaker + nodelist = nodelist[1:] + if len(nodelist) == 1 or nodelist[1][0] == token.COMMA: + # set literal + items = [] + for i in range(0, len(nodelist), 2): + items.append(self.com_node(nodelist[i])) + return Set(items, lineno=items[0].lineno) + elif nodelist[1][0] == symbol.comp_for: + # set comprehension + expr = self.com_node(nodelist[0]) + return self.com_comprehension(expr, None, nodelist[1], 'set') + elif len(nodelist) > 3 and nodelist[3][0] == symbol.comp_for: + # dict comprehension + assert nodelist[1][0] == token.COLON + key = self.com_node(nodelist[0]) + value = self.com_node(nodelist[2]) + return self.com_comprehension(key, value, nodelist[3], 'dict') + else: + # dict literal + items = [] + for i in range(0, 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 + star_node = dstar_node = None + len_nodelist = len(nodelist) + i = 1 + while i < len_nodelist: + node = nodelist[i] + + if node[0]==token.STAR: + if star_node is not None: + raise SyntaxError, 'already have the varargs indentifier' + star_node = self.com_node(nodelist[i+1]) + i = i + 3 + continue + elif node[0]==token.DOUBLESTAR: + if dstar_node is not None: + raise SyntaxError, 'already have the kwargs indentifier' + dstar_node = self.com_node(nodelist[i+1]) + i = i + 3 + continue + + # positional or named parameters + kw, result = self.com_argument(node, kw, star_node) + + if len_nodelist != 2 and isinstance(result, GenExpr) \ + and len(node) == 3 and node[2][0] == symbol.comp_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) + i = i + 2 + + return CallFunc(primaryNode, args, star_node, dstar_node, + lineno=extractLineNo(nodelist)) + + def com_argument(self, nodelist, kw, star_node): + if len(nodelist) == 3 and nodelist[2][0] == symbol.comp_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" + if star_node: + raise SyntaxError, "only named arguments may follow *expression" + 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/PythonHome/Lib/compiler/transformer.pyc b/PythonHome/Lib/compiler/transformer.pyc deleted file mode 100644 index 83c70307ff5360273b0b8719d417758590754edf..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 45754 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 O?ewF32O>%M75)!Zwv#vj diff --git a/PythonHome/Lib/compiler/visitor.py b/PythonHome/Lib/compiler/visitor.py new file mode 100644 index 0000000000..f10f56011a --- /dev/null +++ b/PythonHome/Lib/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/PythonHome/Lib/compiler/visitor.pyc b/PythonHome/Lib/compiler/visitor.pyc deleted file mode 100644 index 16f36584a6b17fcd1070fe91876f47cbe76b8cf1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4037 zcma)9U2_|^6$MC&5*52v;>sVLv_YG+qFb3`Coi4Y)2So7bUGcyv+~5Q>dbbv3z};! zcj*OaSu@s?^VUvZ`qqEY_x_vyjK1WpJ?COcT2020On?9gT-=X?bFbU~Ilum|M}OW+ zRrA-z_ixeMpU`FaXjLdR(Q02SowZcfQ(0Smt<-C!{xEE7x((>ke~k-e|?RS=e>#Zp38Uk9)6j-+*kENE$;aY&HWmkg%n(f z9`{4Dwt`|5jVndB{T1rP72GO%;nrxc-=&22I!ZmT^{A>R&Lk$YQ$M~w%4_G%QBoY5 zYGnM_8Yr>8Zt(XoOd5^MQC<{bW3y}9OoOz%d}?ft)f!@_wXNz5!>Sf3)5^gfF8Dfm zVQZHZyxNu-k5#2P8t3WQOspSQnaQ0=lcKQMAm|X5-KRlRBf9TvYq!md;HqnhfWSR`kADDI-A(i z^9qrY%sp5p6PuYW*+|nK9#8ESoNQ}r=5xB4LFC>h>>`9WZXp6i;@q~egQo+t!!fk_ zJbR!<{CGFeTeJl#xz3dE#N1qeV)#Wq!tGl z5B-6O(xg@C>#8v0>L~baoEMqw0h(c)NQ3Fwtfs%;KqAo%6Z)USl}WjUK8O-AR5svq zd2j()p4>JEHce&@L3_hm6DK2Y>v$nUp3oQ;S7|y!M6yP?$uw~a_}V~k+~I67 z>f>8U=dNNjc=Ct*;7M9drg>rOCk+w?(__DeU*kA0b05b)!`M-R(mkD0H%{1wXzo|& zUVfxrY4uEK`R-Sj)JdDFKGW(I1}*hhkoWWR>QS~-oMQZWbWg3{p?ml$oZOq`ZkqUX z+~*b13cH1w2$Az#5|^IYoK>92>?oNP{udZF)?5tM&{+#>W|+VfI$8#>p)sbVp1~N9 zJ*;f0la6`?zE|pSP1R$rKU+~JD+;cs<;XG+vZ5|?vZh|Qn**G-xchbq@sNRC;-9@f zJ+dpdNgVn;%!A<^#j)@~97j}D@)bN6i5o+(NF#CVX)1n6ysu^41T}gG>ym+%9*rni zZagHv2z&@;&vm(O7c$T4426N z;Y}aGE%>wrIq+ogj$`cZR?FnJNSGw^nIqve=7yIMy^8~)S9A`eC7{Gqrhu@6_MX*D zf#^KF-oimg{HRtBruONA=mI(^B;puUGb`p%iQ}wFn+Sb*FZ%3@y?YVQN@#+XeD6y| zWc2oj8j%Jl#L>X+m2Rus>UHq%T~FKZy-X(4!oIDd`7yS=S<&PuTL5z1R5U1Ch%xtX zbPqu3NF+801;>VLM8+YRCY~99%q~H&**rOeBb%^X&+42R7%Np-9Fr(VvqCa-W?$H% znlhbkGf|>M@LNvEacqkzw}DZcU8dn>g#o8wE zBIvl98RuC+jZp-Nyejao&>Ei(Au8}3!m~>v5J>Xng5?$z06LHTp%npXkLDgWLD{%POQ|GQ9ut4l#>^ueG}S)hFr%JcjDE zrLJaOb%;y9VF5iv?TqD1L(&`+=#mPD_n&{G@OdQqLFhY6<@UgkdqQQq@&th{)ZGNF z0N!)zIgK6rp5qJp`SqJ04{m=&s(tcMt8n z)_P5^V0}aXRCjb=vKomZy3FnhJHABm%JP00eUB19!m&GO!b9C|S9e<}Eny?s?(jE4 z8gM~02+%9^`D>+4S}H(_>pfN95MT)jb3J4{c?Jlx=DdSwGElq00!csgY)mS)b;KY< zWHE_JAl%LQRLYXDF{CD2A5`wl2}a^0$01PoPKmqe@(nG;6ZN6pV)FwGh;ck=1+shXy2nfVE|S-yYjg4$UT07Dp3aN5m;Wi9p&7Vz?w5=XG4fJ(3tAVk0u_ m=$Yt4b|0ZzDj=gXXmLBFvfnWHZXMmm%EeokKJ4lXYySfb)pxc4 diff --git a/PythonHome/Lib/contextlib.py b/PythonHome/Lib/contextlib.py new file mode 100644 index 0000000000..f05205b01c --- /dev/null +++ b/PythonHome/Lib/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(): + + try: + yield + finally: + + + This makes this: + + with some_generator() as : + + + equivalent to this: + + + try: + = + + finally: + + + """ + @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(.open()) as f: + + + is equivalent to this: + + f = .open() + try: + + 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/PythonHome/Lib/contextlib.pyc b/PythonHome/Lib/contextlib.pyc deleted file mode 100644 index 61b31a5fcfe9f683df6e62860ad74a2891b091ef..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4394 zcmbtX-EJgD6+S&Z9(%lA>`lVLDv2n82xCM{$PY*>#|m*)As1Myc3?KvqM>KH#%{Z( zd$y})?LqdM-6m)kv=JRyGHL36)Dmx%134md zWL|dh9)kt3^U}wrrhFpuvB*a|3z95yveOjXl;noK0P#g0o9tdX-F<_+w_7)Pr8m+2 z%%@rEQ|nB>D9vH&_g-~A_I6-%Z+b=U?U8qD#%x<_?%%s_-gxtkwe)j5Tde@c{T#Z( zG9J2WTIVz_bN>|#CdUVH9`D-HH?Wjj=WXKW`8F$Dn(z9rVf?<$Z5jKb+^jhMv^sK% zB3ZqQ=2p>J$O;6|*N7iQ4=EJ~b;8NPoJ8BLI*)uC-A`;bw55vp&g`vBVta+MUhCDc zbJ{j}lqeksaxBtOIarkP zH3@>i0|~qe`Vug zYs-BV{UseZ!0f(t)f*G{0hRH4WpUVAO=%J>BBrX^DsroeiwJA9$nFMT5rC7sj|aBX@sy|285GGVv3=tTAaQCkt@XIv9Wge$jn%uS8@YMi zSw9+X%&hrxJiCb-)#c5)>Uws2Kh5JTd&-gZUS{K*)GImmQfCJ70g{Ht@SG&fA76H5 z6FYJ))3}@2joG`ccZ*~^;b0$)Qe2QZ$QKuxT$J>ZlxG~w+fNmA!is3{d8*tOWbVNb zG&#_bX%+5ybd_l!B*PH?s77%Lkk{f(j3+s8RJ-A8N+8hyJSlS-Su>`bCKYm<{ zN>lXV5$D)W*s;19&_5^dD_@+}a#J?eAZ3_1c^u~+QK;H{o_FzBv&|LsC&bBSmc9WE zzZZKm4Nzv350O70xA6nPZ7 z;x~lVgriC}us^y6z@rt#rkfSLgUa;HW|3Hvr3dz6K2bxOe2ui$t7>Cot$+$<((Njf zSN~$pB7;fNf(LwQ-s&?OT}fUuD?GzoPG>5`S*m_&y6Uef7E?37=C@2$F49eC%UT&m zuV8d7TUo$?KT*r1aqbI-+TY|ltrz(KpD#06QW= 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* + separators = "(" | ")" | "<" | ">" | "@" + | "," | ";" | ":" | "\" | <"> + | "/" | "[" | "]" | "?" | "=" + | "{" | "}" | SP | HT + + quoted-string = ( <"> *(qdtext | quoted-pair ) <"> ) + qdtext = > + 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 "" % (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/PythonHome/Lib/cookielib.pyc b/PythonHome/Lib/cookielib.pyc index 80d09bb80b1e3adbcdb6d3f3159be676675243ec..f5c6f10e3e23bf143bb8ec498eb6db8bbf5fd4c3 100644 GIT binary patch delta 5615 zcmbW5>q}H&5XL>N7OPe!bymAbL1_?3`9U$$A`LY+*W9RVH}KN7rmHJ?)+-^AWfq$4 z2$@1^Mi--So9>FSwW~!JOY>7D1O-u0b|FH#z3YE)o20r$RtLpP!CVwngnXdRtK+HQuQLGcXCmy7kZ1&T$H`m}dL9WlY`#&_vTeRr z1BTqL`v#m5`LcB_Yx4(GT^^ZABi{g|PqZvb2~v;p_n1+{p_j1}fS5b(Vt{&#x-Bv_ zCt4*9{Y)HJ&x?CQlSz@1KkL^2Ly{dyl_?>4O1(0rq^y$y_+Ux~P{RCb(|Z7;k<<;6 zhC|Zg5m;EwrRk9fI+7Z}?#;0vO3U^A>J8@4`eH<|Ff&G!Lq}#XP!4=^>oq`=D~!O0IGVgRXxRD_L`8sms5O4y%;UCodqaEyG$Q! zmjSZY98Ucu9RO)5^#YVHQiFY1J;^J|2q;P(-rs}VyJ|%*THKIQfWV!mg_KgwwMj!#asM;jySXW&&6Hxb!r`PM|0%nWABY5)QJ_IeSkCptX zv;Ged@s`G=^!RYp^nuNmoDHeKH~L&M*&5=-`+mLwXxY=#TuoCTwH&>wUY)lz<{;;M ztnLphK zM0CYI$qR2m|6zRl*`?cdK$WBJjsX~H2hzpXVjPGCDw*5v^#hum@4kf`$x2U+`p1D> z9%LG?^S%SL_79Dzr+C}&JitX#9-aoo7C*{BysvmX2#6&=L3TZEf4T#R(fJ%{RP?+Y M&=OT8)2cDoe?YnBlK=n! delta 2376 zcmZveYfQ~?7{~i}PDl+kvf{->!~=RB{wGQ)G& z7&kY!In$S0w{A*ZpB*}l>`s;QJ?j)OBzswv0qpQfN0Xt=ms1RV?%?AHQMr8hBrx!g z5set8cT|Ehh{Jq5buI%H`hCT6wG7Qc<$CZiC#zIx?2$P;LW;ZqrcG_foJy%m`C(5$ zygj_eLxyEBDy5s(4R+V2DSo#3bShG%KJyJ(sSTJu%?eg@>|^-@SvfLtI8MfrtJ2B2 z!T-bWqX5fjem~cUT2VG9Mm^Sm{yDc}y zzv41bTpk}PI(-&D1Uns+cn$TITz}RlW#~ke88dI}dcCGZ&c>B%U!quBfX38XSxjP; z>0+8g=GtmirL&Al+ldny@iOPJnal7tI676jyP;YZ6K%wCPQIs7Ud{#3im_0(%?>X7Ddvt;@@%%Qc45Kf4{N6 z1sC_|(SbPOs2*&P9kmnpE4d|OR!Wy(AKIL%%1olouCfHEP79TDc=ll3zjx^hy)9Gu z#bGN%;>4rA2rJ6<0IB`h7bx!A@gfvDPVNEW>Ixrt3#flTD^oyht@?>k#d7h%>Y-@R z9)jL8lN1jgd3FRQ5uXIktcgIs?pm9e--5aaFh81eDMoygN-lke6`^D=UuwC2MDga; z^@s4v2{W5-FNSRVq+td?ntDh3y6(NR9ZKNI_X0uB`OUilio@pU`|E-8hX)-1>Eokl zv6<5zn_y6Ef7$?gE^4_6wNcLVZSt9kC)%G(t>=In+IoQnwRgyjgFCz-JEguj2Ex#n j^RXgFXA=l3x}qQ=tKCWHZFl0rCiK`)sQtY#yt(=p8L-bv diff --git a/PythonHome/Lib/copy.py b/PythonHome/Lib/copy.py new file mode 100644 index 0000000000..c227a2e5c7 --- /dev/null +++ b/PythonHome/Lib/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/PythonHome/Lib/copy.pyc b/PythonHome/Lib/copy.pyc index 399329ff24dbd685fe862f74dcc2f194c349226e..fbe4e76689fd2a02855601c7887d75681c1cf3a4 100644 GIT binary patch delta 1439 zcmZ1wHzjog54WKu0|P^On82Uo>#EHUr>N^jDKlKL1{^hOKMVSdQ3oN zNk)F2M}BVVW@+vfOr&d@e2KS$3|*0Yi^^h)1 eoeW)RTJB`%+M~6fbX}Xfw2zaKmM16Z9RL6bbNy=o delta 551 zcmbP|x*%=?4>!L!0|SGzRZKu-Nk)F2k@;p@?iEbvf|JGgDlo+M^DV{@vlft>ypcZ= zU3{~(z;Q+lL1Uq2W^}>H&qe2Ah;0?yfiAXro_GePiRO|l7=n}MiAzszms*KoLZUPu zhDSFqke!QZLY{muBkSfv@@p`iJ70M(hQYlm*Dw`M(U^j+aB`&P91Jlvtpylj-?cD8 mbaJEiFAQ~Sbf#m7mFT)-h`rI>k1n?Pj^1&M(3pJ1@Bjcxew`cu diff --git a/PythonHome/Lib/copy_reg.py b/PythonHome/Lib/copy_reg.py new file mode 100644 index 0000000000..db1715092c --- /dev/null +++ b/PythonHome/Lib/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 , is about +# to be pickled, the (, ) 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/PythonHome/Lib/copy_reg.pyc b/PythonHome/Lib/copy_reg.pyc index 40c56234274fef21ca21f87d548445ae7327d9be..5c64c10d9134f645a922a7a3d560f020b20dd452 100644 GIT binary patch delta 632 zcmX@4zC&xnVrD~I1_lOKtC;l6l8n-%nDG1xJ+EMYzn}o;82{3eg3^*0m(--v^q7Fk zl8pR3kNn)!$(xvWlcB4IrI!p{3T&d2by=T~u5+^jn-m$Io5UqHIi7P8>GnfGZ>G=KTUzjAUr$5UL|X*HocXWa!Eh4gmo1C)e8m delta 248 zcmdm?bx3`~VrG761_lOatC)bwl8pR3BlF2un0I4{9boCj5UXSTi7vKz1)CJ6fuA{7 zpevkwhRc|dZ4>u#Ow~X5Vi{RChw(EpVQA_UbY*1Od|uFs5ktyKxDG??rSK^Xu_q!S E0NbudMgRZ+ diff --git a/PythonHome/Lib/csv.py b/PythonHome/Lib/csv.py new file mode 100644 index 0000000000..c155ada794 --- /dev/null +++ b/PythonHome/Lib/csv.py @@ -0,0 +1,456 @@ + +""" +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 + + # Issue 20004: Because DictReader is a classic class, this setter is + # ignored. At this point in 2.7's lifecycle, it is too late to change the + # base class for fear of breaking working code. If you want to change + # fieldnames without overwriting the getter, set _fieldnames directly. + @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([repr(x) for x in 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[^\w\n"\'])(?P ?)(?P["\']).*?(?P=quote)(?P=delim)', # ,".*?", + '(?:^|\n)(?P["\']).*?(?P=quote)(?P[^\w\n"\'])(?P ?)', # ".*?", + '(?P>[^\w\n"\'])(?P ?)(?P["\']).*?(?P=quote)(?:$|\n)', # ,".*?" + '(?:^|\n)(?P["\']).*?(?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':re.escape(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/PythonHome/Lib/csv.pyc b/PythonHome/Lib/csv.pyc deleted file mode 100644 index d5f1b2b6a6c73e68c96e6ad1f7a22ca138f7751a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 13375 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 P HRESULT +WINOLEAPI_(type) + +STDMETHODCALLTYPE + +STDMETHOD(name) +STDMETHOD_(type, name) + +STDAPICALLTYPE +""" + +def create_string_buffer(init, size=None): + """create_string_buffer(aString) -> character array + create_string_buffer(anInteger) -> character array + create_string_buffer(aString, anInteger) -> character array + """ + if isinstance(init, (str, unicode)): + if size is None: + size = len(init)+1 + buftype = c_char * size + buf = buftype() + buf.value = init + return buf + elif isinstance(init, (int, long)): + buftype = c_char * init + buf = buftype() + return buf + raise TypeError(init) + +def c_buffer(init, size=None): +## "deprecated, use create_string_buffer instead" +## import warnings +## warnings.warn("c_buffer is deprecated, use create_string_buffer instead", +## DeprecationWarning, stacklevel=2) + return create_string_buffer(init, size) + +_c_functype_cache = {} +def CFUNCTYPE(restype, *argtypes, **kw): + """CFUNCTYPE(restype, *argtypes, + use_errno=False, use_last_error=False) -> function prototype. + + restype: the result type + argtypes: a sequence specifying the argument types + + The function prototype can be called in different ways to create a + callable object: + + prototype(integer address) -> foreign function + prototype(callable) -> create and return a C callable function from callable + prototype(integer index, method name[, paramflags]) -> foreign function calling a COM method + prototype((ordinal number, dll object)[, paramflags]) -> foreign function exported by ordinal + prototype((function name, dll object)[, paramflags]) -> foreign function exported by name + """ + flags = _FUNCFLAG_CDECL + if kw.pop("use_errno", False): + flags |= _FUNCFLAG_USE_ERRNO + if kw.pop("use_last_error", False): + flags |= _FUNCFLAG_USE_LASTERROR + if kw: + raise ValueError("unexpected keyword argument(s) %s" % kw.keys()) + try: + return _c_functype_cache[(restype, argtypes, flags)] + except KeyError: + class CFunctionType(_CFuncPtr): + _argtypes_ = argtypes + _restype_ = restype + _flags_ = flags + _c_functype_cache[(restype, argtypes, flags)] = CFunctionType + return CFunctionType + +if _os.name in ("nt", "ce"): + from _ctypes import LoadLibrary as _dlopen + from _ctypes import FUNCFLAG_STDCALL as _FUNCFLAG_STDCALL + if _os.name == "ce": + # 'ce' doesn't have the stdcall calling convention + _FUNCFLAG_STDCALL = _FUNCFLAG_CDECL + + _win_functype_cache = {} + def WINFUNCTYPE(restype, *argtypes, **kw): + # docstring set later (very similar to CFUNCTYPE.__doc__) + flags = _FUNCFLAG_STDCALL + if kw.pop("use_errno", False): + flags |= _FUNCFLAG_USE_ERRNO + if kw.pop("use_last_error", False): + flags |= _FUNCFLAG_USE_LASTERROR + if kw: + raise ValueError("unexpected keyword argument(s) %s" % kw.keys()) + try: + return _win_functype_cache[(restype, argtypes, flags)] + except KeyError: + class WinFunctionType(_CFuncPtr): + _argtypes_ = argtypes + _restype_ = restype + _flags_ = flags + _win_functype_cache[(restype, argtypes, flags)] = WinFunctionType + return WinFunctionType + if WINFUNCTYPE.__doc__: + WINFUNCTYPE.__doc__ = CFUNCTYPE.__doc__.replace("CFUNCTYPE", "WINFUNCTYPE") + +elif _os.name == "posix": + from _ctypes import dlopen as _dlopen + +from _ctypes import sizeof, byref, addressof, alignment, resize +from _ctypes import get_errno, set_errno +from _ctypes import _SimpleCData + +def _check_size(typ, typecode=None): + # Check if sizeof(ctypes_type) against struct.calcsize. This + # should protect somewhat against a misconfigured libffi. + from struct import calcsize + if typecode is None: + # Most _type_ codes are the same as used in struct + typecode = typ._type_ + actual, required = sizeof(typ), calcsize(typecode) + if actual != required: + raise SystemError("sizeof(%s) wrong: %d instead of %d" % \ + (typ, actual, required)) + +class py_object(_SimpleCData): + _type_ = "O" + def __repr__(self): + try: + return super(py_object, self).__repr__() + except ValueError: + return "%s()" % type(self).__name__ +_check_size(py_object, "P") + +class c_short(_SimpleCData): + _type_ = "h" +_check_size(c_short) + +class c_ushort(_SimpleCData): + _type_ = "H" +_check_size(c_ushort) + +class c_long(_SimpleCData): + _type_ = "l" +_check_size(c_long) + +class c_ulong(_SimpleCData): + _type_ = "L" +_check_size(c_ulong) + +if _calcsize("i") == _calcsize("l"): + # if int and long have the same size, make c_int an alias for c_long + c_int = c_long + c_uint = c_ulong +else: + class c_int(_SimpleCData): + _type_ = "i" + _check_size(c_int) + + class c_uint(_SimpleCData): + _type_ = "I" + _check_size(c_uint) + +class c_float(_SimpleCData): + _type_ = "f" +_check_size(c_float) + +class c_double(_SimpleCData): + _type_ = "d" +_check_size(c_double) + +class c_longdouble(_SimpleCData): + _type_ = "g" +if sizeof(c_longdouble) == sizeof(c_double): + c_longdouble = c_double + +if _calcsize("l") == _calcsize("q"): + # if long and long long have the same size, make c_longlong an alias for c_long + c_longlong = c_long + c_ulonglong = c_ulong +else: + class c_longlong(_SimpleCData): + _type_ = "q" + _check_size(c_longlong) + + class c_ulonglong(_SimpleCData): + _type_ = "Q" + ## def from_param(cls, val): + ## return ('d', float(val), val) + ## from_param = classmethod(from_param) + _check_size(c_ulonglong) + +class c_ubyte(_SimpleCData): + _type_ = "B" +c_ubyte.__ctype_le__ = c_ubyte.__ctype_be__ = c_ubyte +# backward compatibility: +##c_uchar = c_ubyte +_check_size(c_ubyte) + +class c_byte(_SimpleCData): + _type_ = "b" +c_byte.__ctype_le__ = c_byte.__ctype_be__ = c_byte +_check_size(c_byte) + +class c_char(_SimpleCData): + _type_ = "c" +c_char.__ctype_le__ = c_char.__ctype_be__ = c_char +_check_size(c_char) + +class c_char_p(_SimpleCData): + _type_ = "z" + if _os.name == "nt": + def __repr__(self): + if not windll.kernel32.IsBadStringPtrA(self, -1): + return "%s(%r)" % (self.__class__.__name__, self.value) + return "%s(%s)" % (self.__class__.__name__, cast(self, c_void_p).value) + else: + def __repr__(self): + return "%s(%s)" % (self.__class__.__name__, cast(self, c_void_p).value) +_check_size(c_char_p, "P") + +class c_void_p(_SimpleCData): + _type_ = "P" +c_voidp = c_void_p # backwards compatibility (to a bug) +_check_size(c_void_p) + +class c_bool(_SimpleCData): + _type_ = "?" + +from _ctypes import POINTER, pointer, _pointer_type_cache + +def _reset_cache(): + _pointer_type_cache.clear() + _c_functype_cache.clear() + if _os.name in ("nt", "ce"): + _win_functype_cache.clear() + # _SimpleCData.c_wchar_p_from_param + POINTER(c_wchar).from_param = c_wchar_p.from_param + # _SimpleCData.c_char_p_from_param + POINTER(c_char).from_param = c_char_p.from_param + _pointer_type_cache[None] = c_void_p + # XXX for whatever reasons, creating the first instance of a callback + # function is needed for the unittests on Win64 to succeed. This MAY + # be a compiler bug, since the problem occurs only when _ctypes is + # compiled with the MS SDK compiler. Or an uninitialized variable? + CFUNCTYPE(c_int)(lambda: None) + +try: + from _ctypes import set_conversion_mode +except ImportError: + pass +else: + if _os.name in ("nt", "ce"): + set_conversion_mode("mbcs", "ignore") + else: + set_conversion_mode("ascii", "strict") + + class c_wchar_p(_SimpleCData): + _type_ = "Z" + + class c_wchar(_SimpleCData): + _type_ = "u" + + def create_unicode_buffer(init, size=None): + """create_unicode_buffer(aString) -> character array + create_unicode_buffer(anInteger) -> character array + create_unicode_buffer(aString, anInteger) -> character array + """ + if isinstance(init, (str, unicode)): + if size is None: + size = len(init)+1 + buftype = c_wchar * size + buf = buftype() + buf.value = init + return buf + elif isinstance(init, (int, long)): + buftype = c_wchar * init + buf = buftype() + return buf + raise TypeError(init) + +# XXX Deprecated +def SetPointerType(pointer, cls): + if _pointer_type_cache.get(cls, None) is not None: + raise RuntimeError("This type already exists in the cache") + if id(pointer) not in _pointer_type_cache: + raise RuntimeError("What's this???") + pointer.set_type(cls) + _pointer_type_cache[cls] = pointer + del _pointer_type_cache[id(pointer)] + +# XXX Deprecated +def ARRAY(typ, len): + return typ * len + +################################################################ + + +class CDLL(object): + """An instance of this class represents a loaded dll/shared + library, exporting functions using the standard C calling + convention (named 'cdecl' on Windows). + + The exported functions can be accessed as attributes, or by + indexing with the function name. Examples: + + .qsort -> callable object + ['qsort'] -> callable object + + Calling the functions releases the Python GIL during the call and + reacquires it afterwards. + """ + _func_flags_ = _FUNCFLAG_CDECL + _func_restype_ = c_int + + def __init__(self, name, mode=DEFAULT_MODE, handle=None, + use_errno=False, + use_last_error=False): + self._name = name + flags = self._func_flags_ + if use_errno: + flags |= _FUNCFLAG_USE_ERRNO + if use_last_error: + flags |= _FUNCFLAG_USE_LASTERROR + + class _FuncPtr(_CFuncPtr): + _flags_ = flags + _restype_ = self._func_restype_ + self._FuncPtr = _FuncPtr + + if handle is None: + self._handle = _dlopen(self._name, mode) + else: + self._handle = handle + + def __repr__(self): + return "<%s '%s', handle %x at %x>" % \ + (self.__class__.__name__, self._name, + (self._handle & (_sys.maxint*2 + 1)), + id(self) & (_sys.maxint*2 + 1)) + + def __getattr__(self, name): + if name.startswith('__') and name.endswith('__'): + raise AttributeError(name) + func = self.__getitem__(name) + setattr(self, name, func) + return func + + def __getitem__(self, name_or_ordinal): + func = self._FuncPtr((name_or_ordinal, self)) + if not isinstance(name_or_ordinal, (int, long)): + func.__name__ = name_or_ordinal + return func + +class PyDLL(CDLL): + """This class represents the Python library itself. It allows to + access Python API functions. The GIL is not released, and + Python exceptions are handled correctly. + """ + _func_flags_ = _FUNCFLAG_CDECL | _FUNCFLAG_PYTHONAPI + +if _os.name in ("nt", "ce"): + + class WinDLL(CDLL): + """This class represents a dll exporting functions using the + Windows stdcall calling convention. + """ + _func_flags_ = _FUNCFLAG_STDCALL + + # XXX Hm, what about HRESULT as normal parameter? + # Mustn't it derive from c_long then? + from _ctypes import _check_HRESULT, _SimpleCData + class HRESULT(_SimpleCData): + _type_ = "l" + # _check_retval_ is called with the function's result when it + # is used as restype. It checks for the FAILED bit, and + # raises a WindowsError if it is set. + # + # The _check_retval_ method is implemented in C, so that the + # method definition itself is not included in the traceback + # when it raises an error - that is what we want (and Python + # doesn't have a way to raise an exception in the caller's + # frame). + _check_retval_ = _check_HRESULT + + class OleDLL(CDLL): + """This class represents a dll exporting functions using the + Windows stdcall calling convention, and returning HRESULT. + HRESULT error values are automatically raised as WindowsError + exceptions. + """ + _func_flags_ = _FUNCFLAG_STDCALL + _func_restype_ = HRESULT + +class LibraryLoader(object): + def __init__(self, dlltype): + self._dlltype = dlltype + + def __getattr__(self, name): + if name[0] == '_': + raise AttributeError(name) + dll = self._dlltype(name) + setattr(self, name, dll) + return dll + + def __getitem__(self, name): + return getattr(self, name) + + def LoadLibrary(self, name): + return self._dlltype(name) + +cdll = LibraryLoader(CDLL) +pydll = LibraryLoader(PyDLL) + +if _os.name in ("nt", "ce"): + pythonapi = PyDLL("python dll", None, _sys.dllhandle) +elif _sys.platform == "cygwin": + pythonapi = PyDLL("libpython%d.%d.dll" % _sys.version_info[:2]) +else: + pythonapi = PyDLL(None) + + +if _os.name in ("nt", "ce"): + windll = LibraryLoader(WinDLL) + oledll = LibraryLoader(OleDLL) + + if _os.name == "nt": + GetLastError = windll.kernel32.GetLastError + else: + GetLastError = windll.coredll.GetLastError + from _ctypes import get_last_error, set_last_error + + def WinError(code=None, descr=None): + if code is None: + code = GetLastError() + if descr is None: + descr = FormatError(code).strip() + return WindowsError(code, descr) + +if sizeof(c_uint) == sizeof(c_void_p): + c_size_t = c_uint + c_ssize_t = c_int +elif sizeof(c_ulong) == sizeof(c_void_p): + c_size_t = c_ulong + c_ssize_t = c_long +elif sizeof(c_ulonglong) == sizeof(c_void_p): + c_size_t = c_ulonglong + c_ssize_t = c_longlong + +# functions + +from _ctypes import _memmove_addr, _memset_addr, _string_at_addr, _cast_addr + +## void *memmove(void *, const void *, size_t); +memmove = CFUNCTYPE(c_void_p, c_void_p, c_void_p, c_size_t)(_memmove_addr) + +## void *memset(void *, int, size_t) +memset = CFUNCTYPE(c_void_p, c_void_p, c_int, c_size_t)(_memset_addr) + +def PYFUNCTYPE(restype, *argtypes): + class CFunctionType(_CFuncPtr): + _argtypes_ = argtypes + _restype_ = restype + _flags_ = _FUNCFLAG_CDECL | _FUNCFLAG_PYTHONAPI + return CFunctionType + +_cast = PYFUNCTYPE(py_object, c_void_p, py_object, py_object)(_cast_addr) +def cast(obj, typ): + return _cast(obj, obj, typ) + +_string_at = PYFUNCTYPE(py_object, c_void_p, c_int)(_string_at_addr) +def string_at(ptr, size=-1): + """string_at(addr[, size]) -> string + + Return the string at addr.""" + return _string_at(ptr, size) + +try: + from _ctypes import _wstring_at_addr +except ImportError: + pass +else: + _wstring_at = PYFUNCTYPE(py_object, c_void_p, c_int)(_wstring_at_addr) + def wstring_at(ptr, size=-1): + """wstring_at(addr[, size]) -> string + + Return the string at addr.""" + return _wstring_at(ptr, size) + + +if _os.name in ("nt", "ce"): # COM stuff + def DllGetClassObject(rclsid, riid, ppv): + try: + ccom = __import__("comtypes.server.inprocserver", globals(), locals(), ['*']) + except ImportError: + return -2147221231 # CLASS_E_CLASSNOTAVAILABLE + else: + return ccom.DllGetClassObject(rclsid, riid, ppv) + + def DllCanUnloadNow(): + try: + ccom = __import__("comtypes.server.inprocserver", globals(), locals(), ['*']) + except ImportError: + return 0 # S_OK + return ccom.DllCanUnloadNow() + +from ctypes._endian import BigEndianStructure, LittleEndianStructure + +# Fill in specifically-sized types +c_int8 = c_byte +c_uint8 = c_ubyte +for kind in [c_short, c_int, c_long, c_longlong]: + if sizeof(kind) == 2: c_int16 = kind + elif sizeof(kind) == 4: c_int32 = kind + elif sizeof(kind) == 8: c_int64 = kind +for kind in [c_ushort, c_uint, c_ulong, c_ulonglong]: + if sizeof(kind) == 2: c_uint16 = kind + elif sizeof(kind) == 4: c_uint32 = kind + elif sizeof(kind) == 8: c_uint64 = kind +del(kind) + +_reset_cache() diff --git a/PythonHome/Lib/ctypes/__init__.pyc b/PythonHome/Lib/ctypes/__init__.pyc index 854774443a48718bd3971c50538d3a79c1ded320..3de5e99b57a1e71cfbf7c72b8cd5e97e9762f428 100644 GIT binary patch delta 3453 zcmbW4-z!657{{HM3x%TD*xAM~Z3~^)WPZ&yBMGB6<&;bO#I`3HQ@-MRSm{XXC4ectDsvmI{ZkSof5&(Aycj}K2} z{XMxSMfw84op}q`#o&xQ9i0^Y(sEtz@Ie32pi3Nx%5za!bO$D*L2+?WugtLU4Rs9JpERs5mCXWrN%NILA@Fu z;FVQ*t62oe5HEowrwxN-TpIyNvktBET8FwF)uV3T^k}wg{YKrqCD{%yC70cE{(Gw>8k<5rO!2`NJMP2m`w+OT}Gx& z*8q8EjsaBW&ZJA02cSqgQ7Z%3@7DdSLt4oe;AVX+8!MAo8}_n+P!Q$2Fb1V z5J;LkM36k{aAG7aaR^AbY)T`YCIn^2=)&m%{IV&vxX@39D;LsHrn&7-U~Xx=%Zf&n V@+AK+N|W8U$o~p!=Y8K8_X8hiw8sDd delta 1458 zcmeBP!?<-0qY(3FUal?S3Bkz>P{6uTNS=>h3CMG{iV3JJ$;i($GM{Y7FEP1_uMJ&% zvmyUW7IeYMi82zClSMvahyxATJXiEPBZdS>!(H)(7~&ue$0hz_Y5+;_ODkeZB+7(g zm;y9?l580^;mP}D^RbGT%jIGf*Okx1D*i+syZMV1FwJpP#0W-khzTfRcgqQ-Vyt$y zC}X$NS)~Z8`hP0e-M&>7(~Y1A$yQ6pX3l15^=xe6E;ISEMkf{xGLu(ox?&NRm~5_< zgH`;E7FGvsUZgFFX|W-{%w!JTWf%s566|-~;~3%~pRwy>_t|#++t@6S*nHbC2CKy6 z24hSwfYPR^Nj)=GtN)s>#1IF0;j_he4Dm!6naSo>Qj9El+#(F=7 z9LSR`HZ9o1HwW5=VfqE6;e*{9Y#Ju3I;_GbzFERC7rQ~{oK9fVF!{doI;`T?T(Yr> zce%!371wuj!Y00XmzyD`gMfj%*}_8=Qv&4WWu9&rCV|4$)C+r-`{;$~1CaU`-dC`h gvzgV`6uZUEeh)D;03Eb>t^YR6;uPeC4I$Bt0GgtlK>z>% diff --git a/PythonHome/Lib/ctypes/_endian.py b/PythonHome/Lib/ctypes/_endian.py new file mode 100644 index 0000000000..f80e675aaf --- /dev/null +++ b/PythonHome/Lib/ctypes/_endian.py @@ -0,0 +1,64 @@ +###################################################################### +# This file should be kept compatible with Python 2.3, see PEP 291. # +###################################################################### +import sys +from ctypes import * + +_array_type = type(Array) + +def _other_endian(typ): + """Return the type with the 'other' byte order. Simple types like + c_int and so on already have __ctype_be__ and __ctype_le__ + attributes which contain the types, for more complicated types + arrays and structures are supported. + """ + # check _OTHER_ENDIAN attribute (present if typ is primitive type) + if hasattr(typ, _OTHER_ENDIAN): + return getattr(typ, _OTHER_ENDIAN) + # if typ is array + if isinstance(typ, _array_type): + return _other_endian(typ._type_) * typ._length_ + # if typ is structure + if issubclass(typ, Structure): + return typ + raise TypeError("This type does not support other endian: %s" % typ) + +class _swapped_meta(type(Structure)): + def __setattr__(self, attrname, value): + if attrname == "_fields_": + fields = [] + for desc in value: + name = desc[0] + typ = desc[1] + rest = desc[2:] + fields.append((name, _other_endian(typ)) + rest) + value = fields + super(_swapped_meta, self).__setattr__(attrname, value) + +################################################################ + +# Note: The Structure metaclass checks for the *presence* (not the +# value!) of a _swapped_bytes_ attribute to determine the bit order in +# structures containing bit fields. + +if sys.byteorder == "little": + _OTHER_ENDIAN = "__ctype_be__" + + LittleEndianStructure = Structure + + class BigEndianStructure(Structure): + """Structure with big endian byte order""" + __metaclass__ = _swapped_meta + _swappedbytes_ = None + +elif sys.byteorder == "big": + _OTHER_ENDIAN = "__ctype_le__" + + BigEndianStructure = Structure + class LittleEndianStructure(Structure): + """Structure with little endian byte order""" + __metaclass__ = _swapped_meta + _swappedbytes_ = None + +else: + raise RuntimeError("Invalid byteorder") diff --git a/PythonHome/Lib/ctypes/_endian.pyc b/PythonHome/Lib/ctypes/_endian.pyc index f135dabc1102c051e38766eb039cf496cbd05695..0a6da991a04664225d176b682c5b8271ca7d98dc 100644 GIT binary patch delta 352 zcmaDVxKVgR2(zIx0|P^On82Uo>#EHUr>N^jDKlKL1{^hOKMVSdQ3oN yNk)F2M}BVVzkLVWRXr8N^wT1v_9xPPQ*#2Dz@SXx@22-Pwt~LX&#Zf encs`uu$7bQk|UG5)uW zZ`YdA{VC!9ZG85w5eY>$Q5p#g(l)XQ0)Itm7i706n?*6Km!w^i-Lh$6pHcipdEVAZl@jO zahi_*ShY^NS4t<<%TqaD-Y#y}e$##EmS-4(68+x3P8#9mlm_V*6^8lbPfCXV|}XVDo7AxbCv<2c|8LHQ%w> zd^>Fh?RhrQ%9I%E^~H@Q`Q%r`w}{VrC~}eKD2=>?TxUsdLlvkRSwm&5R^UhuUrlo_ zXt%wz<$ZN~t3W; z@?53zq9D&9Avf&0Jb{c*-!2^rO$D}!*&;V;)RG>0HBF+Nd!<&-86{8SEKPE<@C1V4 zK)ctDb0--#V~BP?4KiIKdm6Ndk^q%YY1FY2C)z3sF;)Cd;wzb+Mf8Ml4FldRgsy3H zPk9>Sm%dq9s^7i0@S8jJwTH{gcfYPt%RV>rCs@!x{Yez6N}qFvItM4{IpW>mNmRF; zRx95B42@2odZ6A>C^^+9w|2%&mI)F(12(iiuS^4JsW%H1#g1^=6O!(mU3a1)|bo&0_NHvG+El9S=W%E}iD zi(l5?u`s!T6DAO+5j1z|uS@mUZ^Jba^>wb_sd%~k>pTz2`PKl(Gza=f&klZ$3T<@| zUD^M#CSO4qoXsrvq!0NZ0BZf4C+oLpCEavQ8g~{QHbY39nN1R$2`M! z8Ye#8K^5ExY@`#}<$uJ2a@FLj=hZ$Z4<%qiwF)>zijl=30)qvFPQ|3x( z%7uHnT~EBXQNdyRR(+Gw2@%#I;hPjMB0eOFMhruIcGiAHMFW9i4kLr2+ec%oMA-_V=0EU(fhnlx2TTo|iEX zR`~k7W36yYHn^Ts%=g@}ntji`VO&49_g{5yY-UfG{h!g~{@-2yr8E0VR=cecI0j6A zmQ_u0`s%#QHfk)_aC2vQ;o-`If$+H8jhH$8W~tkK7>5o!)p+`@;(yHbrctzx4~ObK z`MJRXgRy5Q1M1~5Vblsb?YwI^$aBT=aAL{@I#v|`dIkR{%!h?3rAJUUix^SDN6cNs zXa9tvZ%vMNan8v81I7{f8Z-~HgP!4DfDqD(Lh!p@`%48j3|M+RtN1k{+oQblG8`Jo z?vq&i?!Ih5&+t}EY#BL^u0O!BnE;YEdjrL|ho5C!;Jm==3d%zW?V*v^!L8(pM?dO^ zNu6Z7{uMX8Yu0O~9gIkDF=|9!E5#*f)!B#|$~B%`U27`R74)`NB@x|3yT<{}Yc!T*$nhNG*XhEb@`Q{x)ruBcL?<|>*q^B#1@j5(c=PeQ>W zNB$GV!Aw7WCNk=^=cOsEZ6s4tg4%Y*C7TxmATWuMuOV*U990+a>*u%-mGrV6cD2he zrmDr5>+W6!RU=|;BQQZyj@A%_$({>C821K7rhAP1LyR%dKU7U-!ZOs&iHV<|p4BPAEp6xWZyujYjPMVav3?He^^|t)M zj`?+5p7C5^=NCI!h9pi$_LZ*5LVum^qsADHrrPy+$xutn^i{%R#}Qnj$++t%!(c1v zFRoWrXL_yOXM7k5qy3>QjQ;*-e3psXL#WO(ts@}lkI9!&Y0}4y6uY0wAoe5hzTclPbDt9v;J`)7M0|!NqSnnm!UOSQ}-0esW&SBM*P;<*hl7Y+l!BPQCsGEt*1$ z88H`(CRg?PF0iFuug!9}Cc5=7ZPx2f{|p=&u+%!RQrytzDowtaU*~Dsb}th3I${gv zUFAZ=uV{Y{&p90&#h>Fc^DGqD&XUsPPm^ZN0I7PPO!yiBiG4>AkMi+pD?YDpUG|w7 zf_*d$g=#wc=588x+R-g_^qW{=1o7w;e#eU=raCeSyDOSXsr$cJ8L5m_%hh7{_hj{S Qb+meZa&mIIQm&f+0?cV)@Bjb+ diff --git a/PythonHome/Lib/ctypes/macholib/dylib.py b/PythonHome/Lib/ctypes/macholib/dylib.py new file mode 100644 index 0000000000..ea3dd38bdf --- /dev/null +++ b/PythonHome/Lib/ctypes/macholib/dylib.py @@ -0,0 +1,66 @@ +###################################################################### +# This file should be kept compatible with Python 2.3, see PEP 291. # +###################################################################### +""" +Generic dylib path manipulation +""" + +import re + +__all__ = ['dylib_info'] + +DYLIB_RE = re.compile(r"""(?x) +(?P^.*)(?:^|/) +(?P + (?P\w+?) + (?:\.(?P[^._]+))? + (?:_(?P[^._]+))? + \.dylib$ +) +""") + +def dylib_info(filename): + """ + A dylib name can take one of the following four forms: + Location/Name.SomeVersion_Suffix.dylib + Location/Name.SomeVersion.dylib + Location/Name_Suffix.dylib + Location/Name.dylib + + returns None if not found or a mapping equivalent to: + dict( + location='Location', + name='Name.SomeVersion_Suffix.dylib', + shortname='Name', + version='SomeVersion', + suffix='Suffix', + ) + + Note that SomeVersion and Suffix are optional and may be None + if not present. + """ + is_dylib = DYLIB_RE.match(filename) + if not is_dylib: + return None + return is_dylib.groupdict() + + +def test_dylib_info(): + def d(location=None, name=None, shortname=None, version=None, suffix=None): + return dict( + location=location, + name=name, + shortname=shortname, + version=version, + suffix=suffix + ) + assert dylib_info('completely/invalid') is None + assert dylib_info('completely/invalide_debug') is None + assert dylib_info('P/Foo.dylib') == d('P', 'Foo.dylib', 'Foo') + assert dylib_info('P/Foo_debug.dylib') == d('P', 'Foo_debug.dylib', 'Foo', suffix='debug') + assert dylib_info('P/Foo.A.dylib') == d('P', 'Foo.A.dylib', 'Foo', 'A') + assert dylib_info('P/Foo_debug.A.dylib') == d('P', 'Foo_debug.A.dylib', 'Foo_debug', 'A') + assert dylib_info('P/Foo.A_debug.dylib') == d('P', 'Foo.A_debug.dylib', 'Foo', 'A', 'debug') + +if __name__ == '__main__': + test_dylib_info() diff --git a/PythonHome/Lib/ctypes/macholib/dylib.pyc b/PythonHome/Lib/ctypes/macholib/dylib.pyc deleted file mode 100644 index 05973c2ae4b7c43843ddebca4dc95649bbbbcf9c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2255 zcmb7F&2HO95FXN!Y$^VUouF`gC|ERwsHBjSs}b9E)AR>01cL%nBvsAQ-6cN%6NuI~Dph$LI?-7YA3Kx4jGS?h#*=9hm^e#Y@!$CLOpASCh##lJO#h0d zyZ5Hka`z4&Cs`=i-J|aPj=Q&gbiP$=q`_G2wj6vIrbk(BL^XK*V6Ri^w+CI`e5G=Y z>vn%Q>iR!E=ydjG+rF4ihr{^Iwar0S9J<%)v_cF1FmF7bVCYXF4AD!A&WQ!L8bwp$j) zPP;v&g9UR2RgV3B!lpc(OaFpTw4FuVpoOulX07J72ba%~aST!r;IlqQQj3*d+ z11ofqD}NTftJ7P!B7FtV1G}e7q#u&8=@(1%cp!8Aw-vqg8$2rX8*~~pn2QDOF*>PW zme{t$G#L}MD7pot#mL_($mI%hMUbm>QIiAzsKC}Lu-g=^Q#6PDS%Ga-V0X&X_};o4 zxM~&AA=tiq7u@thP8g3{7<~-=83g(Ux&*s#bJIY>J-4~fo}=5==^O-5z3(=F>`D4& zZ$gqTN#&%^%i3@%$}%==Rn)7?SrQYe4EDlfq{r#>_ymueuE(z3s4$RJxc&%2FGCRO zV)oS=Sclnok|?8+v#mJAqmLuB#eY*PKT^lj6U`nRZhf6)MPHKh4>fyusaq&kdVPj1 zYzqs$R_s=F5|=!f;*yn_VRyeY;%oVWaxK^H>pL@CdDsli7Xy7&E3a>^y|nG_S6vaO z<)*6E<&ZoPn2=e8*w9`H@+Vv2~<4i6r;g-TnW-AJTCY0EUr+T k1;q{h=E8hD&Z23ecBPKl;fB3zH|@q!({6s$Twk{S0dJHNi~s-t diff --git a/PythonHome/Lib/ctypes/macholib/framework.py b/PythonHome/Lib/ctypes/macholib/framework.py new file mode 100644 index 0000000000..dd7fb2f296 --- /dev/null +++ b/PythonHome/Lib/ctypes/macholib/framework.py @@ -0,0 +1,68 @@ +###################################################################### +# This file should be kept compatible with Python 2.3, see PEP 291. # +###################################################################### +""" +Generic framework path manipulation +""" + +import re + +__all__ = ['framework_info'] + +STRICT_FRAMEWORK_RE = re.compile(r"""(?x) +(?P^.*)(?:^|/) +(?P + (?P\w+).framework/ + (?:Versions/(?P[^/]+)/)? + (?P=shortname) + (?:_(?P[^_]+))? +)$ +""") + +def framework_info(filename): + """ + A framework name can take one of the following four forms: + Location/Name.framework/Versions/SomeVersion/Name_Suffix + Location/Name.framework/Versions/SomeVersion/Name + Location/Name.framework/Name_Suffix + Location/Name.framework/Name + + returns None if not found, or a mapping equivalent to: + dict( + location='Location', + name='Name.framework/Versions/SomeVersion/Name_Suffix', + shortname='Name', + version='SomeVersion', + suffix='Suffix', + ) + + Note that SomeVersion and Suffix are optional and may be None + if not present + """ + is_framework = STRICT_FRAMEWORK_RE.match(filename) + if not is_framework: + return None + return is_framework.groupdict() + +def test_framework_info(): + def d(location=None, name=None, shortname=None, version=None, suffix=None): + return dict( + location=location, + name=name, + shortname=shortname, + version=version, + suffix=suffix + ) + assert framework_info('completely/invalid') is None + assert framework_info('completely/invalid/_debug') is None + assert framework_info('P/F.framework') is None + assert framework_info('P/F.framework/_debug') is None + assert framework_info('P/F.framework/F') == d('P', 'F.framework/F', 'F') + assert framework_info('P/F.framework/F_debug') == d('P', 'F.framework/F_debug', 'F', suffix='debug') + assert framework_info('P/F.framework/Versions') is None + assert framework_info('P/F.framework/Versions/A') is None + assert framework_info('P/F.framework/Versions/A/F') == d('P', 'F.framework/Versions/A/F', 'F', 'A') + assert framework_info('P/F.framework/Versions/A/F_debug') == d('P', 'F.framework/Versions/A/F_debug', 'F', 'A', 'debug') + +if __name__ == '__main__': + test_framework_info() diff --git a/PythonHome/Lib/ctypes/macholib/framework.pyc b/PythonHome/Lib/ctypes/macholib/framework.pyc deleted file mode 100644 index 17ece65d9f9650fbc57df92ebc55139d83d80883..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2565 zcmbVO;Z7Sz5S}yGfCC{-XhkZuI<=`dClQz5C_pWQ(<-Tp&QT(zl*@6qh70FA_jVmX zfL!vAyfr*>7iOXTO=di9hG+zde81390y0@c%WM zeuge0dV$`es6vTFFCa|N9)t=hi(XAoG)ZR|PEu5*Hvm^Ds)2~3=&_4sdm+U7d&W0)VO z-Aw-qm9u`-s5|Rh50fku{Myd)-G;NivUB1NCsLSRtK0Z6Oz&s85!LqLy~gs`qFW$V zo~c}8TkSIX^>DEE!;bsoy@uOZAK6(Q+i8pz`eJ_2?Z!vI`@jRDwIX4kQE?;p#ZNK%b(QEt;h$@d4~GNNp1wC_78hy0+O@b~j6s z>@ZIEAPsVKc~7s%at^?gB1Uc->q}=JpShFuR51{Y-;witxPkYsWKaI@E{v^<#ax*| zo@%?zM~}O9ni)QD8r`?E+zvpXexHM&ej3EDgG8mqHraU`qBu0p*foyKh&`)IqZlpS zzX0HfuP$9NZkKF~IWshLX|~|n>Qd11`zUJnrsZi($0(m4FY4AY}i2>*~1lf zkb^0GPOBgheJ?n+ca_9Zj$6dCpDT@^iK^{PGGA|@>pb;~Oq?c+};9r*X)e`=wq(|A497iFHrYV}Cvk9(<`j-->Ucy{s zOf*Z;9FP_xe=i}gmv;H1q@OS8|0?Nklq`QFmT%J8q&V=Ib$-}eCD=j%V+X2&d{iKD z>W=d!3*~M?FLJLOnx;M+w7o;-tclhZ8&`s&sv#Rf!{%?Eg}`ex!B>dwLGDTW;&T(CUTDnh|vVUlT2HXG@HfOt?dR zOY>b^Fz&XBZ8=jftQhJgD3Y#2?>K)h8W=qW^x|8m+@}8Y9g}WL)|Pi48Fib5>rHLH z(?W5I&jEUyogu`T0K}6H0?8XfQ)`uTecR0QEEl?Xd<|D814q#)ZO+S-ymYuwYYrV* zi_?qN@O#I)E7FoB-1hxm5U0K`FFL|x-;c7;_mOl&cy=*meLqMNs90uZp*VU>K&fq> t?9Qb2eNGP8g8TueU=t5}Su{x0nxxSUC~B42%1os;JyV&vJ+m-t{R66ydaVEe diff --git a/PythonHome/Lib/ctypes/util.py b/PythonHome/Lib/ctypes/util.py new file mode 100644 index 0000000000..fe0ed0a085 --- /dev/null +++ b/PythonHome/Lib/ctypes/util.py @@ -0,0 +1,276 @@ +###################################################################### +# This file should be kept compatible with Python 2.3, see PEP 291. # +###################################################################### +import sys, os + +# find_library(name) returns the pathname of a library, or None. +if os.name == "nt": + + 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. + """ + # This function was copied from Lib/distutils/msvccompiler.py + 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 find_msvcrt(): + """Return the name of the VC runtime dll""" + version = _get_build_version() + if version is None: + # better be safe than sorry + return None + if version <= 6: + clibname = 'msvcrt' + else: + clibname = 'msvcr%d' % (version * 10) + + # If python was built with in debug mode + import imp + if imp.get_suffixes()[0][0] == '_d.pyd': + clibname += 'd' + return clibname+'.dll' + + def find_library(name): + if name in ('c', 'm'): + return find_msvcrt() + # See MSDN for the REAL search order. + for directory in os.environ['PATH'].split(os.pathsep): + fname = os.path.join(directory, name) + if os.path.isfile(fname): + return fname + if fname.lower().endswith(".dll"): + continue + fname = fname + ".dll" + if os.path.isfile(fname): + return fname + return None + +if os.name == "ce": + # search path according to MSDN: + # - absolute path specified by filename + # - The .exe launch directory + # - the Windows directory + # - ROM dll files (where are they?) + # - OEM specified search path: HKLM\Loader\SystemPath + def find_library(name): + return name + +if os.name == "posix" and sys.platform == "darwin": + from ctypes.macholib.dyld import dyld_find as _dyld_find + def find_library(name): + possible = ['lib%s.dylib' % name, + '%s.dylib' % name, + '%s.framework/%s' % (name, name)] + for name in possible: + try: + return _dyld_find(name) + except ValueError: + continue + return None + +elif os.name == "posix": + # Andreas Degert's find functions, using gcc, /sbin/ldconfig, objdump + import re, tempfile, errno + + def _findLib_gcc(name): + expr = r'[^\(\)\s]*lib%s\.[^\(\)\s]*' % re.escape(name) + fdout, ccout = tempfile.mkstemp() + os.close(fdout) + cmd = 'if type gcc >/dev/null 2>&1; then CC=gcc; elif type cc >/dev/null 2>&1; then CC=cc;else exit 10; fi;' \ + 'LANG=C LC_ALL=C $CC -Wl,-t -o ' + ccout + ' 2>&1 -l' + name + try: + f = os.popen(cmd) + try: + trace = f.read() + finally: + rv = f.close() + finally: + try: + os.unlink(ccout) + except OSError, e: + if e.errno != errno.ENOENT: + raise + if rv == 10: + raise OSError, 'gcc or cc command not found' + res = re.search(expr, trace) + if not res: + return None + return res.group(0) + + + if sys.platform == "sunos5": + # use /usr/ccs/bin/dump on solaris + def _get_soname(f): + if not f: + return None + cmd = "/usr/ccs/bin/dump -Lpv 2>/dev/null " + f + f = os.popen(cmd) + try: + data = f.read() + finally: + f.close() + res = re.search(r'\[.*\]\sSONAME\s+([^\s]+)', data) + if not res: + return None + return res.group(1) + else: + def _get_soname(f): + # assuming GNU binutils / ELF + if not f: + return None + cmd = 'if ! type objdump >/dev/null 2>&1; then exit 10; fi;' \ + "objdump -p -j .dynamic 2>/dev/null " + f + f = os.popen(cmd) + dump = f.read() + rv = f.close() + if rv == 10: + raise OSError, 'objdump command not found' + f = os.popen(cmd) + try: + data = f.read() + finally: + f.close() + res = re.search(r'\sSONAME\s+([^\s]+)', data) + if not res: + return None + return res.group(1) + + if (sys.platform.startswith("freebsd") + or sys.platform.startswith("openbsd") + or sys.platform.startswith("dragonfly")): + + def _num_version(libname): + # "libxyz.so.MAJOR.MINOR" => [ MAJOR, MINOR ] + parts = libname.split(".") + nums = [] + try: + while parts: + nums.insert(0, int(parts.pop())) + except ValueError: + pass + return nums or [ sys.maxint ] + + def find_library(name): + ename = re.escape(name) + expr = r':-l%s\.\S+ => \S*/(lib%s\.\S+)' % (ename, ename) + f = os.popen('/sbin/ldconfig -r 2>/dev/null') + try: + data = f.read() + finally: + f.close() + res = re.findall(expr, data) + if not res: + return _get_soname(_findLib_gcc(name)) + res.sort(cmp= lambda x,y: cmp(_num_version(x), _num_version(y))) + return res[-1] + + elif sys.platform == "sunos5": + + def _findLib_crle(name, is64): + if not os.path.exists('/usr/bin/crle'): + return None + + if is64: + cmd = 'env LC_ALL=C /usr/bin/crle -64 2>/dev/null' + else: + cmd = 'env LC_ALL=C /usr/bin/crle 2>/dev/null' + + for line in os.popen(cmd).readlines(): + line = line.strip() + if line.startswith('Default Library Path (ELF):'): + paths = line.split()[4] + + if not paths: + return None + + for dir in paths.split(":"): + libfile = os.path.join(dir, "lib%s.so" % name) + if os.path.exists(libfile): + return libfile + + return None + + def find_library(name, is64 = False): + return _get_soname(_findLib_crle(name, is64) or _findLib_gcc(name)) + + else: + + def _findSoname_ldconfig(name): + import struct + if struct.calcsize('l') == 4: + machine = os.uname()[4] + '-32' + else: + machine = os.uname()[4] + '-64' + mach_map = { + 'x86_64-64': 'libc6,x86-64', + 'ppc64-64': 'libc6,64bit', + 'sparc64-64': 'libc6,64bit', + 's390x-64': 'libc6,64bit', + 'ia64-64': 'libc6,IA-64', + } + abi_type = mach_map.get(machine, 'libc6') + + # XXX assuming GLIBC's ldconfig (with option -p) + expr = r'\s+(lib%s\.[^\s]+)\s+\(%s' % (re.escape(name), abi_type) + f = os.popen('/sbin/ldconfig -p 2>/dev/null') + try: + data = f.read() + finally: + f.close() + res = re.search(expr, data) + if not res: + return None + return res.group(1) + + def find_library(name): + return _findSoname_ldconfig(name) or _get_soname(_findLib_gcc(name)) + +################################################################ +# test code + +def test(): + from ctypes import cdll + if os.name == "nt": + print cdll.msvcrt + print cdll.load("msvcrt") + print find_library("msvcrt") + + if os.name == "posix": + # find and load_version + print find_library("m") + print find_library("c") + print find_library("bz2") + + # getattr +## print cdll.m +## print cdll.bz2 + + # load + if sys.platform == "darwin": + print cdll.LoadLibrary("libm.dylib") + print cdll.LoadLibrary("libcrypto.dylib") + print cdll.LoadLibrary("libSystem.dylib") + print cdll.LoadLibrary("System.framework/System") + else: + print cdll.LoadLibrary("libm.so") + print cdll.LoadLibrary("libcrypt.so") + print find_library("crypt") + +if __name__ == "__main__": + test() diff --git a/PythonHome/Lib/ctypes/util.pyc b/PythonHome/Lib/ctypes/util.pyc index b5a3040a50fd6d2dca1d3e8c588153d7da2a27aa..89129a4d683ac1008d023f9e77cfe5f3345d41fc 100644 GIT binary patch delta 1026 zcmaE5yT(a~`7 znaI*AGWmwsVzP7!Z=Nf@l{`z+7+EHtkP0W$T1ROk@~jn^JWciqS(b`So-5}I0I14f AFaQ7m delta 448 zcmZ4E^vYI<`7EpIa|d9RF-7q=NXw#{wN}{xre2T5vxQr z+d8Zgll?e~&^2uS$YF~`F^9zFaxQjebk!hxC)*3NZa%@Ai$xdEQC0k(u}E-;Y~Cd3 zfkgtS!(O-%o5W&FyMd0nE9%FDDFJj;fdqC9F_IgwYY3DHVq~7YL?#^5IG{Z)vbxx{ QZIge3sX;_?@)HFQ0Ej7q;s5{u diff --git a/PythonHome/Lib/ctypes/wintypes.py b/PythonHome/Lib/ctypes/wintypes.py new file mode 100644 index 0000000000..dafbb78b78 --- /dev/null +++ b/PythonHome/Lib/ctypes/wintypes.py @@ -0,0 +1,185 @@ +###################################################################### +# This file should be kept compatible with Python 2.3, see PEP 291. # +###################################################################### + +# The most useful windows datatypes +from ctypes import * + +BYTE = c_byte +WORD = c_ushort +DWORD = c_ulong + +WCHAR = c_wchar +UINT = c_uint +INT = c_int + +DOUBLE = c_double +FLOAT = c_float + +BOOLEAN = BYTE +BOOL = c_long + +from ctypes import _SimpleCData +class VARIANT_BOOL(_SimpleCData): + _type_ = "v" + def __repr__(self): + return "%s(%r)" % (self.__class__.__name__, self.value) + +ULONG = c_ulong +LONG = c_long + +USHORT = c_ushort +SHORT = c_short + +# in the windows header files, these are structures. +_LARGE_INTEGER = LARGE_INTEGER = c_longlong +_ULARGE_INTEGER = ULARGE_INTEGER = c_ulonglong + +LPCOLESTR = LPOLESTR = OLESTR = c_wchar_p +LPCWSTR = LPWSTR = c_wchar_p +LPCSTR = LPSTR = c_char_p +LPCVOID = LPVOID = c_void_p + +# WPARAM is defined as UINT_PTR (unsigned type) +# LPARAM is defined as LONG_PTR (signed type) +if sizeof(c_long) == sizeof(c_void_p): + WPARAM = c_ulong + LPARAM = c_long +elif sizeof(c_longlong) == sizeof(c_void_p): + WPARAM = c_ulonglong + LPARAM = c_longlong + +ATOM = WORD +LANGID = WORD + +COLORREF = DWORD +LGRPID = DWORD +LCTYPE = DWORD + +LCID = DWORD + +################################################################ +# HANDLE types +HANDLE = c_void_p # in the header files: void * + +HACCEL = HANDLE +HBITMAP = HANDLE +HBRUSH = HANDLE +HCOLORSPACE = HANDLE +HDC = HANDLE +HDESK = HANDLE +HDWP = HANDLE +HENHMETAFILE = HANDLE +HFONT = HANDLE +HGDIOBJ = HANDLE +HGLOBAL = HANDLE +HHOOK = HANDLE +HICON = HANDLE +HINSTANCE = HANDLE +HKEY = HANDLE +HKL = HANDLE +HLOCAL = HANDLE +HMENU = HANDLE +HMETAFILE = HANDLE +HMODULE = HANDLE +HMONITOR = HANDLE +HPALETTE = HANDLE +HPEN = HANDLE +HRGN = HANDLE +HRSRC = HANDLE +HSTR = HANDLE +HTASK = HANDLE +HWINSTA = HANDLE +HWND = HANDLE +SC_HANDLE = HANDLE +SERVICE_STATUS_HANDLE = HANDLE + +################################################################ +# Some important structure definitions + +class RECT(Structure): + _fields_ = [("left", c_long), + ("top", c_long), + ("right", c_long), + ("bottom", c_long)] +tagRECT = _RECTL = RECTL = RECT + +class _SMALL_RECT(Structure): + _fields_ = [('Left', c_short), + ('Top', c_short), + ('Right', c_short), + ('Bottom', c_short)] +SMALL_RECT = _SMALL_RECT + +class _COORD(Structure): + _fields_ = [('X', c_short), + ('Y', c_short)] + +class POINT(Structure): + _fields_ = [("x", c_long), + ("y", c_long)] +tagPOINT = _POINTL = POINTL = POINT + +class SIZE(Structure): + _fields_ = [("cx", c_long), + ("cy", c_long)] +tagSIZE = SIZEL = SIZE + +def RGB(red, green, blue): + return red + (green << 8) + (blue << 16) + +class FILETIME(Structure): + _fields_ = [("dwLowDateTime", DWORD), + ("dwHighDateTime", DWORD)] +_FILETIME = FILETIME + +class MSG(Structure): + _fields_ = [("hWnd", HWND), + ("message", c_uint), + ("wParam", WPARAM), + ("lParam", LPARAM), + ("time", DWORD), + ("pt", POINT)] +tagMSG = MSG +MAX_PATH = 260 + +class WIN32_FIND_DATAA(Structure): + _fields_ = [("dwFileAttributes", DWORD), + ("ftCreationTime", FILETIME), + ("ftLastAccessTime", FILETIME), + ("ftLastWriteTime", FILETIME), + ("nFileSizeHigh", DWORD), + ("nFileSizeLow", DWORD), + ("dwReserved0", DWORD), + ("dwReserved1", DWORD), + ("cFileName", c_char * MAX_PATH), + ("cAlternateFileName", c_char * 14)] + +class WIN32_FIND_DATAW(Structure): + _fields_ = [("dwFileAttributes", DWORD), + ("ftCreationTime", FILETIME), + ("ftLastAccessTime", FILETIME), + ("ftLastWriteTime", FILETIME), + ("nFileSizeHigh", DWORD), + ("nFileSizeLow", DWORD), + ("dwReserved0", DWORD), + ("dwReserved1", DWORD), + ("cFileName", c_wchar * MAX_PATH), + ("cAlternateFileName", c_wchar * 14)] + +__all__ = ['ATOM', 'BOOL', 'BOOLEAN', 'BYTE', 'COLORREF', 'DOUBLE', 'DWORD', + 'FILETIME', 'FLOAT', 'HACCEL', 'HANDLE', 'HBITMAP', 'HBRUSH', + 'HCOLORSPACE', 'HDC', 'HDESK', 'HDWP', 'HENHMETAFILE', 'HFONT', + 'HGDIOBJ', 'HGLOBAL', 'HHOOK', 'HICON', 'HINSTANCE', 'HKEY', + 'HKL', 'HLOCAL', 'HMENU', 'HMETAFILE', 'HMODULE', 'HMONITOR', + 'HPALETTE', 'HPEN', 'HRGN', 'HRSRC', 'HSTR', 'HTASK', 'HWINSTA', + 'HWND', 'INT', 'LANGID', 'LARGE_INTEGER', 'LCID', 'LCTYPE', + 'LGRPID', 'LONG', 'LPARAM', 'LPCOLESTR', 'LPCSTR', 'LPCVOID', + 'LPCWSTR', 'LPOLESTR', 'LPSTR', 'LPVOID', 'LPWSTR', 'MAX_PATH', + 'MSG', 'OLESTR', 'POINT', 'POINTL', 'RECT', 'RECTL', 'RGB', + 'SC_HANDLE', 'SERVICE_STATUS_HANDLE', 'SHORT', 'SIZE', 'SIZEL', + 'SMALL_RECT', 'UINT', 'ULARGE_INTEGER', 'ULONG', 'USHORT', + 'VARIANT_BOOL', 'WCHAR', 'WIN32_FIND_DATAA', 'WIN32_FIND_DATAW', + 'WORD', 'WPARAM', '_COORD', '_FILETIME', '_LARGE_INTEGER', + '_POINTL', '_RECTL', '_SMALL_RECT', '_ULARGE_INTEGER', 'tagMSG', + 'tagPOINT', 'tagRECT', 'tagSIZE'] diff --git a/PythonHome/Lib/ctypes/wintypes.pyc b/PythonHome/Lib/ctypes/wintypes.pyc deleted file mode 100644 index e4e184ba5d99339308bc2ed04d7f7192f915e697..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5890 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 diff --git a/PythonHome/Lib/curses/ascii.py b/PythonHome/Lib/curses/ascii.py new file mode 100644 index 0000000000..800fd8b4b7 --- /dev/null +++ b/PythonHome/Lib/curses/ascii.py @@ -0,0 +1,99 @@ +"""Constants and membership tests for ASCII characters""" + +NUL = 0x00 # ^@ +SOH = 0x01 # ^A +STX = 0x02 # ^B +ETX = 0x03 # ^C +EOT = 0x04 # ^D +ENQ = 0x05 # ^E +ACK = 0x06 # ^F +BEL = 0x07 # ^G +BS = 0x08 # ^H +TAB = 0x09 # ^I +HT = 0x09 # ^I +LF = 0x0a # ^J +NL = 0x0a # ^J +VT = 0x0b # ^K +FF = 0x0c # ^L +CR = 0x0d # ^M +SO = 0x0e # ^N +SI = 0x0f # ^O +DLE = 0x10 # ^P +DC1 = 0x11 # ^Q +DC2 = 0x12 # ^R +DC3 = 0x13 # ^S +DC4 = 0x14 # ^T +NAK = 0x15 # ^U +SYN = 0x16 # ^V +ETB = 0x17 # ^W +CAN = 0x18 # ^X +EM = 0x19 # ^Y +SUB = 0x1a # ^Z +ESC = 0x1b # ^[ +FS = 0x1c # ^\ +GS = 0x1d # ^] +RS = 0x1e # ^^ +US = 0x1f # ^_ +SP = 0x20 # space +DEL = 0x7f # delete + +controlnames = [ +"NUL", "SOH", "STX", "ETX", "EOT", "ENQ", "ACK", "BEL", +"BS", "HT", "LF", "VT", "FF", "CR", "SO", "SI", +"DLE", "DC1", "DC2", "DC3", "DC4", "NAK", "SYN", "ETB", +"CAN", "EM", "SUB", "ESC", "FS", "GS", "RS", "US", +"SP" +] + +def _ctoi(c): + if type(c) == type(""): + return ord(c) + else: + return c + +def isalnum(c): return isalpha(c) or isdigit(c) +def isalpha(c): return isupper(c) or islower(c) +def isascii(c): return _ctoi(c) <= 127 # ? +def isblank(c): return _ctoi(c) in (8,32) +def iscntrl(c): return _ctoi(c) <= 31 +def isdigit(c): return _ctoi(c) >= 48 and _ctoi(c) <= 57 +def isgraph(c): return _ctoi(c) >= 33 and _ctoi(c) <= 126 +def islower(c): return _ctoi(c) >= 97 and _ctoi(c) <= 122 +def isprint(c): return _ctoi(c) >= 32 and _ctoi(c) <= 126 +def ispunct(c): return _ctoi(c) != 32 and not isalnum(c) +def isspace(c): return _ctoi(c) in (9, 10, 11, 12, 13, 32) +def isupper(c): return _ctoi(c) >= 65 and _ctoi(c) <= 90 +def isxdigit(c): return isdigit(c) or \ + (_ctoi(c) >= 65 and _ctoi(c) <= 70) or (_ctoi(c) >= 97 and _ctoi(c) <= 102) +def isctrl(c): return _ctoi(c) < 32 +def ismeta(c): return _ctoi(c) > 127 + +def ascii(c): + if type(c) == type(""): + return chr(_ctoi(c) & 0x7f) + else: + return _ctoi(c) & 0x7f + +def ctrl(c): + if type(c) == type(""): + return chr(_ctoi(c) & 0x1f) + else: + return _ctoi(c) & 0x1f + +def alt(c): + if type(c) == type(""): + return chr(_ctoi(c) | 0x80) + else: + return _ctoi(c) | 0x80 + +def unctrl(c): + bits = _ctoi(c) + if bits == 0x7f: + rep = "^?" + elif isprint(bits & 0x7f): + rep = chr(bits & 0x7f) + else: + rep = "^" + chr(((bits & 0x7f) | 0x20) + 0x20) + if bits & 0x80: + return "!" + rep + return rep diff --git a/PythonHome/Lib/curses/ascii.pyc b/PythonHome/Lib/curses/ascii.pyc deleted file mode 100644 index f1040e365166628405b75ce29c9cf55e95b9f27f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4775 zcmcIn30D+H5dLNt5D-sLP*E4-vEFBHqp%C85m)WOtDjG@Zmlv;*xffXlYkRJFR$Ts+GkY4y+NFRJ3q#wTDa64o>{D9#O$N>CK$PV~jke%?m zA-mxBKz76Lh3tVJgzSYMf(*j%gABp%hwOtNhU|wQfegbRfQ-N&gdBiB1UU#l3ONLS z7%~cf1acVuDC7uy0df?63{rqU1{s6@0CEieI79`-6OfaTQ;;I$G~^8AEaV*IJmdo8 zBIFX}GUN*6D&!jEL&!&vk0GBxK81V+`5bZ`@&)7u(?J0>WHFHKM;cTG?}GbSjjdnPEiiV4c_z6r|nfeFg?p$W>_ znV`%=6O{j~2|9~MCg@xqo1im#VuH@=DZ=72I>J?ja7%6F|TP0gg7Un#Wa_N+BC)7CuB?xwT5va`JaOgW;LT#>%ma4$@Qo;(s<#s^|c?jo?K=hu3yC*KjKt2O3Izmk3ZLIowax`He)(Y^wTETv|Z+PTy4!?-y%{~lKOrV zq#UE%7hA-ppyO=C61C!}k=|IJ6i=^JUX(|3bUEw|w1aWBow&PfJ2?ip4ej#QQlpmM zT*HU4&;s!4J+&>{<=oJf^$+ucJ}%nHzwUW&uWT+FB&}+#KCY^^Vh2pC#h+~ouqob-f2H7(1sD=nzTHMe3ew%n1WRdy7(F&!v7uX*n* za8s(y#~WEWdW0R_w^ZolRzu6V)&DdDJ7GIBa369m8#w8iK+x>>wvc`4@9SS$v;M!R zy5i>9bA;+b8oq-(A8~SJKKojs<2*lV!mWk3ZXV6QwSvvz#~d0rEg)Dw{U@F@m+IW} z6|IHyD|)31CB26A?O}b)F}pDy$E@9d$YD5C2#bvD74tXS)GuyY-u}Y2YxE0wanFur zi$Mdriv-#;>pQNJRRAxeG_eXGuD6QX`LAg|_Z5$uc)==8)^`X7^xqfk4hD0hL4VL2 zREo^8ETNd2lV)vhj-eCIB8eS%W+pDBqpv%T>NqRMsAYs^CrXY-k7KE61yW_kvEp>B zI2|ia$BNUj;&conjuodPBR5DGBCvpQtUw$qPREMVvEpiF-=_x1FtmEZZ# KX>U%S>;Eq-TgKG@ diff --git a/PythonHome/Lib/curses/has_key.py b/PythonHome/Lib/curses/has_key.py new file mode 100644 index 0000000000..1dd5a3bd4a --- /dev/null +++ b/PythonHome/Lib/curses/has_key.py @@ -0,0 +1,192 @@ + +# +# Emulation of has_key() function for platforms that don't use ncurses +# + +import _curses + +# Table mapping curses keys to the terminfo capability name + +_capability_names = { + _curses.KEY_A1: 'ka1', + _curses.KEY_A3: 'ka3', + _curses.KEY_B2: 'kb2', + _curses.KEY_BACKSPACE: 'kbs', + _curses.KEY_BEG: 'kbeg', + _curses.KEY_BTAB: 'kcbt', + _curses.KEY_C1: 'kc1', + _curses.KEY_C3: 'kc3', + _curses.KEY_CANCEL: 'kcan', + _curses.KEY_CATAB: 'ktbc', + _curses.KEY_CLEAR: 'kclr', + _curses.KEY_CLOSE: 'kclo', + _curses.KEY_COMMAND: 'kcmd', + _curses.KEY_COPY: 'kcpy', + _curses.KEY_CREATE: 'kcrt', + _curses.KEY_CTAB: 'kctab', + _curses.KEY_DC: 'kdch1', + _curses.KEY_DL: 'kdl1', + _curses.KEY_DOWN: 'kcud1', + _curses.KEY_EIC: 'krmir', + _curses.KEY_END: 'kend', + _curses.KEY_ENTER: 'kent', + _curses.KEY_EOL: 'kel', + _curses.KEY_EOS: 'ked', + _curses.KEY_EXIT: 'kext', + _curses.KEY_F0: 'kf0', + _curses.KEY_F1: 'kf1', + _curses.KEY_F10: 'kf10', + _curses.KEY_F11: 'kf11', + _curses.KEY_F12: 'kf12', + _curses.KEY_F13: 'kf13', + _curses.KEY_F14: 'kf14', + _curses.KEY_F15: 'kf15', + _curses.KEY_F16: 'kf16', + _curses.KEY_F17: 'kf17', + _curses.KEY_F18: 'kf18', + _curses.KEY_F19: 'kf19', + _curses.KEY_F2: 'kf2', + _curses.KEY_F20: 'kf20', + _curses.KEY_F21: 'kf21', + _curses.KEY_F22: 'kf22', + _curses.KEY_F23: 'kf23', + _curses.KEY_F24: 'kf24', + _curses.KEY_F25: 'kf25', + _curses.KEY_F26: 'kf26', + _curses.KEY_F27: 'kf27', + _curses.KEY_F28: 'kf28', + _curses.KEY_F29: 'kf29', + _curses.KEY_F3: 'kf3', + _curses.KEY_F30: 'kf30', + _curses.KEY_F31: 'kf31', + _curses.KEY_F32: 'kf32', + _curses.KEY_F33: 'kf33', + _curses.KEY_F34: 'kf34', + _curses.KEY_F35: 'kf35', + _curses.KEY_F36: 'kf36', + _curses.KEY_F37: 'kf37', + _curses.KEY_F38: 'kf38', + _curses.KEY_F39: 'kf39', + _curses.KEY_F4: 'kf4', + _curses.KEY_F40: 'kf40', + _curses.KEY_F41: 'kf41', + _curses.KEY_F42: 'kf42', + _curses.KEY_F43: 'kf43', + _curses.KEY_F44: 'kf44', + _curses.KEY_F45: 'kf45', + _curses.KEY_F46: 'kf46', + _curses.KEY_F47: 'kf47', + _curses.KEY_F48: 'kf48', + _curses.KEY_F49: 'kf49', + _curses.KEY_F5: 'kf5', + _curses.KEY_F50: 'kf50', + _curses.KEY_F51: 'kf51', + _curses.KEY_F52: 'kf52', + _curses.KEY_F53: 'kf53', + _curses.KEY_F54: 'kf54', + _curses.KEY_F55: 'kf55', + _curses.KEY_F56: 'kf56', + _curses.KEY_F57: 'kf57', + _curses.KEY_F58: 'kf58', + _curses.KEY_F59: 'kf59', + _curses.KEY_F6: 'kf6', + _curses.KEY_F60: 'kf60', + _curses.KEY_F61: 'kf61', + _curses.KEY_F62: 'kf62', + _curses.KEY_F63: 'kf63', + _curses.KEY_F7: 'kf7', + _curses.KEY_F8: 'kf8', + _curses.KEY_F9: 'kf9', + _curses.KEY_FIND: 'kfnd', + _curses.KEY_HELP: 'khlp', + _curses.KEY_HOME: 'khome', + _curses.KEY_IC: 'kich1', + _curses.KEY_IL: 'kil1', + _curses.KEY_LEFT: 'kcub1', + _curses.KEY_LL: 'kll', + _curses.KEY_MARK: 'kmrk', + _curses.KEY_MESSAGE: 'kmsg', + _curses.KEY_MOVE: 'kmov', + _curses.KEY_NEXT: 'knxt', + _curses.KEY_NPAGE: 'knp', + _curses.KEY_OPEN: 'kopn', + _curses.KEY_OPTIONS: 'kopt', + _curses.KEY_PPAGE: 'kpp', + _curses.KEY_PREVIOUS: 'kprv', + _curses.KEY_PRINT: 'kprt', + _curses.KEY_REDO: 'krdo', + _curses.KEY_REFERENCE: 'kref', + _curses.KEY_REFRESH: 'krfr', + _curses.KEY_REPLACE: 'krpl', + _curses.KEY_RESTART: 'krst', + _curses.KEY_RESUME: 'kres', + _curses.KEY_RIGHT: 'kcuf1', + _curses.KEY_SAVE: 'ksav', + _curses.KEY_SBEG: 'kBEG', + _curses.KEY_SCANCEL: 'kCAN', + _curses.KEY_SCOMMAND: 'kCMD', + _curses.KEY_SCOPY: 'kCPY', + _curses.KEY_SCREATE: 'kCRT', + _curses.KEY_SDC: 'kDC', + _curses.KEY_SDL: 'kDL', + _curses.KEY_SELECT: 'kslt', + _curses.KEY_SEND: 'kEND', + _curses.KEY_SEOL: 'kEOL', + _curses.KEY_SEXIT: 'kEXT', + _curses.KEY_SF: 'kind', + _curses.KEY_SFIND: 'kFND', + _curses.KEY_SHELP: 'kHLP', + _curses.KEY_SHOME: 'kHOM', + _curses.KEY_SIC: 'kIC', + _curses.KEY_SLEFT: 'kLFT', + _curses.KEY_SMESSAGE: 'kMSG', + _curses.KEY_SMOVE: 'kMOV', + _curses.KEY_SNEXT: 'kNXT', + _curses.KEY_SOPTIONS: 'kOPT', + _curses.KEY_SPREVIOUS: 'kPRV', + _curses.KEY_SPRINT: 'kPRT', + _curses.KEY_SR: 'kri', + _curses.KEY_SREDO: 'kRDO', + _curses.KEY_SREPLACE: 'kRPL', + _curses.KEY_SRIGHT: 'kRIT', + _curses.KEY_SRSUME: 'kRES', + _curses.KEY_SSAVE: 'kSAV', + _curses.KEY_SSUSPEND: 'kSPD', + _curses.KEY_STAB: 'khts', + _curses.KEY_SUNDO: 'kUND', + _curses.KEY_SUSPEND: 'kspd', + _curses.KEY_UNDO: 'kund', + _curses.KEY_UP: 'kcuu1' + } + +def has_key(ch): + if isinstance(ch, str): + ch = ord(ch) + + # Figure out the correct capability name for the keycode. + capability_name = _capability_names.get(ch) + if capability_name is None: + return False + + #Check the current terminal description for that capability; + #if present, return true, else return false. + if _curses.tigetstr( capability_name ): + return True + else: + return False + +if __name__ == '__main__': + # Compare the output of this implementation and the ncurses has_key, + # on platforms where has_key is already available + try: + L = [] + _curses.initscr() + for key in _capability_names.keys(): + system = key in _curses + python = has_key(key) + if system != python: + L.append( 'Mismatch for key %s, system=%i, Python=%i' + % (_curses.keyname( key ), system, python) ) + finally: + _curses.endwin() + for i in L: print i diff --git a/PythonHome/Lib/curses/has_key.pyc b/PythonHome/Lib/curses/has_key.pyc deleted file mode 100644 index 09d506b9c4a3200900977b5daa33212b8822bdb3..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5907 zcmeI#`F_(@8V2CwBm@Xa1Eq!1HC<>!ODW#6v_NqjIZ1JB*Gfo8p~kUg;=~)40)#>r zp!>c+p=CN#<`(A8<^pD3y*i&H=8yT!1q?~-M`!zvbaeEI-hU1a{A207SyB35KfX`m z&%Os$@f%SMrB;-x-&WNgWhu2DQDfC!st4+$dZBGpAJk86gSJ!s&<<)lw3FHa4NyCw zUDNcg&wCKgZ5F6L;IK{Q_wV(h74*N%1{P0LuH^@Y6hC4W}$beIp`Gi4wR)%LGx4=%2D%Bp2|T5Di6I& z6`&&ZE@VU4PB%z?O9Ox3Y30U>Qm@*>NDsI>T~Ez>I>*A>PzTr z>MQ6Q>TBp*>Ko`g>Raf0>O1HM>U-!%>Idj2>PP5j>L=(I>SyRS^$T=|x~;}m?x^ao z>J}dGzbfmls@_!_J*s=V|LUf?fWmuh_nW$@ROAY7vO8-1clTiWTtTheR~CMi+UQp+ ze^C|&xUX(T)XE>q!r>okqgQng^jr7T`d?Mm8|iPljn|;otM;Ko9 zPcPhFg|5@*cBz#I%6gz?W-s38Us`T4BblSWAw|{yg?~Ax7u+aE^>^I+UXAH*+v#)b zSFH;kDyxoHQ_(#taa~bvd2m)Mx}?z+v^APljn0-v*KxMF0V+;;)l;>y7WFEtji|2N ztZH?ebv>xn(qmaIJtM2(&CHUDE4rd~)T^lJacj||UVvKEFNsNsKAl=LAtgz{m|$Em zA(+$=WSE#lh)IN)UnLP@5+NoLViF-H5n>V{CK04}Tq49JLR=!m{WcOIE)n7qAubW( z5+N=Tq*Fp7BqTyYA|xb2!fz}Q5)vUH5fTz1ArYi)QX(WJLQ*0mB|=gnB>i3zAt@1( z5+NxOq{)~>7?TKN5@Af=>a}sbb`$!0QZK69U~7$zcN?y?o0g}#e~;FKdvsOrh(^O3 zpxNEfu=VC?wl8@lEx9#Y9j~C>(YvSJ(Kl^J*L1qNPX}9td$C*9+o@~SbV;qN(b2KH zwlubE*+X*s+hslClriIVOQ&)g^V1rIGaAJO@3Ks%^>@~*up2spk<)#Qysk2q7rZug zxr7;MGn*}VRkQhdZ@js*SCGx*3KyQKa}` z?}v_@&DK}XdIO$aE8C?FYwHM}@@^b`_yDwb<3mM;Bg4JJk-~jJ{U+1-rJR2b z1~!s=vE8BEEh+OcatlT=sKFlfTjfoEC}SDBL_%ba28{a6Gsv3KHG{+%I2Lj|}n*`-Y}~R2{SlO#ulz zC=X2`)D@ZAZ-V3>`eC&E5n%j z0V+@(2~GFq#2@~lr=6JzDtHh0 z&3F?8NA6wV$Hi^n*KqOulaW>StGUen5!cyoEUPJNV)_dx*BB-43d+4@2D!!LYWhPJ z4R5jhj^1(vhYzh4?nEq)-`QL=ag&9vS2(4acq_^W%kdvgSt-+7EEMnJRxJLB4_^Ed zUqwnKyd5d!<(_)0?${Om#%dv{yRRuo@;pZ`$&+|{K$0iRosRqeJ@@LPq5E>fVw7F3 zw>Wft6m{PF2=!lIO5D5RShHQ-Y*;7UncK6N-C$pDWZ?fl|I-y1>fO0}u(vnTkJfwf Q9_Rk-j2!G4hzzNJ1JJUpZvX%Q diff --git a/PythonHome/Lib/curses/panel.py b/PythonHome/Lib/curses/panel.py new file mode 100644 index 0000000000..aacca85151 --- /dev/null +++ b/PythonHome/Lib/curses/panel.py @@ -0,0 +1,8 @@ +"""curses.panel + +Module for using panels with curses. +""" + +__revision__ = "$Id$" + +from _curses_panel import * diff --git a/PythonHome/Lib/curses/panel.pyc b/PythonHome/Lib/curses/panel.pyc deleted file mode 100644 index 84e334c45dfb0fe98acad123dd475fc26e67a5bd..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 262 zcmZSn%*(YUJRvxl0ScIav;z 0: + self.win.move(y, x-1) + elif y == 0: + pass + elif self.stripspaces: + self.win.move(y-1, self._end_of_line(y-1)) + else: + self.win.move(y-1, self.maxx) + if ch in (curses.ascii.BS, curses.KEY_BACKSPACE): + self.win.delch() + elif ch == curses.ascii.EOT: # ^d + self.win.delch() + elif ch == curses.ascii.ENQ: # ^e + if self.stripspaces: + self.win.move(y, self._end_of_line(y)) + else: + self.win.move(y, self.maxx) + elif ch in (curses.ascii.ACK, curses.KEY_RIGHT): # ^f + if x < self.maxx: + self.win.move(y, x+1) + elif y == self.maxy: + pass + else: + self.win.move(y+1, 0) + elif ch == curses.ascii.BEL: # ^g + return 0 + elif ch == curses.ascii.NL: # ^j + if self.maxy == 0: + return 0 + elif y < self.maxy: + self.win.move(y+1, 0) + elif ch == curses.ascii.VT: # ^k + if x == 0 and self._end_of_line(y) == 0: + self.win.deleteln() + else: + # first undo the effect of self._end_of_line + self.win.move(y, x) + self.win.clrtoeol() + elif ch == curses.ascii.FF: # ^l + self.win.refresh() + elif ch in (curses.ascii.SO, curses.KEY_DOWN): # ^n + if y < self.maxy: + self.win.move(y+1, x) + if x > self._end_of_line(y+1): + self.win.move(y+1, self._end_of_line(y+1)) + elif ch == curses.ascii.SI: # ^o + self.win.insertln() + elif ch in (curses.ascii.DLE, curses.KEY_UP): # ^p + if y > 0: + self.win.move(y-1, x) + if x > self._end_of_line(y-1): + self.win.move(y-1, self._end_of_line(y-1)) + return 1 + + def gather(self): + "Collect and return the contents of the window." + result = "" + for y in range(self.maxy+1): + self.win.move(y, 0) + stop = self._end_of_line(y) + if stop == 0 and self.stripspaces: + continue + for x in range(self.maxx+1): + if self.stripspaces and x > stop: + break + result = result + chr(curses.ascii.ascii(self.win.inch(y, x))) + if self.maxy > 0: + result = result + "\n" + return result + + def edit(self, validate=None): + "Edit in the widget window and collect the results." + while 1: + ch = self.win.getch() + if validate: + ch = validate(ch) + if not ch: + continue + if not self.do_command(ch): + break + self.win.refresh() + return self.gather() + +if __name__ == '__main__': + def test_editbox(stdscr): + ncols, nlines = 9, 4 + uly, ulx = 15, 20 + stdscr.addstr(uly-2, ulx, "Use Ctrl-G to end editing.") + win = curses.newwin(nlines, ncols, uly, ulx) + rectangle(stdscr, uly-1, ulx-1, uly + nlines, ulx + ncols) + stdscr.refresh() + return Textbox(win).edit() + + str = curses.wrapper(test_editbox) + print 'Contents of text box:', repr(str) diff --git a/PythonHome/Lib/curses/textpad.pyc b/PythonHome/Lib/curses/textpad.pyc deleted file mode 100644 index 6c771eda8d19681e8598a95b4338313923f13785..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6719 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 NJ|rBejc&19{04-6J0bu8 diff --git a/PythonHome/Lib/dbhash.py b/PythonHome/Lib/dbhash.py new file mode 100644 index 0000000000..a5d5375ba9 --- /dev/null +++ b/PythonHome/Lib/dbhash.py @@ -0,0 +1,18 @@ +"""Provide a (g)dbm-compatible interface to bsddb.hashopen.""" + +import sys +import warnings +warnings.warnpy3k("in 3.x, the dbhash module has been removed", stacklevel=2) +try: + import bsddb +except ImportError: + # prevent a second import of this module from spuriously succeeding + del sys.modules[__name__] + raise + +__all__ = ["error","open"] + +error = bsddb.error # Exported for anydbm + +def open(file, flag = 'r', mode=0666): + return bsddb.hashopen(file, flag, mode) diff --git a/PythonHome/Lib/dbhash.pyc b/PythonHome/Lib/dbhash.pyc deleted file mode 100644 index 0ab5b9558e3a3af2a4e021b2915ac279e736ab81..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 688 zcmZ`#%Wl*#6g_q_uP_xwl~^J#1A=V2VF48q>H-N>Xu2qhDupDzo$*W_qu2}`sVmBg z??L<+9{|@0r7JAo<{l=gh)eNG*1xH2%8994!$RW^%yk4>#sl~@KKMUCs?xH6cl1TLpp<= zLNiAA#^;ewejY#Yo?bG1=-Qppq;eH6pX#E1QMUCqcc!RFnZ{9fm6xPks|u@ik*spN zYPZxR<~NTs`-~+_qmGm7=gO@}>B7HIb*n$K0CQCkHL9b!-H~>YPwVn>Q_+qpBYEq5 zi>T|`&V|gpxD!k|^OKh{VCuu)z2&e+3=UWe+yFO>61M?YZpw#umSZo| z=eRNz4W!DKJz>8T^EG;~51A#G?@e(z)RS!Y3$Of$!+HYIchF6kW|?lwEOTDo?rop* zOWrl6S>A89`{T{R*Wi5T-_=_#_p~qCOAPHAUT0a8*Ti~*c3xFkw(!OE4(?6<*J*Fy d)gXD|KibC(V>uUdaU=q9C=O&KCUP!k@()1Aj$;4- diff --git a/PythonHome/Lib/decimal.py b/PythonHome/Lib/decimal.py new file mode 100644 index 0000000000..04bf5c2660 --- /dev/null +++ b/PythonHome/Lib/decimal.py @@ -0,0 +1,6198 @@ +# Copyright (c) 2004 Python Software Foundation. +# All rights reserved. + +# Written by Eric Price +# and Facundo Batista +# and Raymond Hettinger +# and Aahz +# 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: + + http://speleotrove.com/decimal/decarith.html + +and IEEE standard 854-1987: + + http://en.wikipedia.org/wiki/IEEE_854-1987 + +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: + 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(): + op = _WorkRep(self.to_integral_value()) + # to make computation feasible for Decimals with large + # exponent, we use the fact that hash(n) == hash(m) for + # any two nonzero integers n and m such that (i) n and m + # have the same sign, and (ii) n is congruent to m modulo + # 2**64-1. So we can replace hash((-1)**s*c*10**e) with + # hash((-1)**s*c*pow(10, e, 2**64-1). + return hash((-1)**op.sign*op.int*pow(10, op.exp, 2**64-1)) + # 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 context is None: + context = getcontext() + + if not self and context.rounding != ROUND_FLOOR: + # -Decimal('0') is Decimal('0'), not Decimal('-0'), except + # in ROUND_FLOOR rounding mode. + ans = self.copy_abs() + else: + ans = self.copy_negate() + + 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 context is None: + context = getcontext() + + if not self and context.rounding != ROUND_FLOOR: + # + (-0) = 0, except in ROUND_FLOOR rounding mode. + ans = self.copy_abs() + else: + ans = Decimal(self) + + 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 = rounding_method(self, 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) + + # 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) + + _pick_rounding_function = dict( + ROUND_DOWN = _round_down, + ROUND_UP = _round_up, + ROUND_HALF_UP = _round_half_up, + ROUND_HALF_DOWN = _round_half_down, + ROUND_HALF_EVEN = _round_half_even, + ROUND_CEILING = _round_ceiling, + ROUND_FLOOR = _round_floor, + ROUND_05UP = _round_05up, + ) + + 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 abs(y) = yc*10**ye, with xc + # and yc positive integers not divisible by 10. + + # 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. Express y as a rational number 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 y 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 + + # We now have: + # + # x = 2**e * 10**xe, e > 0, and y < 0. + # + # The exact result is: + # + # x**y = 5**(-e*y) * 10**(e*y + xe*y) + # + # provided that both e*y and xe*y are integers. Note that if + # 5**(-e*y) >= 10**p, then the result can't be expressed + # exactly with p digits of precision. + # + # Using the above, we can guard against large values of ye. + # 93/65 is an upper bound for log(10)/log(5), so if + # + # ye >= len(str(93*p//65)) + # + # then + # + # -e*y >= -y >= 10**ye > 93*p/65 > p*log(10)/log(5), + # + # so 5**(-e*y) >= 10**p, and the coefficient of the result + # can't be expressed in p digits. + + # emax >= largest e such that 5**e < 10**p. + emax = p*93//65 + if ye >= len(str(emax)): + return None + + # Find -e*y and -xe*y; both must be integers + e = _decimal_lshift_exact(e * yc, ye) + xe = _decimal_lshift_exact(xe * yc, ye) + if e is None or xe is None: + return None + + if e > emax: + 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 + + # Guard against large values of ye, using the same logic as in + # the 'xc is a power of 2' branch. 10/3 is an upper bound for + # log(10)/log(2). + emax = p*10//3 + if ye >= len(str(emax)): + return None + + e = _decimal_lshift_exact(e * yc, ye) + xe = _decimal_lshift_exact(xe * yc, ye) + if e is None or xe is None: + return None + + if e > emax: + 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 = self._pick_rounding_function[rounding] + changed = this_function(self, 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) + +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 ####################################################### + +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 _decimal_lshift_exact(n, e): + """ Given integers n and e, return n * 10**e if it's an integer, else None. + + The computation is designed to avoid computing large powers of 10 + unnecessarily. + + >>> _decimal_lshift_exact(3, 4) + 30000 + >>> _decimal_lshift_exact(300, -999999999) # returns None + + """ + if n == 0: + return 0 + elif e >= 0: + return n * 10**e + else: + # val_n = largest power of 10 dividing n. + str_n = str(abs(n)) + val_n = len(str_n) - len(str_n.rstrip('0')) + return None if val_n < -e else n // 10**-e + +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)< M + T = -int(-10*len(str(M))//(3*L)) + y = _div_nearest(x, T) + Mshift = long(M)<= 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[-+])? # an optional sign, followed by either... + ( + (?=\d|\.\d) # ...a number (with at least one digit) + (?P\d*) # having a (possibly empty) integer part + (\.(?P\d*))? # followed by an optional fractional part + (E(?P[-+]?\d+))? # followed by an optional exponent, or... + | + Inf(inity)? # ...an infinity, or... + | + (?Ps)? # ...an (optionally signaling) + NaN # NaN + (?P\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.)? + (?P[<>=^]) +)? +(?P[-+ ])? +(?P0)? +(?P(?!0)\d+)? +(?P,)? +(?:\.(?P0|(?!0)\d+))? +(?P[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 alignment 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/PythonHome/Lib/decimal.pyc b/PythonHome/Lib/decimal.pyc deleted file mode 100644 index 837ea3e90796d653eacd83211480205aa35d28f3..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 167489 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 diff --git a/PythonHome/Lib/difflib.py b/PythonHome/Lib/difflib.py new file mode 100644 index 0000000000..3880d8472e --- /dev/null +++ b/PythonHome/Lib/difflib.py @@ -0,0 +1,2057 @@ +""" +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 "

" lines in HTML files). That may be + because this is the only method of the 3 that has a *concept* of + "junk" . + + 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 = map(Match._make, non_adjacent) + return 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 up to 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 . + +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 iterator 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 = """ + + + + + + + + + + + + %(table)s%(legend)s + + +""" + +_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 = """ + + + + %(header_row)s + +%(data_rows)s +
""" + +_legend = """ + + + + +
Legends
+ + + + +
Colors
 Added 
Changed
Deleted
+ + + + +
Links
(f)irst change
(n)ext change
(t)op
""" + +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 '%s%s' \ + % (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] = '
n' % ( + 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 = [' No Differences Found '] + tolist = fromlist + else: + fromlist = tolist = [' Empty File '] + # if not a change on first line, drop a link + if not flaglist[0]: + next_href[0] = 'f' % toprefix + # redo the last link to link to the top + next_href[last] = 't' % (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 + # markup + 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 = ' %s%s' + \ + '%s%s\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(' \n \n') + else: + s.append( fmt % (next_id[i],next_href[i],fromlist[i], + next_href[i],tolist[i])) + if fromdesc or todesc: + header_row = '%s%s%s%s' % ( + '
', + '%s' % fromdesc, + '
', + '%s' % 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+',''). \ + replace('\0-',''). \ + replace('\0^',''). \ + replace('\1',''). \ + 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/PythonHome/Lib/difflib.pyc b/PythonHome/Lib/difflib.pyc deleted file mode 100644 index 25ef4fc5de288f8b8624f9556b34ba13b7fc91eb..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 61139 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�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 Ov%haB9vawL`hNiZ(ih?Y diff --git a/PythonHome/Lib/dircache.py b/PythonHome/Lib/dircache.py new file mode 100644 index 0000000000..7e4f0b508a --- /dev/null +++ b/PythonHome/Lib/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/PythonHome/Lib/dircache.pyc b/PythonHome/Lib/dircache.pyc deleted file mode 100644 index 81bfcd3ba840a58ae20c2d43f95ee12ce7cdc877..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1516 zcmah}QEwAR5T4z$9byt1LTMEtRr`WCBxEY`*c4H24p~WMq@ZO$lM^aNoGi=JsS6@BGP>_H|bBr8<5#b z$_CjD8UwkVOyCD}l;7gqe?t^j8>O95r7mYynabNTHojGL6=LO1!)Q2s0SB9K<`0!` zmT*|*ZCrX6lvbhf(V7HN%~VCer&Vo(svNxQkdKDTfQWe2<%*5c7fodlNgHhip{7q+e> z%)__=xuPoR4Odk8l<>OZ*ayhlVB>lmxTqho0te+jrg1pRIcT^CQ7}9a)RkB^^F?i= zt=rLIcO(v)d^r^QB*JZ&qm$>=s}mHG5Tiv~Fnk9qa0<#wu7HP<-=|96Luv0(Bzi}* zcOvOh(4}12-ygegs22sD56OQ=m`;r5DUs|zPS9^r(pkoPuLPa-=n^^}?8wMp5PSP8 zFQUGKIiM>d;gAnFNz?0G2QXGl+(%8%F^KE7wyJC#CM1SOsvEBEfL*J(8N~o1(f^BW zfA$`u$|r6@ z_zHq#CU(S4u`OJy`{r)UWpR&W1%g^-@;@nN1w z3K2vzsR4ye+)(qFZ;15uWR(+N-j=-G{oR#FBxG!?P zC+UJsCZ;JTll6_}PgcRWRLlyZ>v}RtlaS^ 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 = "" + code = compile(source, fn, "exec") + dis(code) + +if __name__ == "__main__": + _test() diff --git a/PythonHome/Lib/dis.pyc b/PythonHome/Lib/dis.pyc index c71f03d328967dfb3038813a51f4e608749b0e46..7703b4e0eaefd4d6c2d392681c02fe042fa850a7 100644 GIT binary patch delta 468 zcmcbkzsG2UD66pr0|P^On82Uo>#EHUr>N^jDKlKL1{^hOKMVSdQ3oN zNk)F2M}BTrE~-2t8qqsagO delta 116 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 QnX2H9tZAP?Jj9RvKU%^f(EtDd diff --git a/PythonHome/Lib/distutils/ccompiler.py b/PythonHome/Lib/distutils/ccompiler.py new file mode 100644 index 0000000000..4907a0aa5a --- /dev/null +++ b/PythonHome/Lib/distutils/ccompiler.py @@ -0,0 +1,1095 @@ +"""distutils.ccompiler + +Contains CCompiler, an abstract base class that defines the interface +for the Distutils compiler abstraction model.""" + +__revision__ = "$Id$" + +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 +# following import is for backward compatibility +from distutils.sysconfig import customize_compiler + +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'), + + # 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"), + } + +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/PythonHome/Lib/distutils/ccompiler.pyc b/PythonHome/Lib/distutils/ccompiler.pyc deleted file mode 100644 index 74c07b1a93e97253ef498a3f1b6dccc9d8bffe69..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 36549 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 diff --git a/PythonHome/Lib/distutils/command/__init__.py b/PythonHome/Lib/distutils/command/__init__.py new file mode 100644 index 0000000000..20b159f74e --- /dev/null +++ b/PythonHome/Lib/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/PythonHome/Lib/distutils/command/__init__.pyc b/PythonHome/Lib/distutils/command/__init__.pyc deleted file mode 100644 index 29005876628c8f91d003023b83f99725e56ddbcc..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 660 zcmah`%TB{U40Ky4B~S_!IOo8j7kc1=gb+f43m2%w0jY{)w(F%`v3V%#@c1wOj32<8 zK7bR6;>dHlTu0vJndz_-BBy1lckvoH09iTovsZAgjA)Ix%--yMLM@zv$wD_QE7`_Rk&Qy-1*Gtm%Bkr zvbBFi$~7VfABd%SwO)2Bi7*_ZjD|Q62tUD}2)#Z}Mjt%Ov(vLg=1oG+`UI23;uA!1 dz=%UxaoG1onp5S>WjGEW)Y{EQJ diff --git a/PythonHome/Lib/distutils/command/bdist.py b/PythonHome/Lib/distutils/command/bdist.py new file mode 100644 index 0000000000..d7910b14d6 --- /dev/null +++ b/PythonHome/Lib/distutils/command/bdist.py @@ -0,0 +1,146 @@ +"""distutils.command.bdist + +Implements the Distutils 'bdist' command (create a built [binary] +distribution).""" + +__revision__ = "$Id$" + +import os + +from distutils.util import get_platform +from distutils.core import Command +from distutils.errors import DistutilsPlatformError, DistutilsOptionError + + +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)"), + ('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 = ['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',) + + # 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', + 'nt': 'zip', + 'os2': 'zip'} + + # Establish the preferred order (for the --help-formats option). + format_commands = ['rpm', 'gztar', 'bztar', 'ztar', 'tar', + 'wininst', 'zip', 'msi'] + + # And the real information. + format_command = {'rpm': ('bdist_rpm', "RPM distribution"), + '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"), + 'msi': ('bdist_msi', "Microsoft Installer") + } + + + def initialize_options(self): + self.bdist_base = None + self.plat_name = None + self.formats = None + self.dist_dir = None + self.skip_build = 0 + self.group = None + self.owner = None + + 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./dumb", "build/bdist./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" + + 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] + + # passing the owner and group names for tar archiving + if cmd_name == 'bdist_dumb': + sub_cmd.owner = self.owner + sub_cmd.group = self.group + + # 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) diff --git a/PythonHome/Lib/distutils/command/bdist.pyc b/PythonHome/Lib/distutils/command/bdist.pyc deleted file mode 100644 index 0b14c75de2b59cf7635548717b0469e7fdd568e1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5129 zcmb_gO>-N^5$y#)kbp>&u_els>3FS3As81aM{(#xwrs^x>{4RWs#U7!&|+->%n)1> z*oAf$qNtKCR{lc%MJlKKm7IO>56B^vYm)bR78EH{rIKQTJD882o|*2~J#SI{*G%*8 z8-KdpmGZBO?`wG6T@*%S6J;QqftZSzs`M+ei3Zs7U&5wVMqF z?bNJx*wt*_91Qz*VAH~d#f}YcjOD^56<7*O`LNZ^ZM(2xJM4^-ei44%Nz!(Hu+^lV zJn2AtmM*Wl8dke-(_BdYi@)_&fMzj`qGyYE*l!oxSw8T+ljyzfchjm+Y#zno25yzI zzs>V3FHRpF`f|v%bU+QwCF^*u<8gfyFfnY1+8~feB0*2&Q6Tr%q^QVlRc>s(BabTb zFp%9E?ewrBXH8uP>ufB*8w=Z2c^pV^H_u5In-RawqCvL;Ot#;lUm8QQ~lVoUS(JxCg^Fwa0J`)JHU9F@ZuoU(BNB zSBpywxPn%04~I521*O-s)E2LNPp%;BhO|b!WBbDvMZI>~syu<}@^w`)%xzH|#5&F9 zEeMJhE<|nh&gV(z&f&iAlpDIEJ6#kV0B>@Moin__+}<}ERyP~>gtA<|Dt z0u8^S%$oT%<<`sm7Q1In+N4>@PeT;;qq^AYE+nU6VtZF5@8iYAB|F{@g6Ma(6w z%t~~-b&UtVfa0mRZuz)g4v(V95sGT;l}_8)s|C^5aqpol>|mJX$OM>>+isDe1}B87 zHc5MBx;UoIDL@e5D`|UBY8$!_plzHXLJovQ7TQ6_nlMSjo=t6z1Z2YPq;ENlh%$D& zJ?a-%!i#SCSa`TgP*!3=w{vuT7g7h{j#jzVX4Zq2Z{& z4$^l2q=RvzUmtFYy0-MJZZ8?GFmD=n84B49bE_RRk-ca0gJOr(7HwBpSDI+%R+lQc=4pEhubn?ql8>x*Mx*YxE#VMc?F z%Ji`05-dEnsQVEncF=kGSnq4-1-6jO9Q|=9t*N(kMlr*wJbhg5#x0^}BS}rR??QXu zc1ML?9NcNU-?zC!d-LWkb>-pF551`o8u{6MkpWJ={g?A0_hExS*&@E z6{I@fgAC;>NPB_GAhr1(q&8o{wI{gmsBoQ}Li9$7=&~awV}8&rGL&P+X+$^_G=Ux( z!KLC1f>=Yq`)_UAAmfK3S9c>YC=x`MyDT&)yYNx z$K5H}ZID`ktoY^5KGs@1F;;;a!t)T0gVc#o-*<9wPG?N3ni*NZ9mJ(i$;RF9q=pN1 zuPOPr5(EM6aetR_!5Nu9`%Oh4^HsUWxv|dw@Uo+hIj*gqX27hgOML2L4pQK*s!QDp z+9pevif}K@_Cs91%-H39!YReExN@NyKTE^IEPv4{k035ujHu`$3nD5awTbXZaRvq1 zqh?*W(~S8@bb-UXOLTv+LXVEjyxL*A*irqv8Mp{BVN*BCZA`+N_F`rv4^D!jOxq=c z(0N3!0{8d!Kg?a@zBXc$C4W0P0SivpB+XMCP9Jh#xNnNljVfah%G^@-WwRj`)% z%1kgDRD*ND49aS72IC4^I)smcwh7SoJkeb*;dEo`I*IPVqHZsT6%UA#pRIIapsuV+vU?y;U_N~3T0z$4}+Bt@a4{}LgERFTYpI! z=XKG=p36nNy?+oY_e8Vja}nQ|e;7KaS8>EF?2{gAClV(eR=)cj_H?4)iHzz*$!D;v z6J-gkF%46Jh){nn<9ep9F$?p$enMT(U|=oAg$8S^p&G|}RmJfjGo!vmlc8^{>*k=d z_(4N&J5Q&`n8?t_SA)Kcce1Q++v&J3;ybRs_>yWL_VO(%;)_|t>)WTYcUXI$#V079 zk!PXb&Hz4SKhoWAoR|J`&jtAEcN<7-*zZ-Pq6}{afjWlD)l4V=AO zxBvRtuOIiM{xtCZ5Rd&6ibSM~(vz+yi7!b*GGDr=;D1iChK%Nr*!qI} zPUKYNm)%t!;&Eq*C;S^vnA&PmrJ3FB6{As{C%gOXijv7_zuo?HG|tS(wNw#Isk}eiu5-hwXg9dSwV%i&$ z+>}SjElF;>*ByD(U6ABWLIT)I0d5hY!8}1}&`9VcX zB=%bE7wWn3O%erbADff`gFsLV7UD5U;N)EK(l$>Wi6qQ>^S5XDYfE#Ls5Vn+J_ zNty=(lbaHtOM-ry84lZ^lbC)y$*T8)ExT=LW3G)WC$VqeMb8v=ZiFK1t9Gimd=R|Q za^PMs(($%!VbP&6;~id0Z+U3nsr&RMV{0Z!v6JSuiZen5XeWk%@B(NK;(i50+q+ov zN)1fCL3g8SRHt?aYi2scS;vzK_s!$Xx!B7Ffm+lk_Anjq&;=9w5CYf?N~0arzJY(h zQCRKJES0ep8t){SG8mw?T`gkS6!!KJ8oF3-JJsLBQowXlFpjGOJJWwZ&aBzCO)M>* z!BEZu6Z;`Le!>oC(20fpo*kHchK)FY1=Oa&ug=Wbo0KKUD8T&kbCo)PZpTjQz)ph;=^f{uqz_ISTmku}Gv2%?ffHfc2MFIt;Y-63UJ+2G6h&}EYTb}bsaIEvIdxE}j@P)aHCexdw`gIvP}_a-<8=QC zMQSj4Qip^mGwRy~E0dtpJgw3=OJA6%7}H7Yx6x}kBwp)Ff2v_#oi|Yp{}~l%b*Oqi zT$J*CZ9>VOoO&{B$cabo4CiIolw%FMr@pEkrgLjm$z1z|99`4pi@KyGH)ya0`Rq4e z$Q<-?*p~A5;&~q80>UPU`5HyHWc|0kV9qaUfgojU1e3v7Z8>E?r_D(6d#XTHgW8ON zQQa{q^7~bAm>18213WVV;*76!YkLv$Kq_ZsxMjl|=n5H&!Z%PTO6+;#zSMBT1k4#k zlxWUcZUXT&!^0VsICylHx!F|~S5Q=}F|H~b!Kg`8oBmwn+mEeL*D0*(fFz-nVUgzH zHHzWYYB!H+#1d(WV&3OR=17BUNbl55Au?i;fQ_+f4JExmcpG!V4HT~h(p4;+-exNI zBlOu@D8yUw*1Vhkir4V2dCMpp-c`S)Zv`u(4K=J_{Rhawfz{s73Q(dj^=jY%w)j_M zoq8US%h?UWHkzwfvJTzMYv;Vcr-#5Vpsh34fq9Qr2Xr)&1sz%>Oi$hRZRz{6e&RE| z83L<|a_CF>7diH2xI6`|FPMO1an3~CRXaCBY(>M@v0r(vG-SHSPWEeuuqi`@Qn)3?>d6eB zaQ-c83GFSr3$MP6nx+`csAxT|_(!5_(j63JELG4g#nPeG>!13H$Ji>jh(Z~T}a(Wb>gG6 zHB(uLIii%OVU@Y4)$kjS$0kq0>lhBH*6<;U4v+3=>H%sM4^hk2Qz`8cU@oVe9#}QV z8%*b(sdSqAy7+%I{pN$IUpq$gkTCVn@Uo;m2IW=%s<(u{mVd=to?Fr9s(&3LOJKq^ zvY)@?t+U=}fg!KrS@N40X@eU(6#1pE2_Z@S^}Z!Ianzs-6d!~du--+-G%0lh=VIzB zl6ohKbWN*iuI&!?wG-~W*(GOb_ugyf-A)!YG|j8`{*Ub2Nt>nMAtU%Vl7Y`8yEHsx z6#r(jaLt{REh0^2qez`AsvQ|kCRd5Ey%K3TvdEC+>QWMV2)`jrgSUQ(-!F>H#QC%@ zyvONxSiH^R6BM&-L2LheUaLGw&bHq{(e#_Xz$Kb^+6c(5wxBh(@NgVYYi`AFdkbE> z(YnxD>s-QOCABC@iXN`Wi$wU{;c3d>F`_6W_o<89Bik$TemZcxL%pBn-n-1eRUIy? zn&#yAfu}T~PZ6Y+*?drOq-&I)l$Fu7H2b0vpf&c&j diff --git a/PythonHome/Lib/distutils/command/bdist_msi.py b/PythonHome/Lib/distutils/command/bdist_msi.py new file mode 100644 index 0000000000..703f873b16 --- /dev/null +++ b/PythonHome/Lib/distutils/command/bdist_msi.py @@ -0,0 +1,742 @@ +# -*- coding: iso-8859-1 -*- +# Copyright (C) 2005, 2006 Martin von Lwis +# 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 + # """ + # + 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/PythonHome/Lib/distutils/command/bdist_msi.pyc b/PythonHome/Lib/distutils/command/bdist_msi.pyc deleted file mode 100644 index 53016ee53776bb8aebe3422e77d14d37077be1f4..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 23758 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" % (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. 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/PythonHome/Lib/distutils/command/bdist_rpm.pyc b/PythonHome/Lib/distutils/command/bdist_rpm.pyc deleted file mode 100644 index 80da0eb98c0a0bae6ab8635e44e7a7cde062eaea..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 17601 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 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/PythonHome/Lib/distutils/command/bdist_wininst.pyc b/PythonHome/Lib/distutils/command/bdist_wininst.pyc deleted file mode 100644 index 2b1d9e8c085e0bbc9633ee5bde561c39f19cedbf..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 10650 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' 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." + 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/PythonHome/Lib/distutils/command/build.pyc b/PythonHome/Lib/distutils/command/build.pyc deleted file mode 100644 index a3fd3248108a2d4abd787245b302d25cbc613943..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5097 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 GOaB7&o1`ZI diff --git a/PythonHome/Lib/distutils/command/build_ext.py b/PythonHome/Lib/distutils/command/build_ext.py new file mode 100644 index 0000000000..f0a7d4cafd --- /dev/null +++ b/PythonHome/Lib/distutils/command/build_ext.py @@ -0,0 +1,766 @@ +"""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 building extensions with a shared Python library, + # Python's library directory must be appended to library_dirs + # See Issues: #1600860, #4366 + if (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/PythonHome/Lib/distutils/command/build_ext.pyc b/PythonHome/Lib/distutils/command/build_ext.pyc deleted file mode 100644 index 0f280ab0f85a4a187cf63fff710327881564ea16..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 19280 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 Zv7(bOefk_jY7A~8OkoN4mx`5v{{_OVO8@`> diff --git a/PythonHome/Lib/distutils/command/build_py.py b/PythonHome/Lib/distutils/command/build_py.py new file mode 100644 index 0000000000..c123c622c4 --- /dev/null +++ b/PythonHome/Lib/distutils/command/build_py.py @@ -0,0 +1,394 @@ +"""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 + and os.path.isfile(fn)]) + 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/PythonHome/Lib/distutils/command/build_py.pyc b/PythonHome/Lib/distutils/command/build_py.pyc deleted file mode 100644 index 8382e73389256f5f55567f2128a752ac48d691d2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 11218 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 V@!}9iX$l^17Dl^(-PCO9e*sZ^LhJwl diff --git a/PythonHome/Lib/distutils/command/build_scripts.py b/PythonHome/Lib/distutils/command/build_scripts.py new file mode 100644 index 0000000000..567df6587e --- /dev/null +++ b/PythonHome/Lib/distutils/command/build_scripts.py @@ -0,0 +1,131 @@ +"""distutils.command.build_scripts + +Implements the Distutils 'build_scripts' command.""" + +__revision__ = "$Id$" + +import os, re +from stat import ST_MODE +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. + """ + _sysconfig = __import__('sysconfig') + 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 self.dry_run: + outf = open(outfile, "w") + if not _sysconfig.is_python_build(): + outf.write("#!%s%s\n" % + (self.executable, + post_interp)) + else: + outf.write("#!%s%s\n" % + (os.path.join( + _sysconfig.get_config_var("BINDIR"), + "python%s%s" % (_sysconfig.get_config_var("VERSION"), + _sysconfig.get_config_var("EXE"))), + post_interp)) + outf.writelines(f.readlines()) + outf.close() + if f: + f.close() + else: + if f: + f.close() + self.copy_file(script, outfile) + + if os.name == 'posix': + 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 diff --git a/PythonHome/Lib/distutils/command/build_scripts.pyc b/PythonHome/Lib/distutils/command/build_scripts.pyc deleted file mode 100644 index ec07c2fcd3b171eea58c065f4ce76deec8657ce2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4429 zcmb_fUvnEt5$|2evL(xZ66ccK7Pw=&WMw5!{qYY#~kTjIEB7;!&(eeF?>{qm3l|fa8bFx1t0q5pqP?O=j z?9cmgO$G}xtjm7gkLP93kl~{2FZ%I<44N`rlKmwKOhx+3lGf!FmR*swA!c5BSbtIe zAo5D&H~Xu!WUtkvnK8}GtQ)&*VB6hdIPBzU`(T_6(!_SlY~*aCu`?VE%+Tb{M()T& zk1qJ5%{Le~qYHUkh1xqi>7DE={Oz^^4Bb4My0T_0v0U2@G%8 zH**r#d5EvwLu241z=IaZ12CX-MGn1hs&WVvt3(mt!953T4#l7NfHW5J$c2bUcb~uSbI{H(Ry=X64;Zv+`p{z*74m+pIKQ zSCnUwE20Z^s%8rm$F1~=vTIbNXMZpqX9t6`NEJo~00N>cKa5)0VP2F5iw{iXvZ1lA zGaOmF2q|-Fx?|Tl7#P32vG+i=Bh$@#XOPG{gD8anIxZ{nD9fEGN2Ng<(K}t*%x{SA zrxc|vz;z;$D8TFhV^2Zk`wr0c9iWQe3-YQe0jYuXLj_22*=up5yXsW6A*Op{ zdPg@JGo)L@*Zx;<+cz-sOtavyv!0)L6ENMwC4McQF!v5uF)kVBse$uNda-NAV@b@) z>;Sh$k;fz`&hZL+_`VIss}R#Ddkx{cpv@4j1eIVum?6wiQ-m1;9^s4N;ne@pszbnF zi!lyaqA_)!R?!RcHP+k$*;@l2F`&JhUxE3x@TRm{sA%$1xVUYW1t~uca9*)l^!wL&b}=>jQGgSCUgs*4s+6}vc(8wi zXPP^~&H!G;A8r^l7t(UvY{xM;QvN+W{Ud$-=*2|N;al*pO8MmlMyoP`_4MnrkaFuf z4#aK9yGXj9oMTr_Nw3O79WBWO|4lirNC^Rt^BQG9#1t=4s=2KsjJ;+kf9hjkucf!x z2JVATnRiX6do)eONW0dV6j?0VWM*hjZ~M(3M_Dh*+@_6&o$?qQ9UFBT(e&>ZT5DYB zfH3Q!U**|pbkaGCTD`2aPBS{BUH8b?Xj5qkvwTvT&HFP|nQ2Ezza@&Qlgu4O8_#dA zZ)jR1Q)Jx!HwKfn^I^~Ca8zrB9f-n9+KYwY39 z?xUSpvw??&Q(6oB`fx32-EG|go0b_#k_|@%3erT48XmLs@fn(FFs2QTw|il=eBrcq z`UM=o%H*J9P2L$AmG6v3CQp5G*POsgMK_R|gYltC7GTkR?mT&1mROs}q~%$HOFm{M zSGA?-qznTUIq8(S*1vBApX$}P)ZSrPj7Q3z<-G#8DKN2#$2QUOL)lKs%o(jbaFvNL z8Tt@OULtt8zH)GFt1)z8iB<9LpgUrd};^m6}kn>3bE2o0C`)8O$%si+;bjo=o8l)<7Z@g8CS zEvuUNI@J9TUt6M)S~FM;YWi&kcY>wxJ@)4+!CJ6{EL{s4VH53@pcby+w-($CYe6$; zU~UD!!l`oOgmT!Rd?tc5p%W#wK9w3gE|qYl-_Ma>#@E;|U&J@q&~cYe*WNdJGid341xhRx*TPzb^=rL?&pbYrdacD-jj<$2 zi!O}k4U!;Byv!_YPm*|p9K07w6Muvse@=J^W{(!U*)gg2D_<#>^wf+JzUpJj>(RZO zQ@UPNbi#}t>+Qo6fS1q+CpF$iUw86tpwRp2C*DO5xT>Y4fF!($@SlDvE8)KZ@H^); diff --git a/PythonHome/Lib/distutils/command/check.py b/PythonHome/Lib/distutils/command/check.py new file mode 100644 index 0000000000..152bf0de98 --- /dev/null +++ b/PythonHome/Lib/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/PythonHome/Lib/distutils/command/check.pyc b/PythonHome/Lib/distutils/command/check.pyc deleted file mode 100644 index fd49bfb45739abd9a9d6fee4099ab9717b025569..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6045 zcmb_gTXP&o6+Sb&y6oy|S(fc02}5pLQ?^2d6i}&~MIxm}4g!@^!)T{h8hLhR zJ>6?tl>CD8%paim7yJcy6>kl2Onp6$!&)7|Itozva;*HZh> zd%xZ7%II$fzwe>gf8dje?Bg5Aejr&WSwo6Y`VHA{NWgYeil+2uWPirDXQY^w{+#U3 zNpLdIDYH_{OTQ)iEl)BhMO*p{vcKTl^HMBIe@XV2e7mLXW!Yc$?Y0yv(qEDN6|@(` zw4{fz^t>o4CL3@l9+~0Tb@k2AlZuS zc2;@P>pW?0-O%NQ-Rf5Tep+T*-6PYz+iu_L4+_&arL&PcGSQ7OU9_nLo6(rQZJXfp z>aFb6{NMQN1ZcTAe6D+jzT+G^KKvxbxS$S0Eu@Cf0=ewP_lF?dRatH8 zN&IOk5_d8%9WE9xu*F@Zg8_^tW>pQto>*u4$wv9OFY^u}1 zf#$V|%7XgM>n$OFnwM!1t>rzz==I=$yT+pAlW&sEYjQ5e13wZZy)7$3_y`? z(W6w~xb#|xQ+-oO$S!zP2|pbe%wIqr4XtRe2bJ4t_M99@&%9r4OUD zHc@Q=P$Mq4!Q~pfXHev6>AVwTYS**2YFK-DQAFlp?xF{|JBrdWQrF~KsXtWIO9AR# z?w%#&eo%BaeMj-fyH5gm^F7|JFa%XL06erUH6Ng|jWW|qhlPvor^V3N2vUryfy=AX zZYc!jTxeS-#jl_m|A3#@@NtB{1a4760v?rPI@8orzmt)=HOwK>hh%VGb(K*+slEIOEJ>Y}RK9o7&!kEc)cJkO;?cU^&`QAEBq)7vDD@|T)$2EP3;>R?d!J}y zM#lgJm=VbD13~|28it(G03SlR+hh}70E6_DAj_JN7_rDQt%!%E_x^E4Vkz+3NLsS0 ztGP`yf`JIAQ5ut(%v-E|0fe6xCbfWqs;*7fMJEWDWBRRaji_qK8Xy#E5Fb1?sFiDI z{l)vc$&H=spWVLo@vhqdQ&0FbIH)tk6rXDB`Av{2t%v0Y__1^fX|#eRSpKYj*P55S zvS{`!s;s}G;+2Ka`Y2!)@+g#t?+|=%eEya^Y6zk$V=g2eO7%8%H)-0-jJk}ps)yj- zWx@YF^o_IydtN^BC<%9eY?8_9Yy6 zG-Z0u$=TkHUb6~KS0j7n4CNUDgpEyql+9=?1yH{N>QTSn^=8x`S{EId3035(%3k|s zuG4cr!I^lqIUW0-+~4|o?goJm!u@7#SVkV`>04D1X>@=3WIo|m@T1`E9Jq}HAHRuu zN3%#Kwaj_z`~XN(l^!Zcdz9MLxmp!=2*5x+zKDLsRn_Nl1ryOUR1Hdj*kFLRGpB4D8a+fIfReWTAF(j(I6s+U-MUAhmV0rwDzPYc# znm=OV1Zx2MfE$l3uvuV>{gL{3leZ@LKSlxS4>O$t_|TYemMqx`kc+Ex~_Q2n+YaR(vf$o^IwA;r z5GoL8nvx)Fw6y{S`^r4iMd%Tu$J%p@OMq`KQn~D3QeC66OjBUbiac&KAI%8702_W)m;tqxNQBL=CxNkws5AvM z9&I#ca;y|186?0)yeh;zm-hQNgvql4Gq5MSk|$mn{NT$}Y*83m0IbK$@;a^Tn9q(Y~ zvw9Gdv_~kK-Sgd}1rPEUm02WgzSasB!%M+x&JW(+Ec7iYff5!n9^1^nL4V6^Zn4+~q97+$?k> zK?69^3Rl9`T&vNVX|1+iYAtPdnDNJZ_^78P@QnMw^{T{~=q!^*F}$(XhN0EF!nB_? z5A;;xv|nAp>W#s38eM3%^jhN|0ErXhi_Vs}V7pa=AN^m=cRU)?Q`Dhib%uEokm`0l zG%>R{RRLap@lL4jqfbB|riC?egyH9rr0(Dy|6KJh7t?eV@(fpD@2g?M|7v|>xs9mO G4*vrR`(H5t diff --git a/PythonHome/Lib/distutils/command/clean.py b/PythonHome/Lib/distutils/command/clean.py new file mode 100644 index 0000000000..90ef35f1ca --- /dev/null +++ b/PythonHome/Lib/distutils/command/clean.py @@ -0,0 +1,80 @@ +"""distutils.command.clean + +Implements the Distutils 'clean' command.""" + +# contributed by Bastian Kleineidam , 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. 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/PythonHome/Lib/distutils/command/clean.pyc b/PythonHome/Lib/distutils/command/clean.pyc deleted file mode 100644 index 8d7e7a75ee7d63f1313fcb233f3feb0630ac19b0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3101 zcmbtWTW=dx5T5ldwsUEkke2d*R#hsSi~Rr(NL5oIS{{l}kTwqi6SS;-j?)c$arYdT z2EkMK1N;kq0RM`IKJ*8`H*@T@lPXfu#M$vVvvcOm<(nB-->kR)IsExxM6&euq-(=h^8C$-7GA{^?rELKQu$)ZWYLH7gJ z*#nX5{OQEEI-TT2RGj+bIMK!*7kTP;hSNAvrH_WK7glc=8NFxO$D#R*DfYg+@>N{u zkQGao^^O0$n%941vXCBSBOA5w$;YUg0r@5N4QI{yhdFWdh$G$k@ ztoZ_J7rtH5LOuYE8*`I-W>mxzYc98PCUBXBv)6Mg8Er0v=96>wEn>&6v$YoCFt&(? zKxdvA%UD53B=nJZ=inr9a_;3*JDJ)~{Vccs$<)}T+zwBBlLEmUSu^6~@l(O`1dn+L z0(AXO6bj6E0i-!jb-n<`90wS43t)^;ORQ_Z%ZRr%Ugnv$WsXAzh~;t<8$+aQ=_SY8 zu9q)o(Q*RpzMKvk5O4*<`i)M;U3`-e<73r7`ZgXO@c}92qgiPl3CR1CQ@aJBIE!r@ zCGl@M%qJ4l`{0^25b|2(rwosjFiUW`AS5T!lF&*NdPtkpDxKBIo4r6N*66H)p2HDg zkM^ai#p!_E4>%+N-xe@n-CH&}VCgO=V^JC6_l2z!ITuNDZs!Evil%vsbMZ3H!qR2D zT@oqt;6%!;%g7Gft!+5XQ1fx7)jYWJI^asWZn8FU2CB}b>SMl!m2s-7@>#)3lEtCp z4k}oFgM~%1JUXdJ)~a;oQPF2?a;^YpPZo9XJullP+n^IP$x<3gWWgpCf77cUMYbih zEp(N}ReJiK4x`wgoJlI(+e(YIc);X;bkp!FcSyhZ=#LRGy3-Rh)*!G&2tniOvJl@l}ov$~{59 z0^Iyw&mTou$NFvr#8v#_Ix!TP7m$ zIljy;2vv8ydzF^guCzcK-ln(Z-N9<3#+cgl?t1H9mk%wC6q$DcNB14a-M-UUHpCte zz5N?cy^D5o(e4FY1~-{}PAk`$G_G>|U2gAH=iidO+(FzB+`sM=bXqt?7=;0M=$lMJ z`4woJ&=Q7Ol\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/PythonHome/Lib/distutils/command/config.pyc b/PythonHome/Lib/distutils/command/config.pyc deleted file mode 100644 index b94a34555be5e0a3f583c29ac93205d491f34216..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 12389 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 PDhK}8UaOt`y}J2-;`uHL diff --git a/PythonHome/Lib/distutils/command/install.py b/PythonHome/Lib/distutils/command/install.py new file mode 100644 index 0000000000..b9f1c6c566 --- /dev/null +++ b/PythonHome/Lib/distutils/command/install.py @@ -0,0 +1,672 @@ +"""distutils.command.install + +Implements the Distutils 'install' command.""" + +from distutils import log + +# This module should be kept compatible with Python 2.1. + +__revision__ = "$Id$" + +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.util import get_platform +from distutils.errors import DistutilsOptionError +from site import USER_BASE +from site import USER_SITE + + +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', + }, + 'unix_user': { + 'purelib': '$usersite', + 'platlib': '$usersite', + 'headers': '$userbase/include/python$py_version_short/$dist_name', + 'scripts': '$userbase/bin', + 'data' : '$userbase', + }, + 'nt': WINDOWS_SCHEME, + 'nt_user': { + 'purelib': '$usersite', + 'platlib': '$usersite', + 'headers': '$userbase/Python$py_version_nodot/Include/$dist_name', + 'scripts': '$userbase/Scripts', + 'data' : '$userbase', + }, + 'os2': { + 'purelib': '$base/Lib/site-packages', + 'platlib': '$base/Lib/site-packages', + 'headers': '$base/Include/$dist_name', + 'scripts': '$base/Scripts', + 'data' : '$base', + }, + 'os2_home': { + 'purelib': '$usersite', + 'platlib': '$usersite', + 'headers': '$userbase/include/python$py_version_short/$dist_name', + 'scripts': '$userbase/bin', + 'data' : '$userbase', + }, + } + +# 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"), + ('user', None, + "install in user site-package '%s'" % USER_SITE), + + # 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', 'user'] + 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 + self.user = 0 + + # 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.install_userbase = USER_BASE + self.install_usersite = USER_SITE + + 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" + + if self.user and (self.prefix or self.exec_prefix or self.home or + self.install_base or self.install_platbase): + raise DistutilsOptionError("can't combine user with prefix, " + "exec_prefix/home, or install_(plat)base") + + # 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], + 'py_version_nodot': py_version[0] + py_version[2], + 'sys_prefix': prefix, + 'prefix': prefix, + 'sys_exec_prefix': exec_prefix, + 'exec_prefix': exec_prefix, + 'userbase': self.install_userbase, + 'usersite': self.install_usersite, + } + 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()") + + # Create directories in the home dir: + if self.user: + self.create_home_path() + + # 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', + 'userbase', 'usersite') + + # 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 opt_name in self.negative_opt: + 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.user: + if self.install_userbase is None: + raise DistutilsPlatformError( + "User base directory is not specified") + self.install_base = self.install_platbase = self.install_userbase + self.select_scheme("unix_user") + elif 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.user: + if self.install_userbase is None: + raise DistutilsPlatformError( + "User base directory is not specified") + self.install_base = self.install_platbase = self.install_userbase + self.select_scheme(os.name + "_user") + elif 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' or os.name == 'nt': + 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))) + + def create_home_path(self): + """Create directories under ~ + """ + if not self.user: + return + home = convert_path(os.path.expanduser("~")) + for name, path in self.config_vars.iteritems(): + if path.startswith(home) and not os.path.isdir(path): + self.debug_print("os.makedirs('%s', 0700)" % path) + os.makedirs(path, 0700) + + # -- Command execution methods ------------------------------------- + + def run (self): + + # Obviously have to build before we can install + if not self.skip_build: + self.run_command('build') + # If we built for any other platform, we can't install. + build_plat = self.distribution.get_command_obj('build').plat_name + # check warn_dir - it is a clue that the 'install' is happening + # internally, and not to sys.path, so we don't check the platform + # matches what we are running. + if self.warn_dir and build_plat != get_platform(): + raise DistutilsPlatformError("Can't install when " + "cross-compiling") + + # 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/PythonHome/Lib/distutils/command/install.pyc b/PythonHome/Lib/distutils/command/install.pyc deleted file mode 100644 index bb03fb85e57f2a3501405059d3e9b71e59b78afa..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 16755 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 II?!MIKWtX`(*OVf diff --git a/PythonHome/Lib/distutils/command/install_data.py b/PythonHome/Lib/distutils/command/install_data.py new file mode 100644 index 0000000000..ab40797b98 --- /dev/null +++ b/PythonHome/Lib/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/PythonHome/Lib/distutils/command/install_data.pyc b/PythonHome/Lib/distutils/command/install_data.pyc deleted file mode 100644 index 92a6a3cb976b748ead4ef199aaccf90e04ea74ca..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3059 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 diff --git a/PythonHome/Lib/distutils/command/install_headers.py b/PythonHome/Lib/distutils/command/install_headers.py new file mode 100644 index 0000000000..d892416a8c --- /dev/null +++ b/PythonHome/Lib/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/PythonHome/Lib/distutils/command/install_headers.pyc b/PythonHome/Lib/distutils/command/install_headers.pyc deleted file mode 100644 index 3513c7d21b7458e9d24f294b6bf57f94d3ecff90..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2191 zcmb_dQE%Kt5FXoim-w2{s1gN%5SEBkL&>$gR6+uTNM9>?E&NtE^NL zQ(Bi5MS7w$r5igQKUvjjLXdK)iH zq2ZNmXKFUaXallxcMCs^)BB2Z(I{iP|@R;um{(avbqt8=|`n{o1>Gbol6Z zxa?C14Rnw`B%s+LwM$E%p#d^WKn5_j7@66S)V3%iQlThYq{gCble#5JNXb$B4txFp z;->5($^{pb#lHj8Len0G-3_sEQ8l@igA04mJ$I01&H%Q!dZC+_ zjd42CuTT?HE?Xa;=KMmwd|ZdP?8gv5;hZQ19G)mXEn5rVAW(ugPYndc0|>`rT9w+} zg3_Ul1QO<-+lHvtPBLx_#QUu-7BTK5!hQyAGXLHj&wHB9Hx!w79yc_b)MxGvwwuy8 zlNII{omMsHY2Sy{jv&Yj@$Zvkm?XLPpdhnTq$pGe!7rKpoD{QWD%{z;FJW8~b|-mA z*7gQI*=t$18~f7OUTc$o7Y?m<>AF;UVM?vK=w&%!wB8(-J)DNqf1vUazpz6kXi?#q zxC(;G0!oX@sYe$mxkvV{RGO{6tOa!Gk@xCLUVQxH7j)5@2Xx-A`!x6IBA^Qxac)Sb zBRX%-JwKpl0y0B76{sC^pKINiV@#E*6zDf4b{y{N=Q?vIQUDj?Ij`!olv$K;sbou5 z*Sb_OXCuHR+;pxrP z4&@;pH=)Fg;J?OQ!g2oRY1jJbyD5<=^4b$GX1HV~rD>V1becN0r0J?s>w+IS3#Dz| z7?~M9<1m;C{iS=-R8=`L;1g-u=oiMKv0z}%_Hz}V??xxEkhuSU5ekxDwb*?l M72($9NcRSR0Z5SeR{#J2 diff --git a/PythonHome/Lib/distutils/command/install_lib.py b/PythonHome/Lib/distutils/command/install_lib.py new file mode 100644 index 0000000000..043e8b6e27 --- /dev/null +++ b/PythonHome/Lib/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/PythonHome/Lib/distutils/command/install_lib.pyc b/PythonHome/Lib/distutils/command/install_lib.pyc deleted file mode 100644 index 146bf0ae32db83a47ceb150d9320aeff2836546e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6604 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 ZZtka?%2Liaa_uypUsi&Z2Cmd7{RfM>(y9Oe diff --git a/PythonHome/Lib/distutils/command/install_scripts.py b/PythonHome/Lib/distutils/command/install_scripts.py new file mode 100644 index 0000000000..29cd9e7a0e --- /dev/null +++ b/PythonHome/Lib/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$" + +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 os.name == 'posix': + # 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/PythonHome/Lib/distutils/command/install_scripts.pyc b/PythonHome/Lib/distutils/command/install_scripts.pyc deleted file mode 100644 index 1adbdeb636ae186506d21012b61e3386dbcd25d1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2893 zcmb_e;cgp65T3hp9NTr8&`?lS5GS=!E2@^nw<)(x^Ov7!s@&Po9jS1? zek0tzpt>DaXM7!wO%YbRI-hhNpSmNHht-jLwt<`PK1%QExA^Nt9;R*;!^6^sa)B|) z%w)NH@N@FxPy64yb!=R?dI4k;dk^r~rx+A~g!dSM)JK%wpmdYcn=}#p08iSX37}n} zw95zq#B@yrY+VghRTlGwJ@q&h5rU<6|b~aJGQ&j+)Z_H z&#}j;{enkbsF5?pY3NK1+2S;3YzI2Sxz5t%i$l9zFNVw4qgS|2oj+w@#O=Moe+Cn=OsuP45VGGAPQ+7v8u+Q~uSM0DK;{cut8)PZ8PR;Cy zo#MyG^N^Jy3_$-iQGzgdA|MjwN>B?877ikQtEVwg#3s82&rPn}H3)UM;cmTWiTRG_ zrEirnG5aS8Qdt>uZp4g%pb;}f0$|L!Vc!8q*6k%ZV=n+(DlX_^7gD*wHY_n-km5Y# zH(5owWS*yLtaFvtm`Oxp&Vu)k#s=QTq3^`v4qwQIk+*?Z1o%ia7#=oXqVXq$5`BA1 z1mWVDM_yiT__7+v*x+C>VOPjC=@@mur{_Kuf6&PbQD|`;-T&noy%9bix2Y%y1UyDe zafBzqe(_k|?#kRFMD$kLpa-bd_uu%nc9VBs`*aqN$9G+?=U@vCcmnH$9$XlE5?JBL z%vgP5H?cT68srns)2T^SXvX1|)l(#(ev4?s*Go0HKx~__D38tVTfq(Eh4aM@6Q=N6efIyFDYA`vK!uQZ#~$AwCUgWHcP_PrAr9IOe+a< z?9ptUCY+?K(UVMY%wsMfg&v}Hnq0iCQuRYHoe9lg>YTCs1~bcG(IuvGsVGgIbwDNWKQEHsDwV0FjDqXESWKp4F&XKEkw%*c~ zWq<4aYlDlpU`ie&39~*)r12yPNIK7W$_l9}sQ_ZcoHIg~xm8774CVLB(3ngO@_H@i zK*ro~;*f_sJTUG{?u&HA7AAc{S^{&S={Ex|k%89^xz diff --git a/PythonHome/Lib/distutils/command/register.py b/PythonHome/Lib/distutils/command/register.py new file mode 100644 index 0000000000..edb42b955d --- /dev/null +++ b/PythonHome/Lib/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/PythonHome/Lib/distutils/command/register.pyc b/PythonHome/Lib/distutils/command/register.pyc deleted file mode 100644 index 7535f6dc6b654ed9745c654650377415dbc5eebd..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 10027 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 diff --git a/PythonHome/Lib/distutils/command/sdist.py b/PythonHome/Lib/distutils/command/sdist.py new file mode 100644 index 0000000000..821420d62b --- /dev/null +++ b/PythonHome/Lib/distutils/command/sdist.py @@ -0,0 +1,477 @@ +"""distutils.command.sdist + +Implements the Distutils 'sdist' command (create a source distribution).""" + +__revision__ = "$Id$" + +import os +import string +import sys +from glob import glob +from warnings import warn + +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 (DistutilsPlatformError, DistutilsOptionError, + DistutilsTemplateError) +from distutils.filelist import FileList +from distutils import log +from distutils.util import convert_path + +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() + FancyGetopt(formats).print_help( + "List of available source distribution formats:") + +class sdist(Command): + + description = "create a source distribution (tarball, zip file, etc.)" + + def checking_metadata(self): + """Callable used for the check sub-command. + + Placed here so user_options can view it""" + return self.metadata_check + + 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. " + "Deprecated: now the manifest is always regenerated."), + ('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]"), + ('metadata-check', None, + "Ensure that all required elements of meta-data " + "are supplied. Warn if any missing. [default]"), + ('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 = ['use-defaults', 'prune', + 'manifest-only', 'force-manifest', + 'keep-temp', 'metadata-check'] + + help_options = [ + ('help-formats', None, + "list available distribution formats", show_formats), + ] + + negative_opt = {'no-defaults': 'use-defaults', + 'no-prune': 'prune' } + + default_format = {'posix': 'gztar', + 'nt': 'zip' } + + sub_commands = [('check', checking_metadata)] + + 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 + self.metadata_check = 1 + self.owner = None + self.group = 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() + + # Run sub commands + for cmd_name in self.get_sub_commands(): + self.run_command(cmd_name) + + # 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): + """Deprecated API.""" + warn("distutils.command.sdist.check_metadata is deprecated, \ + use the check command instead", PendingDeprecationWarning) + check = self.distribution.get_command_obj('check') + check.ensure_finalized() + check.run() + + 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. + """ + # new behavior when using a template: + # the file list is recalculated every time because + # even if MANIFEST.in or setup.py are not changed + # the user might have added some files in the tree that + # need to be included. + # + # This makes --force the default and only behavior with templates. + template_exists = os.path.isfile(self.template) + if not template_exists and self._manifest_is_not_generated(): + self.read_manifest() + self.filelist.sort() + self.filelist.remove_duplicates() + return + + 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() + + 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 files pointed by package_data (build_py) + - all files defined in data_files. + - all files defined as scripts. + - 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 isinstance(fn, tuple): + 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) + + # build_py is used to get: + # - python modules + # - files defined in package_data + build_py = self.get_finalized_command('build_py') + + # getting python files + if self.distribution.has_pure_modules(): + self.filelist.extend(build_py.get_source_files()) + + # getting package_data files + # (computed in build_py.data_files by build_py.finalize_options) + for pkg, src_dir, build_dir, filenames in build_py.data_files: + for filename in filenames: + self.filelist.append(os.path.join(src_dir, filename)) + + # getting distribution.data_files + if self.distribution.has_data_files(): + for item in self.distribution.data_files: + if isinstance(item, str): # plain file + item = convert_path(item) + if os.path.isfile(item): + self.filelist.append(item) + else: # a (dirname, filenames) tuple + dirname, filenames = item + for f in filenames: + f = convert_path(f) + if os.path.isfile(f): + self.filelist.append(f) + + 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()) + + 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) + + try: + while 1: + line = template.readline() + if line is None: # end of file + break + + try: + self.filelist.process_template_line(line) + # the call above can raise a DistutilsTemplateError for + # malformed lines, or a ValueError from the lower-level + # convert_path function + except (DistutilsTemplateError, ValueError) as msg: + self.warn("%s, line %d: %s" % (template.filename, + template.current_line, + msg)) + finally: + template.close() + + 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) + + # pruning out vcs directories + # both separators are used under win32 + if sys.platform == 'win32': + seps = r'/|\\' + else: + seps = '/' + + vcs_dirs = ['RCS', 'CVS', r'\.svn', r'\.hg', r'\.git', r'\.bzr', + '_darcs'] + vcs_ptrn = r'(^|%s)(%s)(%s).*' % (seps, '|'.join(vcs_dirs), seps) + self.filelist.exclude_pattern(vcs_ptrn, 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'. + """ + if self._manifest_is_not_generated(): + log.info("not writing to manually maintained " + "manifest file '%s'" % self.manifest) + return + + content = self.filelist.files[:] + content.insert(0, '# file GENERATED by distutils, do NOT edit') + self.execute(file_util.write_file, (self.manifest, content), + "writing manifest file '%s'" % self.manifest) + + def _manifest_is_not_generated(self): + # check for special comment used in 2.7.1 and higher + if not os.path.isfile(self.manifest): + return False + + fp = open(self.manifest, 'rU') + try: + first_line = fp.readline() + finally: + fp.close() + return first_line != '# file GENERATED by distutils, do NOT edit\n' + + 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) + for line in manifest: + # ignore comments and blank lines + line = line.strip() + if line.startswith('#') or not line: + continue + self.filelist.append(line) + manifest.close() + + 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) + + 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 + # tar archive must be created last to avoid overwrite and remove + if 'tar' in self.formats: + self.formats.append(self.formats.pop(self.formats.index('tar'))) + + for fmt in self.formats: + file = self.make_archive(base_name, fmt, base_dir=base_dir, + owner=self.owner, group=self.group) + 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 diff --git a/PythonHome/Lib/distutils/command/sdist.pyc b/PythonHome/Lib/distutils/command/sdist.pyc deleted file mode 100644 index bae96454f98a8cb4d6ce6c3c3febae96cc671359..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 16430 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 diff --git a/PythonHome/Lib/distutils/config.py b/PythonHome/Lib/distutils/config.py new file mode 100644 index 0000000000..7dbcc46bf4 --- /dev/null +++ b/PythonHome/Lib/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 = 'https://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/PythonHome/Lib/distutils/config.pyc b/PythonHome/Lib/distutils/config.pyc deleted file mode 100644 index 3a33bb6a64bf2913ce7f358b28163ca956f19808..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3535 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 AyZ`_I diff --git a/PythonHome/Lib/distutils/cygwinccompiler.py b/PythonHome/Lib/distutils/cygwinccompiler.py new file mode 100644 index 0000000000..5d116876a3 --- /dev/null +++ b/PythonHome/Lib/distutils/cygwinccompiler.py @@ -0,0 +1,463 @@ +"""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 = '' + + if self.gcc_version < '4' or is_cygwingcc(): + no_cygwin = ' -mno-cygwin' + else: + no_cygwin = '' + + self.set_executables(compiler='gcc%s -O -Wall' % no_cygwin, + compiler_so='gcc%s -mdll -O -Wall' % no_cygwin, + compiler_cxx='g++%s -O -Wall' % no_cygwin, + linker_exe='gcc%s' % no_cygwin, + linker_so='%s%s %s %s' + % (self.linker_dll, no_cygwin, + 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) + +def is_cygwingcc(): + '''Try to determine if the gcc that would be used is from cygwin.''' + out = os.popen('gcc -dumpmachine', 'r') + out_string = out.read() + out.close() + # out_string is the target triplet cpu-vendor-os + # Cygwin's gcc sets the os to 'cygwin' + return out_string.strip().endswith('cygwin') diff --git a/PythonHome/Lib/distutils/cygwinccompiler.pyc b/PythonHome/Lib/distutils/cygwinccompiler.pyc deleted file mode 100644 index 3cca3fad0799118b1a272982d363c48a247210a0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 9645 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 F{|m;rV4?s3 diff --git a/PythonHome/Lib/distutils/debug.py b/PythonHome/Lib/distutils/debug.py new file mode 100644 index 0000000000..2886744402 --- /dev/null +++ b/PythonHome/Lib/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/PythonHome/Lib/distutils/debug.pyc b/PythonHome/Lib/distutils/debug.pyc deleted file mode 100644 index 35cf785d3c20f59f61ae7076fba236b0a8e00efd..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 249 zcmXYrOA5k342IK(52WH9#6?#w+z28fK9GWl&=#Q-Msx<9Qaj?Lf@`nj%{+i+tReaH z5&n=k?{@38+lNQ^hfRG-rF{}kX+aK<5ZI7dAOJEOG6%Q=PYV*)7((AAv;0tOw837$ zd)OgZ1Ys0M!8&A%=nvM6*z>5`g)s x65S=5kJ9Y}&#D*<(_9`>E;W`YbDeT=C{O+C1Dj+UUlcEMF|mk$?|F9J{Q~INH6j22 diff --git a/PythonHome/Lib/distutils/dep_util.py b/PythonHome/Lib/distutils/dep_util.py new file mode 100644 index 0000000000..2b759056ea --- /dev/null +++ b/PythonHome/Lib/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/PythonHome/Lib/distutils/dep_util.pyc b/PythonHome/Lib/distutils/dep_util.pyc deleted file mode 100644 index 724d8eb853e5fd85bab2d469fc49a84d28038374..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3160 zcmbVO-EJF26rNo>PGS-orB&5Py%?-kc7$UUgam33s?;Bpix#vAM2b?G&F5qwve_= zM$Lu#tBT_y&Sy5WJzIy(clOdd*jW6O6*T(?{ig?ePapf4P0T!+-|PuYdTfj~ z33-N*a~GuW;&Er`aGwkVqwKY5T+4U5SwXhno2wnQCQ= zwtLfn0piFOoM<=lr}NU=B-N+^vVL~uISk4ERyFOqYUZ=+1Mf33f@z*mq(#6N09_QJ~@gj|n=V{!V%m7Ov z7*gvbw}wWnZ3c~CE7%O`A*TZwxk!hfFaU0SB2b6Xds-9bj&R^0WI#w6Fcjh<jI20Fkaj`^+bdLO4q6PCnoQL8ChIPuC;Jn5ItYL8WK;VCf4VWH; z^Gx{z_8i9fsdQ7#K`ba{IpZBsoWv&1bCrXW5c{kc5@uAKjHGwpBBL&GmmyOUZH%%L z#GOREdwYxgilH_$L|guxj@Mc5p3N4{n4ET*Z`4x1(#)n<@KebckC$WqSs`NnT(E2E07uE{UxR zfb)!y`RI8@fV`Aq1ln@~Brtsna2|>?KMZ-8iL-n2nHtZW^AQ#M&p`}3w*XjBySc~f zkUE63_dAqQ_IEJC+pO)q*(PY}((UNMP6|?z(+pfns8k8)Oe6LvzhE0i3IWmc)&d+A z1@09RB#e?V1=4JnIdgu(n{|PGf0+l08It)7iL_ALg$-O~nB;f8athXbo~n-rYkQno ziv(&Tp9*I*%Gs2-c&b2-lpckQ=lS8!L2>dTyOa%VOR5HOnLF8OakN|8Bx@3uk3%L-cMo-wOl?hiZ zv%BOsmS$Bg_7xOR5dLky9LJ|hmZ-VbmLMdqL08HjYq=WT4i_j~4fK%Cr~tK6Guts` z(V`NK3YEDwst@Z$t&|gl0m%wiu&yLFsAtd!Uys2dDOFhVwJ!4%1)9Qt3UWx|l1g(i zDd~d%{8U-rl_#ZRO)OTGbsXm$urrs#!EMM;nT-=yf?8*CsF@?RgsqFH&5hXhNQiDw zN)oSl*E8jGh+-lti4mo4L6IpbPR*7Jkk}A_3RV@$c{+PZE znTOtqg5HBBPeJ@?`U!^iHX5;kYS_3QuA?fh1vNYkJj>x$uoCizGTYPdr#k8P*`9vi zsF#_=r*XgU?|6Bs4Jcex;~vA>a{XtwMAxw#ZK1im0{8w$RbPSh=YUO_t1rlfmbkSM QHo~=FBiIO6Z>(Pb8%hLI0{{R3 diff --git a/PythonHome/Lib/distutils/dir_util.py b/PythonHome/Lib/distutils/dir_util.py new file mode 100644 index 0000000000..e2dc6f4826 --- /dev/null +++ b/PythonHome/Lib/distutils/dir_util.py @@ -0,0 +1,214 @@ +"""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). + """ + 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("error removing %s: %s", directory, exc) + +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/PythonHome/Lib/distutils/dir_util.pyc b/PythonHome/Lib/distutils/dir_util.pyc deleted file mode 100644 index 830efd74d602c9e22c0eb29403ca275016be6074..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6753 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 Rt-iCmUf1il=NrqH{sV?sfffJ& diff --git a/PythonHome/Lib/distutils/dist.py b/PythonHome/Lib/distutils/dist.py new file mode 100644 index 0000000000..e025313dbd --- /dev/null +++ b/PythonHome/Lib/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 -"), + ('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/PythonHome/Lib/distutils/dist.pyc b/PythonHome/Lib/distutils/dist.pyc deleted file mode 100644 index f124d415f579fdeb422f457ae813af9eed61b0ea..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 39231 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 WV`t#f@bGwP*WWt+|GT^X^#1`AT`vp( diff --git a/PythonHome/Lib/distutils/emxccompiler.py b/PythonHome/Lib/distutils/emxccompiler.py new file mode 100644 index 0000000000..a0172058a3 --- /dev/null +++ b/PythonHome/Lib/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/PythonHome/Lib/distutils/emxccompiler.pyc b/PythonHome/Lib/distutils/emxccompiler.pyc deleted file mode 100644 index 688d34377d22a550410bbe5270532d2a66a88e21..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 7332 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 G-u*u+V0{1p diff --git a/PythonHome/Lib/distutils/errors.py b/PythonHome/Lib/distutils/errors.py new file mode 100644 index 0000000000..d9c47c761c --- /dev/null +++ b/PythonHome/Lib/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/PythonHome/Lib/distutils/errors.pyc b/PythonHome/Lib/distutils/errors.pyc deleted file mode 100644 index 48f9309cb0b010cbf0c912f101ca538f128409c3..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6185 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 ... [ ...] [ ...] [ ...] + 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/PythonHome/Lib/distutils/extension.pyc b/PythonHome/Lib/distutils/extension.pyc deleted file mode 100644 index c3ac9d429312153332a7b21ea3a2a60d2447a4a6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 7391 zcmcgx&2J<}6|bHdkL~g2+Pij~{i-+#9&Ly@?VKtTo-$_3`R` z{@$zF@;~NkzrXkPzALhS6L^0QKm9%)o)8CkTH?SGUP*Xm5tPIM8m3(q2j#q75eF4+ zS41!&-smsp166TQ75BnbQBjlPxF!-;Se6A+=ngG$-rbrBZ&!a z;vXux``qr7*%S z>7^{RlNQ2h>4amVN&GY7q2H70p-TE`+YehZRLV1YIqdm?C;e2`+fl5JdO^@9RX8$^ zlGHg2RE?;dI{j^l4N1p|k`8|DC^{ycWBWj*vLE#%wCiZu3-hJ)Mg6qfW~0WG?uI&b zLKia&8E*4{l%dmA^0w5FEo^0dlC4T?nPCV|W-iRP4QAb-=aEoO*q5>69y=}QWoJkF zs!>q66-MbTNOj}~iuZ{U%uUHvCeLM)kp+_|N(&nGQ&uTW8uvdLV71;P`Q)3SekaC~-W~Q|4I(;(F?zV*YZ_E9AcYi4B4S#dHAP|FL z+G9t@%Jq+Y7cz{=1(~qJDa=i7Bvqi5^fl(VQ7iP{QC>mlu+I{&vuD|`)H=Mk+a(W# zKjb7q%#oSS3v1@~GB#DV=O_ws4yyzI&dd43j_<~dpIOJ|ppV`I( zO0fgW=XZcWff`xGIL8L>wm~bDPa((}Hr{B!jfhheV<$*Y+@M)VYPO;AQ!I}V$B1ty zNqx5$I7uc;U7hrNY@|Z=>Gh}0s)EQXuf4X;C~5o(+w9yypM*oRgYJ@>Yrs zT%)}Z^u`qWMX@we8LuF@)L9((uAc_|jG4ecOq`_uU;BrlL*7Fu=7+~J^^3S44Sq@F zXPhuzz{P+vBNQM@5XR_DG7FP;T8<9@%*04~A?;`XPs9Q7acQKildJ1Cup6l$Pm>61 zWCUbCjo4OLF%GWO8$<}90%x!;aqQ@@gRuM3$mEGx;N`-T@5#DqHKZYs4U^9NE-ZW= zLpBUj=#6b;1YoHP4YJk2Bdpb>ya+@a`G(AZOL?R4IrKyL$ps`+soTi?(ukC~uI(hP z$I3;y#mH3PB#2Pj$DBKzH$3YqZRY(m0e}()fLuJbB zBZ$p+WuqY%ucLzjmI7`a@Nx{7)+msW+j8@!{n&RMO7Bj=P@ccCIEZ)DD#J=w#YHu=#{+w|DaUbhE#gavC^oe3|L0eO%yWMBko;~ zl0p?QRW`>#y>goST$Z8yFjYyMC_FbQwfbEjz*#IVhK<>g=16NB7hP*(q#Y`fY~Al3 zM!{n}F1JlS1q>Q@$2vstQ4)25;*Z8NnA;mGF1Y%IBf{<@SK4OJrLb$MP$ldWp+bqH zDOQMcBXuDjljQjjKjZbh2J1n3AcS3|8Pu2* zgR+SGq6ND6oDzeIh<}lPPK&{Wh<}@Z*2JJH;*avr88Mg?@gMTfSuvOr@gMWgIWd?P z@t^b0c`>Mo_%HeAf*8z*`0x4Wq8QAISXdbwm&9OB#0&Z7k{Ha3_(uM@ECyH(ZZET_ zi=>X^V{5P|I#=jqI>hozqO(G6i`279-|v-Z00-6d3DH@j9oi?!MVHeHHWG43ER;G#on|XTgNSRte+Cuyn4i)g_*g3y*%R(i$53yxSY}Nyppo zYpqZ=M&Zjzg0P=L*Q+?$@OT*?T_;ZIO+_TpA?DLbG%`+8oM^>(b)U|m!xWlXZOBu` zi$(4jFOm58Z8}i8rI$hBag`L4MyQMmmUIbIO;46VIW?sVMR$>|SXzT^IY{%i1z53E z85FP{@(5?Sk5ylDLqkj4NK~ApWL9Gs?(0NI9HhfjCkc_h%n~Zzd6;@xn;OK-Qk-TI zL?KoreyZve<7OKb95snjlddM3WVz-HJxJe8(s7f_*Ca`sgbvM1^dNmSiAa-_*t|lI z6+8e8@Y++p?Rb@0=;~G-eS#nQ8))s`eqhqX^WS*@V>~GCW*!vq)QI~mo^4Ymux;EV z3H@y%vv|W=vYxf3OVif0weSUh)8$!fR@5-MV$E8MrM)^yo>3&vvTgQJ+cuXR_#{`e zZ7*_dyLlb$CUH7q{OfYxq_B7rKYb04>WkHhvi0~smu8YCN#VQr>AxWkfUdYG3lJBU z7+RtWq$r7QSq#gp&TRa|ft9%@Fsw zIC+<6%!oCbXoHR<-{JnNV={nO zZIorGd|Ez7=)o5d`rs=Pf){ME7kt7Cu8r+X`xxKeASW`u{hW0Vg$HS2*7(A^;vURO z6R%TPS@$u#U%!QD-{U)CzP07dfy)(5w@1ggM#AkVp(~OJj&Mbv{SZ?)wNcBbn^rqH zGndR$nEnP(^cAc%J%lP6N95E#=|w0Fc@xScu}x<;I<5JHKq-N~K1TN;^3gGF8t_eN z26qf0awTPlz^pqpUtof$oN6CKqDc=;h_~^q-k>`R93-j0Y=idz$Bw>AeM$~oH#A%g zkP{8p<-78R8^>AW>?~_+ZJC)}Gqc;}&z-yGb%!&|cg@F}=Cx~HfqA`ZUQJE;ZztjF z6jIO5eM;3T(Inu`{Vbg)W_FKX4ae-MqwH-+HX^3g@cPJFENU+t-C`D}Ur7q6bLm3z z{wJbxy86nj)Nf!L;0tiR_+Jhrem4q_{8p2kthq&x?Tgb=_=-)A*4&{%%Jd@|^#3Kz z2KAHPa18dys+=9UlE77k+iue4ob9;KaAG>*a1{`lqJ$LB1lS9)-&mnR?!r|FE+M_K zvV%(uV#X98TzhcEK?Ml!?FNy~su*I9M4-I>h_oz~5ut)v95~eA&?5U61&864#J!4(6rppV~>@?Ly z)zT%5%vn{mR;)QuE6rAx(L=u_{MJg#)|Ko#@6X>vGyhuz1<>TbtUa+@x>CAanwc>& zaxu9H{tRTk+9v&kF ha_j3BmM= 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/PythonHome/Lib/distutils/fancy_getopt.pyc b/PythonHome/Lib/distutils/fancy_getopt.pyc deleted file mode 100644 index 40e79346eeed1c09748a76a0c75074fce6dcac6e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 11853 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 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 , 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: + 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/PythonHome/Lib/distutils/file_util.pyc b/PythonHome/Lib/distutils/file_util.pyc deleted file mode 100644 index 1f2fd224aefaada09d0344f8a953b75e2089d3c7..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6601 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 diff --git a/PythonHome/Lib/distutils/filelist.py b/PythonHome/Lib/distutils/filelist.py new file mode 100644 index 0000000000..2f1c457ea0 --- /dev/null +++ b/PythonHome/Lib/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 ..." % action + + patterns = map(convert_path, words[1:]) + + elif action in ('recursive-include', 'recursive-exclude'): + if len(words) < 3: + raise DistutilsTemplateError, \ + "'%s' expects

..." % 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 " % 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'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 gF}!ovhG+N0SToM5f#a*= 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/PythonHome/Lib/distutils/log.pyc b/PythonHome/Lib/distutils/log.pyc deleted file mode 100644 index 8838752b8242174dac5179718384e97a16150077..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2726 zcmb_eQEwYX5T3oW&pF3QTS@}~AzXKl`oQr^UzT=l3l3 z4^}Br%vw>bDD^1zDD^4!DXmakp|nbImC}IH8s!1S3^pijP#V$;qHCgG;~ME2P`p8U zgU&*VLjiS)>jE|@-W1TFxFKMR;w=H&6mL^nhpqS)rJDk7W3z5+3k*MH)o$8s@;ukg zycjkoxH9IG7k!;%qmb-sDJs>ad`Qp820%g zAIyBnV!Ny~vrwej14J*_A?yStjMxvJ0Ct5hfc;PrP=kv=pWPA&2tglj>J)Wb8*I0a zU6yiy-Eg)`MVCa0M4;OO?~Z5}GIS%O?WoAp7S=f&!|HqxVOoo&RJO_J;Omp)xf>PJ z{Vz}Q?DQnfted$kwY8(X(+f3d|9EhO}LxaV+Vy74dj>Nol@e&@R?@EzQuaaHZM#u9ZF{8`dsH0gL}3v z*~5g1emH#i%VTlikDW(H0-m*_j*J~f(NQGmQTyli6IbW?PkZ@H9~x5_NfzsjIKBKa zw|so|pi8weOIXaD*tjs6(}D*1%#K>vJ(BPN2|ckgu|uKJGsC4hqkEH^h85vUIK+2B z=xtV{-dDTcEfuIObx$?CP~A~|_yaQ`k6G+HtT^w^%CJe0u6D6i63p~IKbFY{zbv`E!i$p+cf+Gscwvd~ioi?Kpd|OkybzaEpU#FKF<1*T zSX>7)oG_aXijUVt3~9SAVi!F#{bXIlYHK0}&-0}$%xCLjhPt^9mx0-!=X&|)D`u@t z#*4~4?M-x&NbyOMNs-QS{uv=)5pGDC^7nvtpm2esccFHn-ea}8kAhySEkwMIwplFh zcHlMqa69yu-#$tKE*#{5#bR&n3}=e2q;WA$A!_o`!xh-IoE6#vYk{ z8Q@BTfn6Ek?!;Z}CmHa|fkofJo$O@TboDQzERi4byE0&iby=Q3hbtM;`J0~hT$|Iv zW^UeQE4IOkRD)}KDWz4EK8GumBx%v-v;oOTSV#h4DB6HRWF+R%2SERuPmvtxKF?cm k7xY@0C29R_naJP41F|Zp2HctC>ovT)dx+c1uNMaY0pn!E9smFU diff --git a/PythonHome/Lib/distutils/msvc9compiler.py b/PythonHome/Lib/distutils/msvc9compiler.py new file mode 100644 index 0000000000..7ec9b92a5d --- /dev/null +++ b/PythonHome/Lib/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"""|)""", + re.DOTALL) + manifest_buf = re.sub(pattern, "", manifest_buf) + pattern = "\s*" + 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"""|)""", 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/PythonHome/Lib/distutils/msvc9compiler.pyc b/PythonHome/Lib/distutils/msvc9compiler.pyc deleted file mode 100644 index 3e3a255ae5eb08e630ff217f94ec053aef38d3e5..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 21387 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�VT@Ls#+OFZdhuXd!WBysM3$P4a z9dLJH)W>&Q=|#x+vVFuCU|DwkiSbRPb~`r4Obwb>NRY_;+>eD&;-$WS8&{{^ zpPid&D}4QGK0lK$csFm(d*s(pGg@Czo;VGwQrwC0-lve}+|~Kng_#20v%mDJM}?WU z#^5syt}*x`1D;a7fbHF3O#U`c;HEdGTffSZ0b4KWo*2W)(O9qF8ubShu#^=b&qx*>OR 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/PythonHome/Lib/distutils/msvccompiler.pyc b/PythonHome/Lib/distutils/msvccompiler.pyc deleted file mode 100644 index 2c7c6924563723d03ea2af2c972f0f6b7ef77dd6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 17393 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 Le1`^vj+6fdb>GT6 diff --git a/PythonHome/Lib/distutils/spawn.py b/PythonHome/Lib/distutils/spawn.py new file mode 100644 index 0000000000..321344a3a5 --- /dev/null +++ b/PythonHome/Lib/distutils/spawn.py @@ -0,0 +1,226 @@ +"""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$" + +import sys +import os + +from distutils.errors import DistutilsPlatformError, DistutilsExecError +from distutils.debug import DEBUG +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. + """ + # cmd is documented as a list, but just in case some code passes a tuple + # in, protect our %-formatting code against horrible death + cmd = list(cmd) + 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) + 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 + if not DEBUG: + cmd = executable + raise DistutilsExecError, \ + "command %r failed: %s" % (cmd, exc[-1]) + if rc != 0: + # and this reflects the command running but failing + if not DEBUG: + cmd = executable + raise DistutilsExecError, \ + "command %r failed with exit status %d" % (cmd, 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 + if not DEBUG: + cmd = executable + raise DistutilsExecError, \ + "command %r failed: %s" % (cmd, exc[-1]) + if rc != 0: + # and this reflects the command running but failing + if not DEBUG: + cmd = executable + log.debug("command %r failed with exit status %d" % (cmd, rc)) + raise DistutilsExecError, \ + "command %r failed with exit status %d" % (cmd, rc) + +if sys.platform == 'darwin': + from distutils import sysconfig + _cfg_target = None + _cfg_target_split = None + +def _spawn_posix(cmd, search_path=1, verbose=0, dry_run=0): + log.info(' '.join(cmd)) + if dry_run: + return + executable = cmd[0] + exec_fn = search_path and os.execvp or os.execv + env = None + if sys.platform == 'darwin': + global _cfg_target, _cfg_target_split + if _cfg_target is None: + _cfg_target = sysconfig.get_config_var( + 'MACOSX_DEPLOYMENT_TARGET') or '' + if _cfg_target: + _cfg_target_split = [int(x) for x in _cfg_target.split('.')] + if _cfg_target: + # ensure that the deployment target of build process is not less + # than that used when the interpreter was built. This ensures + # extension modules are built with correct compatibility values + cur_target = os.environ.get('MACOSX_DEPLOYMENT_TARGET', _cfg_target) + if _cfg_target_split > [int(x) for x in cur_target.split('.')]: + my_msg = ('$MACOSX_DEPLOYMENT_TARGET mismatch: ' + 'now "%s" but "%s" during configure' + % (cur_target, _cfg_target)) + raise DistutilsPlatformError(my_msg) + env = dict(os.environ, + MACOSX_DEPLOYMENT_TARGET=cur_target) + exec_fn = search_path and os.execvpe or os.execve + pid = os.fork() + + if pid == 0: # in the child + try: + if env is None: + exec_fn(executable, cmd) + else: + exec_fn(executable, cmd, env) + except OSError, e: + if not DEBUG: + cmd = executable + sys.stderr.write("unable to execute %r: %s\n" % + (cmd, e.strerror)) + os._exit(1) + + if not DEBUG: + cmd = executable + sys.stderr.write("unable to execute %r for unknown reasons" % cmd) + 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 + if not DEBUG: + cmd = executable + raise DistutilsExecError, \ + "command %r failed: %s" % (cmd, exc[-1]) + if os.WIFSIGNALED(status): + if not DEBUG: + cmd = executable + raise DistutilsExecError, \ + "command %r terminated by signal %d" % \ + (cmd, os.WTERMSIG(status)) + + elif os.WIFEXITED(status): + exit_status = os.WEXITSTATUS(status) + if exit_status == 0: + return # hey, it succeeded! + else: + if not DEBUG: + cmd = executable + raise DistutilsExecError, \ + "command %r failed with exit status %d" % \ + (cmd, exit_status) + + elif os.WIFSTOPPED(status): + continue + + else: + if not DEBUG: + cmd = executable + raise DistutilsExecError, \ + "unknown error executing %r: termination status %d" % \ + (cmd, status) + +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/PythonHome/Lib/distutils/spawn.pyc b/PythonHome/Lib/distutils/spawn.pyc deleted file mode 100644 index 5cc2b90eb2c812e4d7522fad8bb387fc09dc580d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6363 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 diff --git a/PythonHome/Lib/distutils/sysconfig.py b/PythonHome/Lib/distutils/sysconfig.py new file mode 100644 index 0000000000..4aa93346d5 --- /dev/null +++ b/PythonHome/Lib/distutils/sysconfig.py @@ -0,0 +1,482 @@ +"""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: +""" + +__revision__ = "$Id$" + +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.abspath(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)) + +# set for cross builds +if "_PYTHON_PROJECT_BASE" in os.environ: + # this is the build directory, at least for posix + project_base = os.path.normpath(os.environ["_PYTHON_PROJECT_BASE"]) + +# 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(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 == "os2": + 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 == "os2": + 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": + if sys.platform == "darwin": + # Perform first-time customization of compiler-related + # config vars on OS X now that we know we need a compiler. + # This is primarily to support Pythons from binary + # installers. The kind and paths to build tools on + # the user system may vary significantly from the system + # that Python itself was built on. Also the user OS + # version and build tools may not support the same set + # of CPU architectures for universal builds. + global _config_vars + if not _config_vars.get('CUSTOMIZED_OSX_COMPILER', ''): + import _osx_support + _osx_support.customize_compiler(_config_vars) + _config_vars['CUSTOMIZED_OSX_COMPILER'] = 'True' + + (cc, cxx, opt, cflags, ccshared, ldshared, so_ext, ar, ar_flags) = \ + get_config_vars('CC', 'CXX', 'OPT', 'CFLAGS', + 'CCSHARED', 'LDSHARED', 'SO', 'AR', + 'ARFLAGS') + + if 'CC' in os.environ: + newcc = os.environ['CC'] + if (sys.platform == 'darwin' + and 'LDSHARED' not in os.environ + and ldshared.startswith(cc)): + # On OS X, if CC is overridden, use that as the default + # command for LDSHARED as well + ldshared = newcc + ldshared[len(cc):] + cc = newcc + 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 + + +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(project_base, "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() + + # strip spurious spaces + for k, v in done.items(): + if isinstance(v, str): + done[k] = v.strip() + + # 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.""" + # _sysconfigdata is generated at build time, see the sysconfig module + from _sysconfigdata import build_time_vars + global _config_vars + _config_vars = {} + _config_vars.update(build_time_vars) + + +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.abspath(sys.executable)) + + 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 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: + 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 + + # OS X platforms require special customization to handle + # multi-architecture, multi-os-version installers + if sys.platform == 'darwin': + import _osx_support + _osx_support.customize_config_vars(_config_vars) + + 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/PythonHome/Lib/distutils/sysconfig.pyc b/PythonHome/Lib/distutils/sysconfig.pyc deleted file mode 100644 index 26d896a1a0a157aaecc3e64b04c607a32a39dfb1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 13137 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 YI5>1cF6nYZ)#3ym&=rfPQ2Nq;0kVzp<^TWy diff --git a/PythonHome/Lib/distutils/text_file.py b/PythonHome/Lib/distutils/text_file.py new file mode 100644 index 0000000000..09a798b190 --- /dev/null +++ b/PythonHome/Lib/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/PythonHome/Lib/distutils/text_file.pyc b/PythonHome/Lib/distutils/text_file.pyc deleted file mode 100644 index 2703891965173ba2b4f41742325e601acf72d6c7..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 9079 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 z

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 "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": + import _osx_support, distutils.sysconfig + osname, release, machine = _osx_support.get_platform_osx( + distutils.sysconfig.get_config_vars(), + osname, release, machine) + + 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. + """ + 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) + + 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: "): + # Function kept for backward compatibility. + # Used to try clever things with EnvironmentErrors, + # but nowadays str(exception) produces good messages. + return prefix + str(exc) + + +# 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) + 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/PythonHome/Lib/distutils/util.pyc b/PythonHome/Lib/distutils/util.pyc deleted file mode 100644 index 1088e8c1cbccd0e79e2468392a451fcf4fe57e57..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 14295 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 F{~I23=u!Xx diff --git a/PythonHome/Lib/distutils/version.py b/PythonHome/Lib/distutils/version.py new file mode 100644 index 0000000000..0fb5b6e204 --- /dev/null +++ b/PythonHome/Lib/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/PythonHome/Lib/distutils/version.pyc b/PythonHome/Lib/distutils/version.pyc deleted file mode 100644 index 9c99d4561b02d0a17e73d8aeb99bf798953d7282..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 7133 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 diff --git a/PythonHome/Lib/distutils/versionpredicate.py b/PythonHome/Lib/distutils/versionpredicate.py new file mode 100644 index 0000000000..ba8b6c021b --- /dev/null +++ b/PythonHome/Lib/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/PythonHome/Lib/distutils/versionpredicate.pyc b/PythonHome/Lib/distutils/versionpredicate.pyc deleted file mode 100644 index 5e3040a33e102230926ea5c98f36a44d200ca7d2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5437 zcmbtYTW=f36&_M|S+*Q2vFf%+M~MY3ZF(Wec7O_^+}3UZ1Fd1K90yV4EQh-zX=QSk z-Wlp*$PZ2O+_wV#B}IY$fxh*>w2yg6zH?@|BxTn%97-I{%+8!W^Ub+@Gh_d~IQ#c6 zn%j{mK4bX(4Zh}IC}JUYP*y}-743@HLB-XpVrQ&h9~V30LRZA$goww)w-`3rZ;o?w zs^6U8=Cp_>#dnZABNB`p7l*SVo)Vu??ShD>U2RUpGp=?~#Ivq;NyHaiZC=E4;h|0-Uqaz-=X+Z7Wdj(?q#{`s@x>$zEo)}tu~hG zT@^i7`&u4pJj+tq&2^ka%4%tBjseD>O@6@Vky(K-?_N^-de_|WzEZbdhR=47Z+Q1M zcKxzdyHWG}8#QwoV`<#3N6pc14KYs(6L}F>zKE z7En)!!%1<*8@5LfRY~$w6pw+6mP!&hfT|Bgly!huVzShqot5|m+V=8PdV>cANOidl zup;}^fmq|w<`al+sknqV2jn!0U^b_zRVN#AIrpY$ZC6m_IyBvOV(*vlwG-&>C>tHv zS=64Yc2EC4&$HZ4qPd@Ey{@q{sK$x0J)5+RC27S1>_yZ^6!QpFKp_Nevn6;*De9m# zu~baP91mTB3-c*z{_Y=>)^7Qh-Qo?UvH0CnelzR;d6%}|kj7$SzA{-^s9dR7+S5%# zm~S@tr_tcPEpBYNzNLnxxdo1o`?eUNk3S@YjM~&tXm}Ky6D1qLcc{QctLz2iaMcBYDLo9TJu-ya`QGm z{%y5ZmrIScyLa#UYpvV0m70_ES9FK0RjzhxAw(ya;yY)nv8@n{J+0y*YTRl4+KAR6BX8W0rQ% z>!|cru2rmBLyiDJq@X^*ejADs!^(6KC9FK+`6Hl6hl(7AMV7b>lx-Si6SJ4-IBcDI zwWjQ7dyvI4QmJfd*)zbyW-``R=ba?g@;I>vSQ*2@ukCMN+UvA*PLL&O)b7QYn53+_ z(G~(s1l-ZtI_1t{8jBe6O*6c@BY#A@l{J42J4(UeN#1i?z&7&QusiQIY_%Bn2h}$J zTihLd{JzAu5A6dyB9|3@gCzi|y|z9{XtRNoiXz?Rte{V9uH^ASf;52)p+_Kjqd&lx ztS1`{DOde9DQi*|8aQ}{3|83{*5^&QVeY%&w(76HzP^Vr_w=-k-p&{d^fF{YSYDjL z-mQ$X6v?ndHU+DGZTHD-nj=xOS!X{ggKv{8ELRD{{(oG$Ykqg#@80&icf75Ja|!(P z!-T*7(gg`;Qh>UJge<*IW~|J0q~TkULSSesV{03%t(3m+b8V0iHn6}WcyfGh{Sp>S zuPB1UL(7)mah!lDflL1!aM+^&69UpXppFrWRt&!r%4Ej?R2iVs*88e0-z=_<*fWBe zgZdqD+sm?BEtQwn@Dq?h+|m(6Rb+GEd7upiJlRIh+>k5$mZ8}CM(c()652>_ZQWmA zqoDqi_v`Ii4ZqAO7g6e@v`^XkKECD$6hwBI2NsNINg%0$5tVER1PN>i!-zFii3*vA zJO=g3Fl)j%kXL3+pi|)l6Q{Ahbch%e`F{i`0*PZ1Rfzi=i{s8A64nGBV z1qGWDF;n6P&#s796T(i5Gj4xf6)*llG%lQ>@^D6&?^!GeTdC!X??pPpl6V{#^tLxm zK-@sl=WzX8P*RhEqB)15T{G7(T!ZbLmid1;`d`JD=f&2e{@|HpcJEA@ z4So@z!?_Zs7MAZ*u1%ohJlZQi+wt1$EFit|Y72}5$>Fyv!h7`g{tj_#mW{UlcJe|I5LVraC2W&*==hGtpn5+a2;}VHN zz;Ry43E~xx#AzBXL`lUR#REzWa5Z!eWdUR-gnZ5x-I%1ioRNP+p&wBm7a`7R(O(?h zF`h3`(9frIiel#1Fx2AoO(w`OnQk#M(A6vj1?ihwaRlI_51+2+xKbSE$T&yG)yd?U z_0(~yfPKTraz5nu3C=kt$R?V=I#n9!y3EKPk3j@wVoL$dM_HvO1?UjdC16q~r(Pa@G36ahcN?!@KN<8u?4eD!nsl>wr%FF41usB!A>9j(`H4b5Ak`kBpXG85y#tIYxKh*Jml$ zo`d=?)I}^n%u$Y-!(TsVO(JhON2GusP&K%T!qRP9c{}14M#g$`n$Eg9SBPdooo3MB zfYNb*ui%8uaI~%aap33|+}d}Y`>r$9!6!6_ygDG-6VOFSu!`b60|e{0=>pIe;ch6$ Xxn<9d&5t2rkI!6Ksw`C((#h(NiyuvN diff --git a/PythonHome/Lib/doctest.py b/PythonHome/Lib/doctest.py new file mode 100644 index 0000000000..86c9839b2a --- /dev/null +++ b/PythonHome/Lib/doctest.py @@ -0,0 +1,2817 @@ +# 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 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 = '' +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 '#' + +def _strip_exception_details(msg): + # Support for IGNORE_EXCEPTION_DETAIL. + # Get rid of everything except the exception name; in particular, drop + # the possibly dotted module path (if any) and the exception message (if + # any). We assume that a colon is never part of a dotted name, or of an + # exception name. + # E.g., given + # "foo.bar.MyError: la di da" + # return "MyError" + # Or for "abc.def" or "abc.def:\n" return "def". + + start, end = 0, len(msg) + # The exception name must appear on the first line. + i = msg.find("\n") + if i >= 0: + end = i + # retain up to the first colon (if any) + i = msg.find(':', 0, end) + if i >= 0: + end = i + # retain just the exception name + i = msg.rfind('.', 0, end) + if i >= 0: + start = i+1 + return msg[start: end] + +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 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 precede 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 ('' % + (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 + (?:^(?P [ ]*) >>> .*) # PS1 line + (?:\n [ ]* \.\.\. .*)*) # PS2 lines + \n? + # Want consists of any non-blank lines that do not start with PS1. + (?P (?:(?![ ]*$) # 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 Traceback\ \( + (?: most\ recent\ call\ last + | innermost\ last + ) \) : + ) + \s* $ # toss trailing whitespace on the header. + (?P .*?) # don't blink: absorb stuff until... + ^ (?P \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=''): + """ + 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=''): + """ + 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 explore `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] + 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 = '' % (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: + if check(_strip_exception_details(example.exc_msg), + _strip_exception_details(exc_msg), + 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'.+)' + r'\[(?P\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 + + # 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 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 s are being used, then replace blank lines + # with 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: + + >>> 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: + + >>> 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] + 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 + + """ + 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 : + >>> print 'foo\n\nbar\n' + foo + + bar + + """, + + "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/PythonHome/Lib/doctest.pyc b/PythonHome/Lib/doctest.pyc deleted file mode 100644 index faeedb901d495e9fbf2af8485d41e91703ade31b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 81866 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

6`Q?K3lcV@~f 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 diff --git a/PythonHome/Lib/dumbdbm.py b/PythonHome/Lib/dumbdbm.py new file mode 100644 index 0000000000..4a0c3a7852 --- /dev/null +++ b/PythonHome/Lib/dumbdbm.py @@ -0,0 +1,246 @@ +"""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: + with _open(self._datfile, 'w') as f: + self._chmod(self._datfile) + else: + 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: + with f: + for line in f: + line = line.rstrip() + key, pos_and_siz_pair = eval(line) + self._index[key] = pos_and_siz_pair + + # 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 + + with self._open(self._dirfile, 'w') as f: + self._chmod(self._dirfile) + for key, pos_and_siz_pair in self._index.iteritems(): + f.write("%r, %r\n" % (key, pos_and_siz_pair)) + + sync = _commit + + def __getitem__(self, key): + pos, siz = self._index[key] # may raise KeyError + with _open(self._datfile, 'rb') as f: + f.seek(pos) + dat = f.read(siz) + 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): + with _open(self._datfile, 'rb+') as f: + f.seek(0, 2) + pos = int(f.tell()) + npos = ((pos + _BLOCKSIZE - 1) // _BLOCKSIZE) * _BLOCKSIZE + f.write('\0'*(npos-pos)) + pos = npos + f.write(val) + 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): + with _open(self._datfile, 'rb+') as f: + f.seek(pos) + f.write(val) + 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 + with _open(self._dirfile, 'a') as f: + self._chmod(self._dirfile) + f.write("%r, %r\n" % (key, pos_and_siz_pair)) + + 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/PythonHome/Lib/dumbdbm.pyc b/PythonHome/Lib/dumbdbm.pyc deleted file mode 100644 index c12f4872d65e76b56f205a8ce9b1110f39a7095a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6242 zcmcgw&2QYs6(5qTm3AfDvMoza;xv<_Y1WRcBuEh;iIXP&DB#wSQOZG7!70HdXC->M zVd+X`b?<@O8t0ek>p}bomZc^YG;nktCdpaHs zx;o5aU8ecI?v5&5CWB#Wble^2D9tmo(Qbb~FLWGMVK*#|E{EY@UCNC(DRh))RhVR@ zuJ(*hve?|!olsZiZl!xkYR<2>xnQFk_VtB9IKD7hphMjaqyA{9^WLGgX_;f}Ac6fo z5UO_!s|f+SBiZ7H-6RW(vE33JZ*OnwTQ~L9n{T$;7jNyhQquNL2A-Ej3QH(hqg)p%YLqhMb04u{=>e})u;g0 zgRl>l+rqmk*NNX)M`5N1qykK*$~d&4>GhH*fhd#x07)7ayU=#6-NP)9%Klys@I|q0 z2ve9aw!m?4vW#NpLz9_!-5OIqFcw+xU6}m>Uriy@Kj0YPqYG0)Pm?)1`d zSHG=a9K49x$$#*-nJCz8)q({FS8JvtG~~}gc^O~%1quU)a+HD9yL1^kk)mI~gWzSX zh&Qm(RHjK+f}SMZfzqPXX(dypCx zM^%oxoM zorolf289+&xQ|L=m8jJCG%bNxy9%1P??8hmp+QeH_%bz^{Qzol)aUOh=k6OciK`#I zs_w&-TxuSwLLFkG2?Dpp3hu*n@E=sMkEbqu{Eqt2>R5D1mNrGBK9%JkXF-SbPoNMq zi?S+`p#Wn(3DXWG@K3W?cg%-yx zJ>rVs>8S1T(~|{Fsmx0$PV|UnpH7yMm~}aX8b|zTlR9I6t0u&q?|xSr=xtL$S3i1Q z6eGHU0^wme#TgAe)pOM-vSF-J#`Lok@*DqOMT}ZS?&` zwzy_xSv7ykgjsT4rI5! zPodHDsP;9S0%!62B)%2Ggh{wKA~Xm-XIE%vsB?h~0cm#Ckbwr=K)PU*b;K`eh(-4$ z1S~`?ik>ifNT^qG4YkpO!uj9k2p1$-C74zwO)Cxsmv7v>^24p`JJ&BBT- zL!hw`e}{7#C^Ddb6xMWtAdF+I{u!zgvlUQYMg&>KZxfjR?|FQUTRepJvo)58#Wgel zc4lccPB^;-TRSM`>GYv9+j_KtB3d(rw zpls~C!qF`h(D2lqEPcX-QZveSBq)jM!$VPtX8iC; z!Z0I(ACP$(P99%o=oQDyFDaFkndj=V)h88CBN3UuLWTMi`$dHg=R|v^|GJVfMHC6lvl?iaX-(xAEFR~G9Uy4 zhx*Zp|2T>qRs2N=!QsRiLEG*Rx|gz5X-xK=4Tusb@g@WWBF~@zI;Gs$VHzXc)d!=p z(p|iKaDHdIrFg6OsrXYh9vTV$w@{J0lhxa6pya>8Vx0wT)qfR5hZx%fL6j#3E2jG* z282?c#@#fJ`lYlovu|5RS+tFiFliehe+6>&JzxW8{|V<@<23yDEb8axBv#VR_=&c8 z<03Aixwlz^y5SLmkiFh;t`+V%)Z{Rj3G#T{;ZbP0`#mU>1YWuAxrp>9pK!xt#d2fW z*y=pQf?!Wg$$+qN1PA_Gp!o-UCFM}|z+{!*Y*TBYu!1Js({9RAtQ`3848Gy|{ zqWXW^mlv5Jm?R;B;Lis(pP-ZF6dikYDP9u3<&|3pQhR$rv=uKU zflY)*JeK)zvrn|z2=THkd>h1V-7j9A}ZwO>LxPeDo!7zQNj?Ea@oH=U;2dZxA9TE*{T>v*fxYPOz2iAN~@ zx#;y;ji#G?0S}tqfrz;n*9}z0nwo<**#i@IL))|$YCMMc8g=FM^qM?_mhc+IY2~RC z@ABa(Hwd0}yfRX!<-f7lO}x-0T{O)vQDN(n-6Qfg$y697!;sTMcCH-eSNp2$n?DBTB}*SGCRoouyu3K)`UV=7c=AHo6w zomkB{+0gnr7%{zYlvXm9M-?`Wxaljezy3N>u~{sHCNhAZq*td&Nqkr!Baq;|xvNKm zu z{Qt!4l3S={4;P1%Od)uSuFXS{lOTxm2)<6Tc_}_#+3QDll%z-N&N%&g*OeVES&MpySAG$y=`P`hv*glMo9+`| F{uh9NtW*F1 diff --git a/PythonHome/Lib/dummy_thread.py b/PythonHome/Lib/dummy_thread.py new file mode 100644 index 0000000000..198dc49dba --- /dev/null +++ b/PythonHome/Lib/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/PythonHome/Lib/dummy_thread.pyc b/PythonHome/Lib/dummy_thread.pyc deleted file mode 100644 index 8108412edf995a25f09932594012f6cbf144f1fe..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5169 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 E0`IUoFaQ7m diff --git a/PythonHome/Lib/email/__init__.py b/PythonHome/Lib/email/__init__.py new file mode 100644 index 0000000000..a780ebe339 --- /dev/null +++ b/PythonHome/Lib/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. -> email. + 'Charset', + 'Encoders', + 'Errors', + 'FeedParser', + 'Generator', + 'Header', + 'Iterators', + 'Message', + 'Parser', + 'Utils', + 'base64MIME', + 'quopriMIME', + ] + +_MIMENAMES = [ + # email.MIME -> email.mime. + '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/PythonHome/Lib/email/__init__.pyc b/PythonHome/Lib/email/__init__.pyc index c037387473c77cbd74acd3a9ff9d3ab1023627dd..b6bfa1303e5e7f2573f23682f2a8730dca29f05a 100644 GIT binary patch delta 353 zcmbOw_Dp=k4;Djb1_p*ytC;l6l8n-%nDG1xJ+EMYzn}o;82{3eg3^*0m(--v^q7Fk zl8pR3kNn)!$?+Uwn`K!I7|GK*xrpr|SvtihXR<#hOJ^2Yy2LiW= 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/PythonHome/Lib/email/_parseaddr.pyc b/PythonHome/Lib/email/_parseaddr.pyc index 7918849a1afe151f4a221e13d68f8ff62510a519..a1bddd2ba2ae0d54ac76aecec356c17fe9a38d97 100644 GIT binary patch delta 1614 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 R29wz2^X$cB=nUj=0RW;PkSG8E delta 180 zcmZn`o+`LuFC)Jq0|SGzRZKu-Nk)F2k@;kMPU*><*p;vJuRd5*1r)>r@jv;|@bWXnrCrL+xVIY_&ubP2=?X^~|MAbn6uH$gmv&xk}iS$8Y(WWb$1sr%oBo;)Gi(?Vel1kB+3Z z`1&BrOjbG`-3|LV>;|bp$D_Y-ZbEcSp#b{@eZZ~Eb+NI@m?RCBDb3sjtyOLB^(d0A zi_>tZc`AoPx9T5KBW4LbF8fDe;^DA|w=kdVr})_a?)25An;8A|&x4S#EmbHQL&Cy@Yni)nV6!VBgHN;MwJZ8TA;K z_RTC2de^bB(tF6f zi!T{y40=>UR|v!#8W=4j3g+C9zq^jLh`8`ESs?(OMyKf>;?2N>;yl!4vS0D||587N z<9X>;>?JCdSgeMPB&%loXy(|23#Rc+QN6@N$o^Q^wWSg@sLyc(1|pcp4r@3d9T@kL z%r6R)I^1h)WC5ThrE?@y6j~xnVDCfiwc*)Bvrj8{D2OjrW?kM4e#Klov`8_?iZi4} zqZh^XJt~}sj{?M5T+zoU-5H`&&LR(^WtMjh|DraW)Zf0U;3PUYQg)i~Sc(Ir-^5I1 zj(JgpKY4_^ziIXE%W-DX-2i}M=A#u3DX9_yyQ3MS4+@Z@#KdoFLrJ~ySp_9^oFks# zaS3bYX6Rm^3ZKyPJ-Z2ao~2V|{n>;fni&0*;jxTB8$6L^7YdJSX)s&t0=8jYxNM_rm|WkgICQTaz+C8bV8&W*_K4SIm@ cI6veE>>p_lzK3?&+r@vUz1`XBY`4PyUnSeq5&!@I diff --git a/PythonHome/Lib/email/feedparser.py b/PythonHome/Lib/email/feedparser.py new file mode 100644 index 0000000000..15db26d22a --- /dev/null +++ b/PythonHome/Lib/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' + re.escape(separator) + + r')(?P--)?(?P[ \t]*)(?P\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/PythonHome/Lib/email/feedparser.pyc b/PythonHome/Lib/email/feedparser.pyc deleted file mode 100644 index 4471a5038541a81f939bc1c15f66be6df5e78ea9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 11027 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 XK~usPZ}|NI%1D0mloLh^M?d|4$HK;N diff --git a/PythonHome/Lib/email/generator.py b/PythonHome/Lib/email/generator.py new file mode 100644 index 0000000000..e50f912c5a --- /dev/null +++ b/PythonHome/Lib/email/generator.py @@ -0,0 +1,371 @@ +# 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__(). If there's no handler for the + # full MIME type, then dispatch to self._handle_(). 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 + '--' + NL) + if msg.epilogue is not None: + 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/PythonHome/Lib/email/generator.pyc b/PythonHome/Lib/email/generator.pyc deleted file mode 100644 index bbbc9e046368362e8e54eb1d75c6e2f714c674e8..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 10095 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 diff --git a/PythonHome/Lib/email/header.py b/PythonHome/Lib/email/header.py new file mode 100644 index 0000000000..2cf870fd57 --- /dev/null +++ b/PythonHome/Lib/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[^?]*?) # non-greedy up to the next ? is the charset + \? # literal ? + (?P[qb]) # either a "q" or a "b", case insensitive + \? # literal ? + (?P.*?) # 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/PythonHome/Lib/email/header.pyc b/PythonHome/Lib/email/header.pyc deleted file mode 100644 index 57323cc5de5f0221c5401c882df9d96bbfda9897..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 13422 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 diff --git a/PythonHome/Lib/email/iterators.py b/PythonHome/Lib/email/iterators.py new file mode 100644 index 0000000000..e99f2280da --- /dev/null +++ b/PythonHome/Lib/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/PythonHome/Lib/email/iterators.pyc b/PythonHome/Lib/email/iterators.pyc deleted file mode 100644 index 271a01da068d87ac1d813076d8c9c64e3ec8217c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2341 zcmbVO-ESL35T84L$Fp+KrhfK_B6;eNiWiAKsyVhmw1C- zrc>-G`AeeEqElF0=GCqC3Lkn0keCm{+PmELfKuw()OjBjODPo@&PQ{s4Lz7k0 zj=zds{anwZ)Mh3+)AQFLW+OUs)BYqb{KXRA@@1SJ+Q0DWwgc8&1ljV1&4!zg6PDDf z!Le~afE>ZO0OWw^gsAwQW}mU_AmHi!y$w1JX!b501#}RWqDyof(ou+Q&+pLo^Bc6C zNj$gOAshV}WE*a%{Dmo$9~m_^&c#Ecd|}KjHMb_!a7dXr8L8?Po#kbP&l70#6_j;q zVv0dtjEz<{Q`$`Y==Q)C&a1r8rs%LTw8qAda;PAHV&Oc59hr99d|}@Lu`U`KhEJr_UY%lsqOEY zactAwGsIkHG8gmfY=aF^vk|m{HT)%fYy*Q26-1tanLQBz1dscB52|Pb5acXiIHBOU zMjjA=*61XpVufb!ldrSnBmihY2$MP^bQcJ%5dOE3?ptz2_X`f$l*BU^AaPjSEmasl zEi#73N!q9?LQZiW-tNzD^LGW;wG$+b~!Z3Z!7tRBRvGdBgr*f~JxM@2pz zj+D<;=asm(Za;guZ-1<}|IdrQ2X z!4m{4_YoW-_Wbp+!$$fLqr|SU7F-Qhft^_NX66$A zKs*%GP(;A=aFN_SSp|G3$WT_hECGOB22bz{fS**@pRoTg{Hok^>ZSD~6|13rVKVh- z^U-(GbSlJtaz^bVKQrzjAFCK0i3=2h3snYb9D5XJJj8BdCkwaOPcYmf2rY23+z2f537^Sn z&f^}2`waxCfQJGZP`pE4S}fXa*-kk*LRw$vQVyt&a^|)yDRMpB43HhgwybER7FOz< zJlDd_hnZ}6$g&2@ieG8g5tSxS@9%v;#|^HIqXzHibLw=Rdj}r7=e}&`{Ccsc?ro5} zYJ}%$jtuBeheK`-vDI*wNLjv?WAf}Hw`W<_ZS&=OZ-Gcry1A43c3$UG@2^1qDry|< zb77TZkw73Qo%etU6+cbTos2lv6Zp6u1{2Rpsd-^izY5M~NjlXgs*H&fKJLFEr0>Dv z*BFk|jlvds_vK(cXa?8Ay7cijKPJ*_qDbdS6jgkjrcuXFoZEox|KA$P=Po~Gs-w(t0tM6*^4YQa*y6@,;:\\"/\[\]\?=]') + + +# 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/PythonHome/Lib/email/message.pyc b/PythonHome/Lib/email/message.pyc deleted file mode 100644 index 053154397ea084946f328495ba69572c555de70c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 28454 zcmeHwU2I&}o!^-uMRF+0lqKuSQLMYPWm1Vq*^0ACY%8`b$yz72;tUnbk)@1=Gndpz z!x?h!j6`nj0=sf{+cf);6bQ1}ZISImQFKvsTcAaOeqqr*>_f4D3-qCj_NCpo?n8m1 zeJarYe!u@Y=iVWy#ALT`D~Xr)bSc(?n?fh z33s!iXZu{c;#Mc!%}IMUrtAIg=6+n`l_{5&-Ms^@IpH3m15dbS#eIw}O|u*6ldd`G zK1OE_x#oV|KkS-QI(dqHZle4FUOsZ}+c%H!oyECne%hCDc%z=R8p&#!W%ZRb=`P(% z8~tRt+e`X)(Y+raJAb^+Y9}1y!?*6*7`sAb8W7KJN*e97W=(cXXUML z*qwd2Gw8S4nO%^b?1@~de-7E2Ho6aql-D14{ zaKu00-8r^?tq73l3t zAEE1`?%qDVJmOBUj*|TvbtfKa5Id+EBe>@JWA5I#uebN>u8Fto^$C9y19)_?ImX+l zNLQUvUM-?yi*x*h?9Xwy)a^V-JFT?SNR#D3r@@g;`dt#(YQ3M-JI$n*_6NOAQcv!u zn-?C`+k+GY*Xk`yPA2$s{cbBu9=6);WPQ->r=m(L)LKqDY1&Mi35XRJ_8g`Ay+OK= zByTMzzF?NrRagIRFGUT5wRW1!HSX4XS=v9FwCkOf0m%ET6+d$}Y4xqeB``pz0cvk1 z^+u!HYl5h)qHa=s^V0eAUwAR;4cck8pt~)6FQ>z~&$UQfEuLm%lhfISnbX-!#!1Ba z>FnAZX|2j4 zV`;tDxT{w+8Y1f|Cqwr%9Mz|ADGJr$(~;>E-l^G~iB6wqV+V0?N0&*-;N^`fDG`#2B>ii8 z3VMZ96_0~jSsr&FTf?2>AjhM=tZHHfC3g&5fC|^Y=x+ELo$LJ_*9Vh8BC0Wxy(m9{ z2m$>XLh-lr7*S98vn1-DXp#?9nk)!#W{`z#*tZFQ5*7 zFFL{RU9X@&CC@6?L@HH^mz;=ZBpz?gh?YcF7v@ATEVkV0G&QG~LwaG+lb7^mJ(ozbAD(hr3Ud8srfEL~3~h7ky0!`a${iBBuspdxF2p?gZuyQ^E_# zFbwH3lv%uo>%}HykOcKL4W&j_L#Ufo>b)u{*Vu{!I_Ma)up`wYIPCW058$1euSGoe zE^cI;1h;RxG*fQyjDPr<{KD){&{hfs4hqImbowz)gdlh_>QYhm$I$j;q0AK0I0#x!9kA;ZUR9(p)x=a(>eiy zIH(gKh$nRd+;B)IM_u!Io&*~^Uv#i-ZgPK@7fD) z^_;tT&XuZ*bLTj(e+*f@6QJ_S?BZ6O1#Q(#!OPSzS(0^E)Bas38E82u$Gf;yPnMuH z?70x4{2>R#OjeoP)kXx1m>24U|9X^8HOz7ex@i&tpk-%wTACHtC{x?_n!T zsgzZmkgT)f2h_jgVQZGOR-xNhp-j;PyRoe1?yN%k;icK6)#<0b<$43k{^8vg#q(w}fA2X}0*+pXsngYmy z=&hr$MhDQN-@<#zT)MEbkW|w~+Io;S&uAtMc6af$etyrYW1HOp-o_{m@Py-+Za{E1 zFd`SvYFo0w33cNn^~X>cYA=Mhl$ zB~tg-aDXa@@U21q+6iQroj`Wk36wMtI|~Ul*2cm+kYB*6xDWY7Ax&I!EhFsdryKoq zYi&@JaFJ|?n*Ra=NrX!fv8|0|P^UfjL}V8p&FNyTm)2L8+NmzmwN|^kGDu~vfY)H% zWPJ&2T+}fowf^Q>YL>|;8p+c3@^0n-1Upx2bz1#e?LOX>unF%q)ZlBpJuyEM}wLf#9(b*ML)+dMO$PTAarLw#o3)i#Ke(yiARz zk};;{isHNj7G6mqZtLCx3MAkqRjeK)L195L2gR_IHtG}^OPka(Bz8*CRoFYQS&}y7 zHz@>~W+`2PuzJ|)-;FiRNFB^Te!L0Evf3pDw$qK)QVX^!$S8=S<#xS~#^%m=VM3W} z+JIko)jEwDf?bo-nw$p4c;xO_wE6OdFzn$Ry$I`Lv$;|EDV4*z; zB=!KL6MOI@T!$Wnp@_qAKK1~z>HdW4J;Tv~SI`EibI|wio_sJ6P$iV}a{a&K-HXkp zCVmAE$M&$aq)>X!1~keF+c^x9UlT(m*g)v3NgL#kuokAp^+eK&Cm9Uo-M0 zRY;LnKZ~=RWW>Yabv)UP>x}jlWKX?u_xEsS=GORhX}T<*8J|+0h;F_D;=nY)?BSFh z*Bn82z)F9`I|9hBP$+PIy-60MN)~#dAF}sqeJB1yUi!{Y=3xmWBq(- z6ifo=@BK;F`x9r{ZSnneG>rFf8=i_Umf#;^EBoB$3$8!y?j5AZ2=&AEJBBtsgf+R} z^`FESLObqr_YSG}h_m|fg4Mr(>Zv_dKV29&og2gX|Vwj==+MililqO+El}_ zX{$jVOXzffvEWt=0||dAv}u3-dJm`qgFJtQ4oEg&$RXA=7d3j8yb1qbdZqv>ZUlHD z1i>x^MFY+!n1FE>Y&Dr>aojXjJ9Jq33NKqPFwoJpdPmNa=KLDWvVI+~dzPliouzt~ z{^Cos5-_pTG;qzNGsh~w3zY&(G-2vl$iZ6R?bTKWcj$_qn7)h^1&0oVX<(v;Xb3v&9| z7znm(%!gqxjPJ)pzCS#XYg%P8D$+@L2iFI!w0}*0vn_QfMiDB^AR63I9dn0q$K<^v zztGFexF>7kIt;EW3;+qs(EO^t!e^`oinw}`FH_^Hr?qt(Si4v%Tr9OZ^{mlqsjsTg za3NnE3^V{%x=O8G{SppyR0{@HW_b1v4|GYPkMYVPd;vvSB3?uL59z-i&4nKT+EUNQh*%0s=+AitmvMY=$&1gnXe&obCo7a86jWpOZi3 zrJS;3#P5Q-Y%HRLpLmpj-~>>@^Iq3uSfM}}vV~%=L8}APgGw+ZAYTB6-q#2ffB>NM zaT8?`>cDjPGT{-SMTZn^Wr!x?yb3Cy_WR?m_aik6$1ZfY>eti?i}3Lug~w3na12AU zBgimGWlqiBIjYC|w>)qqb_TFy%E9%)K935u09F7bpn_?3o1ZtOo&&_{Lt@?cM_liv z5-*?h^%To9V&XfmGKMY6ZWEPoP_4mTBFNy&d+S3_^D zcHu%y=o%x>$9_dH0TG)lx6(H8{>2Ug()^+npuy^hu7!FMWphC~Trc2<(5CrK^)VPg z&H&qxAMbN9XgcIj@cmzCb=C$^N^sQjVC&Erh4S4&zwko*Hafn8T3_qIuib0ID*>2b zF=6_5p?Uq6@pB~%>0(qbV?DhT?!pYp6)+B=X-`XD?4f(_y!FnN;6h90cs2hX9PcP= zzFEq&;y9npuY$4;5bjKzv3gT6WneJ{unS{dt%Az0Wwc3)ZArzxxbT7=6r0=PJ{4Ms z&$o6USIg4F$l`!(M6|9-9izyYg3v?_-rYypCk91@x!o07h!#h3o_BpMoum>%ooI2+`CsOAQ;bgPeK`*7i6SCM980rN$3=c zelDm2@8tRlZWq3)-|g4iNoTOS1YrfnGGvdSjyX%oluhJf(1Jn=g*gSDU=`2fu=fu! z2QxA%YPA#bBOd43g1(U&&Oc%v?_6ad#rM}Nog#~xYo3xhxbe2xESgC;LipLeIU zK@fx6XdqDtvZGKP!ZQr&zzYlEMIq%Yv#1dWAo>FpH#!@mQwm^3IaY{MfddQ143x+K zNdXEnLY{pKLZ2)O_YWW%bP+BXG>R3m3&Mvm!0P>mR7D&MDG{o~bSv>)<(!c~gx!Sf zS!|cgXZcVy^r_WPS8KJ;#tE!MWK4l@2|wA>I1n)4pKuT`0}_!ilLepKKSP;-7tCbE zjD*kGG7B$b_%T||F5KcYlA%<44}0i{O&yFfPNScm$d(zt(v)i)LXD3Nb*%;|Yu`dd z-0Hzahe5|psBqM~iRm1wcnB(MJjo5_HshBYG;ZKbrV74kZ$k`u?7J0*c&x$pDDqyCM1S;y0(*{znOQ&S@Q;}| zgqv{5QFyRfMZGTjVL=Qtr)N3E!<0$IdyQR~zRO|G$ZUSTJgaSCD@?HWE94aHZIYAd zhGdV8HV2|G+LO5Kq(Bu4yemuQzK##}HUW_?Uf={!;k$iPuo02#$`#0Q7N$QR~$RGbw@^**R9C<_f~nl!t(X`KYTB zM{K$D)sUk28o!Y<U-#YZg!{OY;T z_sz-GhKw)6>Ex53A!1N^fO*m-%)V7FP#U8m<3d40~WZT zmVOdFn$x^Ct%XagQCc)mv6;`&ix3qQSo6*Xyk z!*ps63rzQR>wcQla<~bIwlwJbKmd}rkUF$P0)^zZ?3*|~R;?Km#pNXg%J5ssGnISi{=!A!&rn

^o&Akk1C$<#u{b|PsN47Cu^gX6s`zaJuc^e*v_`86UP z89?Ra=J2N4CN9ORvCR2{wCS9sP5f6d3kVd(JWYP|-Z|_)UV3WmAX`D(RE3GerYb3gIv&a!e zy#pU6eLu9`dl{CWz$^vuGB0whj>cp?19(6`u5nQfbAH*?SowCZBNy7th!tm0J95D+ zWtD`cyZl;nJOfHvo@@g?LFB{wx>3P!t!Nyyp67k#ja!AmL;yQ<<}WT@dh4y+osQ%= zB&9LEl@ON8S->mGhtBKM%AI*zxdQ|KXD;3u>N2X{8qyA4rgrvhGHaPBqy}6qx8RNf8C{rN8Z;MHTFbL%Vhge% zYdX%;26KLG&^k`@lo>fp;j3m&L-i;g$=ESOEv+mk>*AGn-dcS3;-xF{zufC0pO%~| zA)zQ~jlIyTHBF4FH7BrN5W<|ZJqwWP`)KXsC^@FbN+%#YPL`j?5&3e|M3frQSi(A( zVO?~OnXpKl^YJRNEjX8`O~J6sw_ouP;1(?29W@n}|3Q4n6=bhLHNE=o`hvs18yEx# z1=NW6Tkd-Jx9CRI#x@C#hJpYHk4)v$gA*NNfnBi(C)!=nTIw#0}nz)ydg0lx!uHKs6!f&@W@{A`u7T04u512pOqN z;9jV&5E1`n4#QvJVTOl2YZ3ZzJ*oP@z~3TC$i*=}ReA}kOM6@Uf0{#)4dn6U<4+IHM*h(uR9H14c1Ow4PwmF6_Wk(jg{r|S+D({>mq zJC_ZX_}j8$D6L@-bGAVQmqG#%<7u8=%%G3;L;@p0hOoTiZ>YiopUC*79`_F|#XW|f zVnrZOth`hf;39nT>2Nxd)|aaSAn1k?KjR9h#eO2)9H7kab{ z&bd`SU}liGxWV@3aJ8Eph|r+#vnb&Yqkuk80WVHr`R38`5kfmWP>_f2!b|wcn5{`E z8vMWDKR6vBImuSww?zTd>~Emhj;utAe>^{ddpxd+tT9X65*O}xE(>&uMD{r09L3^C z%@xpc^;gj!&5YS!-^HbdPz$Z|C`I*SJlO4sK81IRjR&UwV~#4t8BMS~kL368zK!J8 z{2R!OdH=!NB~xJ}gKYVW8%R<`K9JR4iQnhzhTEO74By z=`ip0uD7q(-vG`wvs=z0dXoUWWO85A8uuzU{IDhOuj9=2LWoMT`Yi5A%Gf$~YSj0* zErg|bQYBe-D2dV%JiP^D6-g@586rE!AXIggZ%LJMfMuR$Qrm0Q1|Ow3>_rpMcj#NM zDJ_A$s*9N(5z#nV@MBSn#jS@f$|g2c$u>06p#GS^4^g|QU}4?R1%oq+v!0^ZB+|$fF8WoF{3)kHNLK>`iOsZt+E5 z+VH6y87PH5N^B&dQJ}`yE7lUnL3LXHeNE}=T7T1<2)?iJdEwizK(oj8Jx&_}M`(Xi3dYNpLeY`vNzc_jE1B@%sw^(a1HHQ3La$Rvtk%A9A)={h& zHNpSmw?N>)+1g0wK`&F}NUb3BNLe}iXtc_6^s zEz44tX~wb+()p%-iZsBaRSx?|1k#_>9O#5Z+t`ihzCI`2j_%& zJRukXlchH8gl_a_DVTdV#EWogLT*DYFRnl9@Q-dy4{ZJ= z;!Jp(@&7O3C{FyCmbGm`@OsCd7f3A<(5EK3p${y4*}F_$R4Obu9ij*{?~TqzcNI;8 zv*fp=n+$egA8YQ~o1P(!Sz=#oVCl9ku2VAmLtk4@zTo|jK20lrnk;u1v#~Di3*^0w zXibZ8T7AgTSchfwZk3YO2Y!WLs!xY3N10xPWbV>0U92u%xqdcz`{K2$-@179%Gu<- zi*JAH3ioKplgO5^V?yGKGHw}r72XQI>75+BTnOj^T7xT6nLwa6C|(Myf`SXx)88PQ z*FubtxQq^c8#Qq>2iZU#X-I7@Ar74=Od?8Rvxqgz17r$rju4?xZ5HX|PT??@KRnFC zPBTd5A-9^WPP)o9fcadZraHH~&_XV6UbYzp%(?|1F9%-lBo`9;d!xvhn_cd93(i{> z1U=;2HqGfZ%r7^YI`eWIeHP@OP^-^Ct0dD;LUx*9kFIF#NM-S=T)OXBrV};C2|7lRuCUe9#9gO=xyDM9<^6`Wih{EG zI^JurPt1Icu=^pv8vqw%G2kIU)>Lnf@YRkG)_8y|hmZuAyj& z4NTpcmYR@967rrXTh44?b_T5g=S!vR9}_`mzo|8+!0u2eK-y?!+^v7D1Q>e{Z;fw# zx+1S9oA@zZoH*I|Eme-~HB>X)ovg=|FW(*r2~N0=u($$6vGf#BU;a~ibacW_A1nd! z)6R=Mm~@>(Y8aM6C3Fj~qq{GbKAcn+KMC8#p_h{`c5D3;s5JZB@bz@VX4(X6#9gpw z7=c$YlvvENs8~hzUoeBTDY>gnpzlwm=Kw%R`T1M*HZ}rj`V33D2KC&u4xE6n)QxYp z28g`xx{!K}yuWSkOEi}&up(he0&!s?ZO%=6$x@1y2WXF1#%?^c772}1J zxI?Bf*paOQFDyd| zifC&rFV;t040RM?ZrJQER&97!gTw9o!t=AilTZxbU`jXxTj2d0)VQJ3oTX4lL6eyj zF68!ZGyS$K_qB4s#T1hNEdw%J@~S zK9r~_uw@;59y%?bsDg>zcGE1|cqIbUjt!Q!XODM@!K*jX+A9>(G}PT8WEPa4!45fG zUoloXQXVTkgCB;7#vr_pln>!|rF;TU$4j!0DYE%<2|wAt!GY2$Aah!?6uihq_(;MK zq6N|iZVy<^5VjPCjY3|+c9aegb&i6LtMyPZJA}voNO}A!`am#ghfAuviBPsl)dgxp|>81IL8 zAhL(Ft;um&{Y_S~2b;5c9WO$;I&E|7Cd?glTEOH8Qix9tQ+5O*{{pX3ISWw$Ie@BB z3pP~*F7c~Jm0nNC0Y@OT_hph7===f|KhDNPUZ65u&~E*Xcj1!mux3*mRlp?(%?|c} zau<8hwdjdd{$3W|P)r>iICc59rQn%~Ye2?01g+rxQKW|b(A{9|bF{UyuX}CI8B{Px z0X<4d@ALNxad>{WQ?gzQNh0+ael?XY`)DQvVnTEkp5uJ?xIC5Qz357$h6y3`NKx1G z?NR`u#UG|3iuC9EcNUpH*k6omdu-RWSWDz0!H%#K1(e%X)knpKZnRVE(r4|2^&qh> zqj8vzl-O#FVKXW<4663V+oBz}apoKf#_GI>ytrLN0SA!bJVO!*3}xi(3-#H6JYG`#Pg)FF+!immnL zVfJx-=FpnS;$q5c1^GZ%PnBWU>i2j!$%DiNwNybgyvYYqG*sn<+N(s+P6ikY1!I|m zrj<E9bgj1%W<4fmXGCYLFgTp)=P2Xy~5&di^-CWp=+S1gtu`?$M75E zXBG%*&&3T05D2kpFM)jRauoBI^K>dtL9@9ox)ZvfaIyJ-43q*yquyY+f;Pc(wwb2Z?eL*r z0upJApR{v@Voh_zA{n^d#$F@X37rb5-R<5dD;k>5nd=Vos|uaUHIpVibUR}JG!Sng zaZIs@ZP3v6Gi#Fq1@=HOu1`(Y=(gMSwJZ%gLR(Ikq9%nb0(nv8JN+HJvrDulv`6bY zbp7{9uTP*NH&KD+ngW$lqbX!a`W(TJXjHp53@`U#TnYpVcvd7(i(l~-2gHTiwDl5Ev`!yAv zQc-NFY@2dDSNd?jf}B$njHUJe?d%%(>cc5|Jkar@{>cscRdByT^vE5)_Vb+(82v84x?s7VHM> zn5CV&STEGO7HCn9v6Z3vJO%(zi^R;tWkMZ!Ah`Hh-dMW~O&5CjpjD@4_Zfgl&ryIr z)+R6*x`Wg+^igtpptaKM4>e?{HwMH^sUXNIuoP>vj7lE?-04F+cIhJa$Axbp3#2eo zza$0mF1IibiIyH6(!4Sj$};_9Ci^bN#OcuvyL{$O&^F{7-ysK~n~oRMb@=DRoD}jjVJX zl)fc;K<12rwH>lu1I&s+^H|vqO(~itj^Y;QhRV!a8l7md$9eR=5cCe6%b87HESl!F z#xDd|rUD7XnTXshK^_e>z zgyE%PL6QzpkZs$D5E<9~LE%`+!(&bAEXP>e={NY!L!0und(%5lzk{eR`mH=BEcEXR zwhUE&puu2@ZV&h-G?;yG!0VK4orxswHOmf^Zu|x+2R--C(4V%o+E~e~r|*L4kZfNM zrp*sn2P@3?sj$SsSeG=bwk?v=1RtO{0^K3jgYYewJccNIWTG%YoIuT+#>dlvcEk4( zQ%*$6QB+6#5XC^oT6>V2Y6J@2N>Yj?CtB2gUbBF zEOXOl4V!Ub?o1W{lLRuuI-3=^<6q2$gECjO9_C@aeZTtmLF|QHg2=^s$S>I~-%gRo zfKvQ`W|QDROQAfNZ*E=v1C+WpM};OKQPUcnT1|T=)oR$q6#s(|F2_*-yM=TcwOaKY z&Z}SG;io*j$OE@XtiH;_1s-1Gf$vn`T!pc859-w4g^{?|F^dUU)+q{%arLRP8&gzeO_Pad%Z65wE z4;=C8KfnR|(uVE4Aq}vXIsOYUjZQx9I?EE2`+5I!7KN^(^u_{IX#6J-B-mdWn>tt- zuZ&d2DpS+vrzR`&m5ItI?oU*vaCcv2l7FWTP93V8s2r{wuY^BG4jsiJ$7jb%)90p- zPA4dFpfW#oYU;4{OkU$ZL^FPpAaXEa5SXr)R^P_2>eu*i0*8n79#{NiLQ#!H|No%b zzLZ2#Z4i0jjjpL+YM mQQubynz96kv2q33iT3y42(uLrmd8e?M=O)l$18^_Q~wtu)Opze diff --git a/PythonHome/Lib/email/mime/__init__.py b/PythonHome/Lib/email/mime/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/PythonHome/Lib/email/mime/__init__.pyc b/PythonHome/Lib/email/mime/__init__.pyc index 7779e6f6b08d4aff4c8077866af8e4e61b4b231a..a9c488f614f344b0bb4432c6dc62585b441572fd 100644 GIT binary patch delta 58 zcmb=O&p5%>(1U@2A=N4-J+maEG$|%Lze3L|*xxTGz&Xahw4|W4B*rB*sWd$%pt2+* NKhGmSH+7fgc5S_J?(3V!@1P2c6tr2R2gn$!5l!`+I?IA@%M3v0e-n4G*wY9sUij)&@ zZL0Lpu zOhrUxOyigY?>kgZ^ zIg_fci#%06ugsIj($8uw4-XFC%B)JKC3M`---9Lp+gqyUzwrzN4*VK~Hffb<>zY6P zR{y9nhttC6wX*)N6yHF>Nw!0Z01Sy_fIp^-4k!9O;*>_m117{hg=mmZDl5;l(H40B z!F~g_+k{z_dhK_ew_25H2S2*)`wn0C9%3G7y<8*vkUX#m`X=bBAcNE*x`=6x8bqu% z@6ZqMjy*umgPxd&b65z}=6JvnTqgot1oT=e^Iv|48ym8Hl1zCeb0?JqVoorvj90ng zr9aows;gChlJ!^Z-SjjR5H46f5W+4{#-_5Z!j8=JL~&`@akT)jy-L^is^_-A4YO4=+~;SZUch)o8q3h zFSf*h|2F{>1LA;^6_TW^vT4EF5Hi6HlO&^Xhiu`z!IL!g4!)OgZjT9$h`l)m(G$HW z7DwU!8}TjHMpi`u6iiM?uEFr&dOPG?ho&;+_2m_KAK|2$cup4~@xR7mH9RWqxc zGG3dhkaeo7`}c%j%#?U?{N%AntE4V5>qdSPdsz067wLcSIT=Qf`3-cZ-a^6g(`$(` zNtG(=8VOtF%_o(4QWsv&r1gFc!gJ|#;yZYfwPV5SgSou$97FuOevn9=WxmI2ZagFj zTjwo2bA;v)X}S#27FQ8@3?h0H(N%|De?vZ^mmT{4*RSZROPBaXblIUd9lGk#B|_V! zSDR!7!O+XKAnDLu>^}WX(DM*Fw&QNY>NC3#z7jg+xMd3=g{x|licA+O1aCAL2z;DL z^VE*!x%9&?MJ^pyBHZ3DL}KeST?lQwvYAZOzNk%BSzjCJRk0We@hsO);5W|~LD^g( zSqCZ1dXX!uu;kc_c~uvwI9Ea;kjk=KR$Uq1#Oy;L5=Xx$&gbv4#422 zCIlhXUODeV8i4}kcQ6|_(=kJ%l(Ufbsq#b4YFL>{FM||u3_#1|E5)bqteiDwCd>oG zLr5re?k=82XFuxmGgV4moRzv%X93-#*&^tPIVrHtE8R!DbA1qPMZ3`s`cI;SCH(24 zJwkH=okDS;rqGA#RRJlewYR9}K8;U@yxQ%fYl;gA6;oxDmG6|-dzF+aB_Yaq!Qp^1`tVQywrvt8B$ix8+C$LGGsHzv4MvH zI;<;!Q9w9VOc_8ks_P~ke_HswGU7!8mOX}FU7%vH$Z)sP`e?-a)iQEUQG3cGAK1vqp8GlQxlif@uszMPNi5T*yqRA0$)&I zCHzcp=B6dzCNo)W60Z@!d9ITjHH_fQz&e#J!%<}7YgvFU5Pi-YCRQfBmB!7$OQPb$ zDWO3P$W)t5FFfke3DmQYb{ejV{nic~<4mtq9fzITFv}z@d$~N&7ZVW5KAy=%QOOis z$$@b1NPM-@l;qOD33jL5!L-N2=G-7+oUP%<)`BctC1lEc*RUz)cm)7HWTx!F<7EgC z*NOqq!U890^p{8gpI=@d%cz8fwxMhWaVBxYU568KcqE-Vd~hQ{4-GDjG}W9Ig#MLU z%q#HjGK8on%V*a@h+BO7bsmH>elYuw?_kdXTEqHxwgThtM0cX?=w!$W zTTcz@6`lrP;)ZfC3>IU&7RB*69G72R{5HDArYx15FPKPDUGNU38`@Ofl9eFz_qFnE#iQnJ){wcD3Wn^op#gxh;|&IqHuyM ze}_ND8NnN8wW)eQwKTI{dpz^r^Em#!+xzwL^Lawei1B>|<0H6~XacY3Qqe?F8c`Zk z9#Ij~BqoIo7t_2$GwgNf2hn$;Pm?W5x9EJ(l`K!;PAof}4EJ$<8j;gZbe z*;nhcs^p=6fI!)i;OsBPKw-si!xfI%Ub+^dY@EROF`NTLREGyRB^ZEgbUuhA;J(!p zVZ8nMVS2T}k1!5}DT`5{cG>d5OTSu1Xv52z5Jf@!!LSk8k7DpQi{vg%( zDr231sIQlahX^)JSzG)tceN-A6(54=1^Zbo4R_~>*;2UuiTwu z>ky3!-d?*>&+4ks9$}`iS?Q5FWH!9Kke@b_tuL1as`F6m<223WCTy-3wzh@y01&Rr z3-qRht=*j(ZL({3^QEeRzfIb1u_(LG&-R%gVs@J|i|{Xo&%?%T;%5W7ic#AGr|TXF zZDLGTX5JXzLkNU4YjguC`!JS{rR~1zt4AuJZNQaKuK{OFQKidVex;F(Nvp(|kYZEr z9yO)XE{ug;S9PPa@VZ7KXOr3HIjRVofH^2Pl1DItt$A%q{+D5(akK{hQWCPfZ1U5UrkFZxUk@BNPy~h6@WyHbRPWiV(!|!2%n!4nnLfP1-ZPyJOFEuey6! zjbtu3SN;qK{un<1UiHk*+BpP9-g0+OSJkUmA2axSfA_DSU!P^vJp=sz20#B3L{2n= z6toaD6O<>E52#FNh6VnHR1T;b(rieA_d8VXP&K022zx<#L~|&O=nc^g(J!-mtbR7W z$L60x9G1#^>GaBJuT3b-LKc-;=%-)G(5$pPIX*d(xy|YdZ~Y`ZfDWG>^QGb+Jf~xU zvv40mo6P3g`S#?XyLxKPNnM6wrChiZ<4audlJyWHP(sF_^pGxhIOI17b41g#F*D-7 zf@tB+t&m`Yj=I`@#zf1IBVA z=y$=dLPU3soFr`LdPsi^NML_CA~qqg84&ioiexhc|0iNNbXo;1m3arpligj}J!#BD zu7Z+(-p)n-eLI=QxJ~Z+lxAoL*>|YtB$EFPf<9gEF~t zx%{ySOKaroqFO9-_qnWWUYGhYUotFuJHEb%b+InWk`1al*a~ULR9QB%Fj-l%{UU0~ zLqJ8{JbA^XwA2d4G3ibH0K0Boc(`e7Eg7L->8zM{*y6g#y5KgBe=Ssmo^}VlIh2>G zbYKttS=v=(%ip{G7L?WHxK#4TdCJnsA;6`YUWRBRnE#N=n16BeXj+PchT?KKKJq$|~wR^{U_P%F9g zcTR%sEoDn(7COS|G-R-G+s2)92-O`As`OT>Jcr??x6`MIgPd#kxGzF&x)L-dlZBdRJ z3Q_e=%N0fxYN~U60UI*ovDM>8N1!+AELgW8J=D%H@45oh(Cn*&a}+7+gGO!kmfo&W z{~3DsFy_YCAQv@4>{1^mV^@TMCrs?t(>Pi&BZx5fbQr}K+*I*wy;LF2Q0|B$=d7D1 zxDlsknxd&gnuhmqay#d2JZgJg&ciNt+sV*sZeZ{b-qd{H8IMXrSNJiO6ovl;tI7HI z#l^XIS#h%qCXegM(=#RP)iNEVA2 xUW?%4&33}kPK-6x=7SXJpW=N>&lc6YiHfwpXaoP6y?Lf$lsriGk^^xt{1*?O75@ML diff --git a/PythonHome/Lib/email/mime/message.py b/PythonHome/Lib/email/mime/message.py new file mode 100644 index 0000000000..275dbfd088 --- /dev/null +++ b/PythonHome/Lib/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/PythonHome/Lib/email/mime/message.pyc b/PythonHome/Lib/email/mime/message.pyc deleted file mode 100644 index ca2110e43d568e48a925d2de2b722cbf96d7aba5..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1403 zcmb7EUuzRV5TCvLX&cd2`ylAc(g!)Eq)>eDK|~D|3Z_C*P($F{+-;H#cYEP>QVI0Q z^i%jj{9=9po!PsjEePt7o!rjO{AT7ivse3hxAo)WmwpV@Q=|XawA?9)1Ykf?z(l}6 zKoUSwgEWAw27?+1-q#_mL)L&ngZ2V+1IA?7fGdC%z~?~|k|y-SErvWK(Mgqave5HF zJ8jX}iOjTfYNC&x$?j?QL?(H>$mqzm@eVn#u3K7|U-X26l*o9MU#ZxuOwV%LU8HE{ zs=!TA0Uf@j3R+pU(Yo+xt@Y23Ag%ttdFqf|DL*}|b55t^08I#f2+G9SyT z2Zu5*q}m`Qx-b_yk+E;Z5Eh;*sJjOTiMD4TL1L!8o_&uE#Ts{1!#V8jK=r(Z;xSk9;J5FRD)A4xMk9 zN1jrJsNyN|U2z&CqJz1Lm~%h-$aCv-I`%I-C1u2_2O*t;7w$2=wTJJ`Xs9z~(qU#Y zJzRHWzU(p3eOiu_gx0=zAa-l}LCE^53ac_*RS`v5o-9({^2LrK`UXUi2f2>~h^M|s=Vk5J8U2j~U+BxS Sv{(MJZWBl|*a`N;Ui~+eomqtd diff --git a/PythonHome/Lib/email/mime/multipart.py b/PythonHome/Lib/email/mime/multipart.py new file mode 100644 index 0000000000..96618650c5 --- /dev/null +++ b/PythonHome/Lib/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/PythonHome/Lib/email/mime/multipart.pyc b/PythonHome/Lib/email/mime/multipart.pyc deleted file mode 100644 index a8d371360e798fa214b187da3f317ec234574399..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1624 zcmbVM-EP}96h4w{w+WW5K#SgOICpc4RJ$Hf6kEFuD7N$>8Co=Oq0l02E0IK3q>viO zuG-tZ&YofKvj^C|L&lmgwc_i1e6FrV~k#qIs;G;k;DN@xnHI^z`Uw zuG-QUYt{Jg?z7*l4OhlFwKOjE2UsF8N86C%Up&(Y!~SMJCn*QMBf-Gy7>xm6ut5u^ z=p^A6(>w4T(ecStqCbb$80)IyjnTPe5OFf{D_(bo#uJ@KbQP?+LT5yO!k#6`P!`iw zLd`Gq<{Rn!^y)VKF_ww*gs#T)HlpbDA-$*(98)t3Gb8EC3`Sx4$yBQ1{*H;BG)8&j zSbfyQbbp`w=kbQMStwX}$oU5r21Q%*5Bak2D_%EtZJHs)6I**z`v<>EnN+Pq0Uta! zjVo-;E2A{J*B~?3&O=EH$9`pa`)L>9bErJ$UE)yx!!6CCUb43X_*o$M?X~oC+tyk& z8}8HZ@(nZ2H%OB*@6>bQv0zA>t1@p(*r-`Ku8q+~U&9ayvN@fAD0b#`YwFxEBouYw z3ss7$E<(1n$Xu&UX_W@*Q$OHTt@At=+d#lHYF;AA{M_Uyhimhdpers5=dtdkZ8=Az zDlgS$$5nZ+5Luhc9jLdRm))V^`G#8;oCA?AetHj8^(%W_){k0)ysbeW+!f|gxo{>$ zz%F3!S?A3*-dC}NPFb8QDW^-v9_}47k3j4$H6i%#h%3*3z_YAWD1d)Bzy>v+6 z_pqaf>OGsvaXKDOd6tROSr(2wvIKLz9J@}R|3c1#@!7WO;lAl_}In; z*rCAw2GaB-y@0Q$Xec!9YxL6DZ^e9ODpi!Ts;JCtV4SWu#{zc?ulo`W-MKs7izm@R zbSIibouH0KR>N#)*+)>8RaUp9dKq}*}%R3ZW|7pDuCQ#6TtKZRV6 uqskIEUtu7qNkvUM$3+@UKgM_`dk6mi1_XHzJ3)`6fKDnjiTC1LqyGQ^%&M~h diff --git a/PythonHome/Lib/email/mime/nonmultipart.py b/PythonHome/Lib/email/mime/nonmultipart.py new file mode 100644 index 0000000000..fc3b9eb4dc --- /dev/null +++ b/PythonHome/Lib/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/PythonHome/Lib/email/mime/nonmultipart.pyc b/PythonHome/Lib/email/mime/nonmultipart.pyc deleted file mode 100644 index e50c707a0f72f091fe11bb5453a1c8a561ce9ffb..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 841 zcmbVKO=}x55FPDTlR#649@?XhOQG9KFM(1@Ob&tChxH+3F>K|PoNSR+W+exFP4b)a z$NB@38LjO$&_k&}vl{7X-g~2sf4x3>y!o+&nFj?bM7}Q z#f@@KTr0=@jqqIbig(s?v(~;{iQX4}gtrMkwcTX5+dkpQ8J_qIgX(+RyCFZ=!ijM2 zj*w?K-8({~JJgC1eK1mtrpj3!5uhOCU$pK8efscHchS(j-5gVmw-`LYPb6V*&)_bw z4Fps78BfQeBbUN^(cEw$W$Rnp3C-PlL9VeI7W>eB{DU^=D}(3vSYqFcvF&bE@9_RP zwIRTKLOPUQdU}AB*k~(cj!Ou^aan+a diff --git a/PythonHome/Lib/email/mime/text.py b/PythonHome/Lib/email/mime/text.py new file mode 100644 index 0000000000..5747db5d67 --- /dev/null +++ b/PythonHome/Lib/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/PythonHome/Lib/email/mime/text.pyc b/PythonHome/Lib/email/mime/text.pyc deleted file mode 100644 index 500fcdba1fd019682a37fdd8af83f0fdad913507..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1263 zcma)5&2G~`5FXn}fK-%nf(z2BrwBC$E|dd8h^U83G>5bjB8p@--f^>cQ#Y4yQ~>jEr~H8~x0*zGxqrrn~pVu2M}`Ok*C6tpr@ zSB_g>yPm$}8$vzLfl2i|&lcc#kdQKo`HE+sWxCQn%lr;06rQc*g{h?q zLkt-ln!@uB69&`-wWK#nn|VMk5QKY7U+L_tF>X35o8&yT$Y6dH^u&=BG=(vbWBJu>c!)*=@YiKnWZsQ zB`hp=oHlD~-6SmXBXSH#Qbv+ibyaTmHZVD%`v&?=Uw= 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/PythonHome/Lib/email/parser.pyc b/PythonHome/Lib/email/parser.pyc deleted file mode 100644 index d660d508f71d2830ea40490e201d0a607e0f2691..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3789 zcmbtX>uwx16h5=JWYdJCtw1UlVIe`bQWK&4p+cpCrY#gHZ8b@Wh$3w#Gu~vfvonkB zZL*O5A$<*AgWo&=PXiAC-#MP0O(?VhHX4t|KIiycK7V%Vzc0-Fy!~`Drt(+E`*S?@ z2Q&%M4%&c{8tvC;2c0@44a(53Nxw;1odylsX;8p(Ey|iSXwgo~f6q`hLxWk`nZ-BM z=O~$_7euE--|n>8u5MEg6YXjgA`RN?Tw*6y(0rkWk+IsSqNl?9>uT-h+M0^;L~T6S zxTo|WN;5Uk)<*lEM1%`b`QqJDk^;m*!3b&m%nc z5=I=+NkFGC6HvcN<~Hk{)TrMgvqBEzb)Nk(pj;%8ookqe&@Bv1wVTwhkvZWSl-hmK zo;j}_c{E@h8gntL5W@gC6-svozQChAM{aLX>4=g|x)LJ|fy1!}QZ9d3wCk zGsR%JG_!k~+RZg2hnoD+cihvB;;lMOpDPt_7L56sZ%G6#K<$c92or%61 zXOXpvEyIZaK$_Fsx(I<_AAgLT&*z4Uo7xQBotWoR%P-adZrOJ zk_0D5u~hLOa!L>o^`~)vuMLWA_D2JN$imWH-HS$Se?A9^;2OSCMF-2?V!5> zt#p`a^(@Lpz$}N;*W;tY0AOZcEqmGJ6ta{u=?JxP5@UBU3to2FUV-vfQ80#)_=)qv zt;?lMHOzq|yh~y!W{07a?&pQk$#wfK3_Z#9@emsdP&wnS&&R_K6DIh8C_{eQyzY3Y z?-^5=u!*mbiBGuqC^9)Vp#@J6@rPqC@0KeAmfK!HcvFO|&U(^81XkAQA4wjF(@FMy zH0z)4J|4S+B47JtH%s?+<#5;?%5ktd9LvhxZkngA+vWAV{?e6TK3EJc2h;Z=Mizp( zS{v_nFo(ZZ5OZ7{1s7wTwYzATe~Au-z@LK&L2Vzo_^ppypKyY!g(5aLb##zgSlhqTQDE!N-c@M3ls2=e5nq6+XHsw0D~fQ>2}C5c>w zO#-1_nw{NGA(#QYkY!V`N{K~xP8FW3g@OM^C5MzWVT&AW0t~@} zEZSEVP)U1Zrd#YwAqH$?>xyAzjjO}+Q4b^ndW@0@IZx<}H+tbb0|A`XhPxkSR^O-$ z4Kz3!hEnG*3_cJhd!&f@kGJe3CZC_l!I6?867Ys~M)8X86{ybGom58(DR2uirETmWuSc{-gT?NCm=f5Z^^3bG3$Erc3f z#$$QaR?z-v{z}Ya{9}La;IRsgmiw^AO%GRMT!ZVx{mGRW*I<@@8IxBr3L*uI0-2ym z>>Jz|H{}xk&?gcSM2#lN$cTskeFTKRCs< z@E_O2DbFN)?1t}g!>jziO7d0Y8$6aV*$U?C9u7=Ujt}o{Hz{I($@g(!07-m~%V8dG zmj5vcz=a^?gk7C-neeAufQFwb&ki~G1x6uz@E-~\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/PythonHome/Lib/email/quoprimime.pyc b/PythonHome/Lib/email/quoprimime.pyc deleted file mode 100644 index edccc0cd878127a7bf2b14203400596f19c78bc6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8785 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 T4*_-Q@)~Aqqc_nGjhy)(!1Q}G diff --git a/PythonHome/Lib/email/utils.py b/PythonHome/Lib/email/utils.py new file mode 100644 index 0000000000..c976021e0e --- /dev/null +++ b/PythonHome/Lib/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'(?', 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[^?]*?) # non-greedy up to the next ? is the charset + \? # literal ? + (?P[qb]) # either a "q" or a "b", case insensitive + \? # literal ? + (?P.*?) # 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\w+)\*((?P[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/PythonHome/Lib/email/utils.pyc b/PythonHome/Lib/email/utils.pyc index 15fbd0b03073655426dd75835509a51c541dbeb7..da9d3ebe0b066ee43c0a0d1e323963e6f090d4d9 100644 GIT binary patch delta 966 zcmezEHrsoH3X7ow0|P^On82Uo>#EHUr>N^jDKlKL1{^hOKMVSdQ3oN zNk)F2M}BVV 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/PythonHome/Lib/encodings/__init__.pyc b/PythonHome/Lib/encodings/__init__.pyc index 9d5e1017e792a759c9c9371b187b7dad4c7ae083..b7380f5f9a2138f90e73e704ac7b41bbe7da2659 100644 GIT binary patch delta 246 zcmZou>QmlO&t~Y(z`)>Y6_cJ>l2Muz6P{n8=N0Vl7Zl(e<6l}*P+Ah>lA2VS9urVm zl98Y1k)NA7xsT15k!ABCwv$X`Xx=9vJ$Wmq9;5K)C!B4pa6%$Zdl98WhWIlNVn=vEv<|k|?nXpJnP5!~D&&a-6gR6}d SoAla>Hz>*)*!_I diff --git a/PythonHome/Lib/encodings/aliases.py b/PythonHome/Lib/encodings/aliases.py new file mode 100644 index 0000000000..a54cf774b7 --- /dev/null +++ b/PythonHome/Lib/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/PythonHome/Lib/encodings/aliases.pyc b/PythonHome/Lib/encodings/aliases.pyc index 8157ed7af0a5e14c1ad7a54053bbcc2bbf162bc3..31661a3de39cdf641aab9a41bc2a9bc7504a331e 100644 GIT binary patch delta 62 zcmdn%a^Gdcba_KJ1_lOKtC;l6l8n-%nDG1xJ+EMYzn}o;82{3eg3^*0m(--v^q7Fk Sl8pR3kNn)!&CBGcGXVg=Ru=C7 delta 28 kcmccbve#w9ba{Ri1_lOatC)bwl8pR3BlFECmsdFNS8USjZ%q9Q; delta 240 zcmeAc*)F(2mWf}9fq}up9;5|dk*ZLx}TvmC%GF2ZVoReUOI i5>{~sHtgcB*(P99zxfEeJR^q0IZlbmI-G@A#BBi+EI{)B diff --git a/PythonHome/Lib/encodings/base64_codec.py b/PythonHome/Lib/encodings/base64_codec.py new file mode 100644 index 0000000000..f84e7808e9 --- /dev/null +++ b/PythonHome/Lib/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/PythonHome/Lib/encodings/base64_codec.pyc b/PythonHome/Lib/encodings/base64_codec.pyc deleted file mode 100644 index 8c080b6109f9d5486ca47e934f900b15d4f05b3d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3633 zcmdT{>uwuG6rOcrJ8{#r1d51=V8ovosSQFZNFY=-O5Biwl}08rQssjWX5Ob%;j9ZbI$D2ua|p2J^J<_RkLRazqirc z&*(Cx4$(&{YpEhqhadvoQim;-Eval-y}&pK{I`W(R#``xNS(CR2$Q?&g;LLz`sT2$ zvK3);gt59{bX3+8Mpqb@7L2aS)|6=rZ$*u8;^hTzMP=)A-m37fEO@IbyULft9tA(> zzd?OoqSIeZ{c&CC?P21~r#A;_otbo7@9{_9&|y@kb>&UvwYN#-M#gGWVPak#^?Dl5 z*Hw`}F}kds*Y!yIW20+y7VEH$(@&4{^jQ1E9vP3xIft)fTJFLO+2mC`cOl*2%x5}*14^26o*dyI9 zlj3#}UUt&D{1B`1mw5JlhvvXxsZU!V>2bC_4u6d9nYj5$OSui@mHIJK9`0#EbYrU#Ao8C*#8Cem(Kvi9u-Dp!#)P znCb|M!w+s!nv9~8&Bs_3|?o8Ae22uTGbbcM(u5-rvysqw1 zd~ra)nqLD~;AMjQVOOP~f1kg;jZVxbOM>n~2E+BiR?@lmLG3(#m=7P%!Rj8L2Kml- z>Mvu?Y%Cnf0Y@~b-bQpK`diWP3(;^_@cPf8Awa8~AQFd+kQstzAvm`6cljKQ!_ffo zXibt0C!>WgK{LQzQTv_W$DzBfXUus(G5||c)^@sBUIJ+*)1$lq7869D`93LuY{$ef zUl+s>Xfg-LS^r}|$8fBQ8Sw(%kdgv;V**}~8xy%Pp%r&IhITQahV9?Q@&MFz0#)K- zkJ&cm#(XHx9WJXJ-GIC?R=K;lZFv zN;4RE9yb`2bv7yR8q-oSvsi-lVuEg~Yz< z;I}X@IM|3^!~FwJrJoiCq&>x-AAmsNIuS6ird?w-V@+$R6BMzCH7!)I{U&P%=q`{R z6C!6UEg(b{N{UARbE!_deS#*ctLR!JrjD;*D87nLHol(}&WMSd-Oq1bUU+Wu2%4c2 zowe;!Gq#NhhDPyonUzTV9PQ7{8ovqVh4D(%ea78q7G=O4u$+{q*#O~5iBuB=y}AP z+#`{9@o|7?%a(a-#8-lsPXxdm9|yS2;H$uQ@rlqq=o1S2U@OIxBSof3GlJs0$q*rX z+OxwUlUXTFC`<6rQ}NKL0p0?P?bAbYo8pxn}obzeO6Cf98&Nme +# + +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/PythonHome/Lib/encodings/big5.pyc b/PythonHome/Lib/encodings/big5.pyc deleted file mode 100644 index 0ec9db0f37fdebe03c33b8133035689e2b72beb2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1665 zcmcgs&2G~`5FY=;`Kgm2#7_Z<1E-vNe-R<06{v0KAfBATyW0b!zX*>=siK1F|C~~%X zmm-f0(ZVO~(gvmmX=of;1T=%2Pq#!Hq90K}xT)>He8MPSV?wG(-ng{zBy$KpMLwy~09G3C=eC6@j`K-o;@Ea%k*)Ogl9%j| zaC{p;GC9j4LItsk0t<;$zJzo({+dq5;+p33a?Ci-uGWfyg%~A+51h7RpF+6Elfq;s zx0B@;iC#R;gcGkbiQF2!2fcE65{cs;0;mc9Cm1D%2;7HoK1+tjgTu%0Y!43CYGeyD z$&{IBb37nzY(4P+uo=X~1AcmBL2GD0HGeCE z>kUFDgS}{7(AG9dx47>&)Eo^s-HK660fiMQZhOTYFHMo|dbDCd@lai{p^#FQa%MO; zoY|h@MrtR!34w%FrRCj+Ot6c5wi1r)HdoxCiu*#bo8o#L(BSq2{&NF3bMUKJzs0iT zh9{6Oa6;UH+yhot%&$8af>h&Q=BhuXPKtjnhZKv;{Gs~qedM~A%*9hDbo=frzwNy6 Ic)Y{?7vmK(bpQYW diff --git a/PythonHome/Lib/encodings/big5hkscs.py b/PythonHome/Lib/encodings/big5hkscs.py new file mode 100644 index 0000000000..350df37baa --- /dev/null +++ b/PythonHome/Lib/encodings/big5hkscs.py @@ -0,0 +1,39 @@ +# +# big5hkscs.py: Python Unicode Codec for BIG5HKSCS +# +# Written by Hye-Shik Chang +# + +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/PythonHome/Lib/encodings/big5hkscs.pyc b/PythonHome/Lib/encodings/big5hkscs.pyc deleted file mode 100644 index 579c76595cd09a381148e5f0f1d9650ede56ef72..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1705 zcmcgs&2G~`5FY=;`Ki+&1gQLo1E-vN<5r=Hz@ZZKusKv%kxb%sQm3(lyj!81!!z+R zJO&Q{-;5h4YT=Meyx#Tf%oGPXuJ+Bh@x6{C~`J> zmm-f+qPb7nr8P_q($F|G4`>QEpMDUniM~Vu=?0}9&6{Fw(bOd!)aDjx7+`LTxg+LQ zZSIhUArOxv@d#<^k?zzUA!!&YkFIzei$_>{9Fy+yB`Jj_!Rl1hJ9G6&&zEKLmU_5JdI=9kx9PP zw+o)KL&E#p08(18EFx48t6g9rk<2Sdr=w5VWF)RxF*BnY?CH0aVss(8;iC(jwqqYd zxG0h`&C|k;7a!#p<->3|1$8))TZiC5uUsBP;(hl<)x@Gl=!W+R-20e5NUR6O#HaFP z2NP#)Xv=h*t8}c>1Eb-pJE_q)c8lh!%;qN$6e2i<`6=NK%w4qD>{dp)us zJv1PqzmahhGzcXQZlk6_YTG2;VnVE`IqY-HmzE2PxuNhS#e7gq1*ws2TelT8%KPey zCZ*)d$m!t(ae6z7?~*|In=ni0W`yShX5K|HT?%iuKUZ9^iYr7hNX7Zsx9IH=7R^#% znt^!b>NTc@NkCv_;Dl&_v_31Vd!d3BU*9Ovak}IDc44#0$_hsk%OuPviCik!T~;X0 zp@d-h)IM)kJfyt@_Ftzv9!lW$>F!Ru#E_Ky%Uo5eBunwFvvND&Fh5V6 Q(CxX;{kHSWbs{@!7fUxqRm`^PMA5-;ubw4dP?-wL4%T2nP|$y z+I*r(Nn0jbGI3@;(W0b7x*>C`G{P6x=X0x+Y|Q4?WNvdlw?@fXemQ6}U6Wn{`+JqYUW>hP{jp&GyN6MzH71u!D{T{8b}5S zw>=(y58V?%#={!fEpkLZ1mu8#8a;vS1Nt6BjaVNHwe>m`J*c!8 zPn-zvwPjVL++>_-)h#Cub0P)X#VhWj%5-rEwZ&y&C%I0Tb)M!&8&et!HICAv`iu;z zBWO2c?YmM%<8e0asoRd%MUxD+aOM1nT`&9YVvDyotSd+;vZ;zE#^}OaL)38|bcCtBnH?Z!-JP9T5=fR`EMSsSHB!E>F4!I?)q8L!9X^<0+&-8)1VH23Sil1^tvB&z835GY3O0j(6#zdo0B#7t|2qJ9 zH02Yx?vP!o0!`%`V^e;c&hR%J4dB2=N6Bz9nwt;w2<~OG()Ir6xb~u|CTAYZ9-HgD zG}HO^9N>b>j?xV9i{NnjyC?^kEk}~sKF@}rk%NYO>m|l;2*XmyPA+KT80JH3$Osq2 zhK$&dffcrR3~gC}`q20mHhO?=FhIo<_BbrZd?Y{2$8|KT&}k$Fge%EwoV<`$K-a27 z7WO@JSV%ED)~xM;w(IB+-w^H)(4KM}V>$Pw57{@pFS3kQXQPFP%Sgv6@vg_A)iU!G zEXfPIuot8Q>c#o+8h#&VRDAdd#i9-dMU?BoKny$>0LC-`fJuYHMa%gb`cw$BeX`DPZj2QyI#P$=k2Odlz6+MD5*$F?kC$*Ov5fW0 zO$^)v@q994dqZGkwHh7Qxt!rw97Uw zNrj=9iFYlucB;Z88w>_%k-EX)Bkc8F5Nri&9xp8DT(pnz0@Rud%=|I_Aygpg8HrhP zGYV&3C8UoP*^Zvdh0NE|yz#kLd@1w^>%eki X0K$XLN@t_9wcXl2yS=$n-)Z~?wPuy9 diff --git a/PythonHome/Lib/encodings/charmap.py b/PythonHome/Lib/encodings/charmap.py new file mode 100644 index 0000000000..81189b161a --- /dev/null +++ b/PythonHome/Lib/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/PythonHome/Lib/encodings/charmap.pyc b/PythonHome/Lib/encodings/charmap.pyc deleted file mode 100644 index 55d7208b98da265db2c1bb3c8f70275b4f2b895b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3278 zcmd5;>uMxL6h7T^%_MPkR~I8Ilq^C=b_c{Cf-JHzUI^@tQlo?&0%NDUGSi_iLv_u{ zK>j69;zRgiK7gL@bmqbk&Bgq%hpMTnQ{Gw>;Hh@d8d=0Z@TxFv$R2-*ulo#G8LzQ`JM z!W(oJvIfPQb6HblTMJo};%#&WEhyCw-hr+UJtFmk$&F1S_0!Cai(KuGLmNiUSoJ!b zOp<)0_KVm=-A+gG_e*J%8z-fTFsS0hn#iRyWkWaSC2kz%T-jne8uPzV;nWpb=#ofQ zM@9bD*fQZ`G86IKq|8cHPA8KzF|j(HscD{I=U`Wbd91o7uX=oX=g=n3nH;lThcI)k)TJ#NY`-m&USb9MFv_^xvG#WH$lI{mArJ%)? zYjZUm=3!=rL)Vc`R>ad3-6nSh#nQnT42R9a$*{VzNH3eKQU;yj5oy(|4&(JCEm5s| z^eQ<%lGSX#^5}Bw?qsGh@jWhOovUVj!*dV0agayWWF~iE`kf$d7k37)<<3vJQQeu@ z&2(mVU-&d&UNa?qx?q|&aCvMj`jw7ZJ9L?gM<7I%eYNj{l6X`Li_ znBH7pFcb=vIFr0y07_{p##;q9xUdzSTAYU;9&$yY_0KZST+&?kIVpkAD!|C;dxq>&c z5j^5kXn8dq^t;#+SJ8+78q;sd0${4RELi{&_nkFihVX1|WB-`LNEJ8g^SDvjAI>r_ zV*jT+ux5Xb7VL4}S?%9~#v@+0LIH6?@j9T+;fb}rD;qw;4%m>q$5(`j$1GTei7G~j z#`DMqZfh(TXI!VK7$2-y+UGh4g->_6ER2tVWh_`R{vEs@Kth$u?mm0}((c-X@&C;3 zAK>ajbcwbLyX*HMSb7`xZtnkI@Z|fkI2`XDERJoygi>>N|3{18!P5cZ=hz(JHQC}3 z|I3G%BwqOyH!6--i7w{^PO_o6E)7l#8hCZ$Ch`GJXZgvF+jzy#snrh<>U;7;Aw81k z{4!6eTmnkVBa%&zhWQCNKTmL4(Xk~zXomnb}NZvlrYg5r4_s@S0pu;}_s4x%_Y#7twH7r8}4@ mInSCF8qfVLRlx}_s;u*Cs8u4mH2tmmPHU&V(|)q?Wb 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/PythonHome/Lib/encodings/cp037.pyc b/PythonHome/Lib/encodings/cp037.pyc deleted file mode 100644 index 6c14032d11add558185ecbb1d42723c38f7116e7..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2694 zcmc&$30E9N5bix$76`cw3F^j+^@3>Bc*ICpAfjP|vltRYH^a^>Ebis(Afi!8AoqRW z_kG`xJMUHfB!57x>Ipj}`gr1dK6mM+rfa&o>Z`A-*7Zk;f3Rg)BqpAGT=c)1MsA2E zO^8;S9YS-8q(iil;1aq+bU8(wWVaX)qF;!mtxlnNq{1Z?-n_ykv;wJcONB45a0{(a z=uWBgh&UPW=XD;T6%FgWQdgYUd4*QO53L148z)+Q(g0cViGFg>&z?qtr5r$xra)7# z*_lZPLY=Ci#!TG^G^*KbBHa-PWi&k&h-GKZo)hTM)4HLWx)z8VnN*;naeh-%LwG@? zYH?k-c99aPYHSEa>YJ&`93sj_WhqP=a{O0G@fNjO+LBrHX2j$;>&e-nhlTc2{DkS4U{ zk`$kIUt!=C22LrUX)OL)h8d|R{stKe(??S@npRVKG-~?gLn@qO00}emob>a{Ksvu$-0 z)a6X-NIotX{h}ZeWD0~$zCv6%B+q4Wv`dC0Y{I_uR#`TlUAC%{A(KSCfRaRmP#Uq& zBeN!tw8|wPE}Kt7I-Zf`#y(czd!sM~6h=bfY>Xv+CR4IQCr_yFnMUtSddx8og`?2n zbrjRrE5F@+Odp5S1qTaZ_3y9;Ho@ki;*xQt<0nj<1czXi57ta8gYB@T{P`DNgg#gS zE1@3-{LjsRwXhD>!v@&s@fN^V*fte*z)si&yWOxC_Q8HQFnJ0bo*sascpOjSQ9Onx z@D!fGYjC`BZt%_Jui-g7j~DPPUc$?G1ux=}nXkO@`X_Ml?J8V}1K5Wvupd|98r%k_ z-+DDV?=!rO>u^18z_qvuH{%xExa{MXt1CWz3HPe)F-?zmbSB^e+{3H*03X6NxZ3r7 zGL_C`e=y)Y+{M#y8&|_gxb<7k?EbOmr{1687(BwQcnA-}#Tj4tH#ND_Zci^sB@4P$vz4t$u^WjHu0}tRq+=u(&NRYEd%;XlPWn$E_ zxaeDyu!+DNu-GtzB`#Vfm*?SM4DH>Cq-OO4S{*@`Q7^jeoO7*SInPD=a@@YC-?__t SW$rR}xvSh$Sn7Q&+ 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 -> + u'\x81' # 0x81 -> + u'\x82' # 0x82 -> + u'\x83' # 0x83 -> + u'\x84' # 0x84 -> + u'\x85' # 0x85 -> + u'\x86' # 0x86 -> + u'\x87' # 0x87 -> + u'\x88' # 0x88 -> + u'\x89' # 0x89 -> + u'\x8a' # 0x8A -> + u'\x8b' # 0x8B -> + u'\x8c' # 0x8C -> + u'\x8d' # 0x8D -> + u'\x8e' # 0x8E -> + u'\x8f' # 0x8F -> + u'\x90' # 0x90 -> + u'\x91' # 0x91 -> + u'\x92' # 0x92 -> + u'\x93' # 0x93 -> + u'\x94' # 0x94 -> + u'\x95' # 0x95 -> + u'\x96' # 0x96 -> + u'\x97' # 0x97 -> + u'\x98' # 0x98 -> + u'\x99' # 0x99 -> + u'\x9a' # 0x9A -> + u'\x9b' # 0x9B -> + u'\x9c' # 0x9C -> + u'\x9d' # 0x9D -> + u'\x9e' # 0x9E -> + u'\x9f' # 0x9F -> + 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/PythonHome/Lib/encodings/cp1006.pyc b/PythonHome/Lib/encodings/cp1006.pyc deleted file mode 100644 index 956d036ff885349a44f67d7ffd32e35cdfefd655..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2780 zcmc&$d2>@$6u()UhL#<)P&K#_w-#J*Lj*#>Dh>4oS!y+;c`t1+n=h|o6$NZjftG!> zLSYyXbrM+w?7c9~+;8B2%;ZCyKl}iA&V4iw&;en_G0D5V_nvpp@;kqKPCb9t2QRH& z7fZ4m9}oUrh)?k{4mx8UIJ%hbW*Hajz=?+$F1FsyQaJar0mk|nTifAgx=#r_O5m>w zJWQ`q0uJ$Z!}Rg2BcK$ZrU2_l z2ZQ8kEIfe%$lwra@3VUHxlp7hVJ4E6VTRfgg+e;l9g5_2BN<8-=FXWjFVt=13^QRF zdMIV)v!U5-i`v^;qswB=t6HKiR0!!@q1RG=7^aywi(wQpH540g*3`K?-PJj!rPyf$i9py#6fWaP9|g}`_Y;Li zM{n^Tp+>mXmYUw`zedPwgq&7`!#z1{YbLC2I2tMM|%YB2nfx6g8?% zPN;VQkoYwnpMM5Wn~0+O;2_~PZA>d-M;VD(rjf|5Hq%%ntK1`IEv6SKkv8|RLgAb# z{y3?00#dWPL`9UKBBG+Y#lB`F^#9&IRnSJqel=W5O@#Ir;$Yt$yZ2$&qbiG+2(OQK zY>q9=MUF zPuLYOPxv5CH*IWCiBmT1x=Gem8*0s^@~Y}MW;MDz8nHklC^X8)J!Q}$UUnPk3bsJY z?3;zlB9W1~YF&O;9e(}l+xrJm$mRBUeg2w2ZE##&{rCwJCrzF*b=vd?9&DH~v+<#a z9|_HR^s&dEcyf05si&WL_PM6!Idh+X;l-Ecz5L3nuf0D1jRkKmT(mf{q-E){w_4wR zXL(z6Mfh4Le|0t8qRnAu~RDP{otX!&GuKZRRy*7AlSeCAh0N(<92>4F*+XZ|Nlnz4a zFz|iA4*)*|rPEM41N;c^Vc;_JG(2;sA(4AdY|- zhVou0?+0-d#0ZGvAWncd3FTuTPJuwvs0xjqhVmIGqZ>Z~-wb>kaC88bp966o#04my zg>o52ufXWlFr^>KPR&uzC$Sk)H?c|PP>Wb)^J^x}s1{mO_Q(Dk>FP~qbi2{u?o9-| lbM;V7dA{9-7kKbsks2d*Qg1_`!Q0?%^fdZvC-|>3?_YsetQP

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/PythonHome/Lib/encodings/cp1026.pyc b/PythonHome/Lib/encodings/cp1026.pyc deleted file mode 100644 index 38f110b8734cc8ebe0196cc91c84523d36c3e41c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2708 zcmc&$33n7l5biy*SrWpnfvAgD)++&2ybwb+2}a2hXCr|aT_!uT$>LtlPQ)lmAmP5` zJ|*1u6^?K!?^T6g#gG4bGW(f=xX zbJuCmglM7BAvC8*Iz$TzE}=Wb5~qlh>=wO3^a!!2#VIt8G`OU}n>VT~F(VYU)}bZe&t{@`gE$ zjrHNVk;(ftgQ~!)Q2iVjl8O&X<<`&U}?ha;Po-yuOi!3;rA!* z(-Ss5biO<#kFAq5)$Ce;2AyIc3?;n1`XgA(lAAGWv50((%DW^`k@;}#>fT9DCCeUC8?ryUZSmaXqQ~8g(v}GEs?m4;{7;y;dq)T6ka;a ze}bCemMSR@_g`V;6-G`epy7!ewsvN$9ylCiFial}(P&yt>Cvd^my=XR>rB#AVVlAs z+6PJL(eNm=KoruO;{&|TB9}Rig!**M&{KNaRFkz5J0nI~`Q+I%fuBNJW(+6( z?*LCGtxXf+3o*sTOrd*S8VT~Y;RFprhAP2Um}e3^g}sxkuu+w?h$qr&(vJ8s!7@f1 z-ov0OMSMsx4RXUeHJQ^TnD(y!21m}-*rBbxj*%$VNUHolC~|r&6qzz3P*k``*`YoL zK<3vZdjAtD`=U0em-1IO^EeXG+1}XYJ$}MxXRKcqU+-xlBt(@ zn8ccw3pO=8lbVx{t45C~hyBVPM&GiO+H<=q55<@Bdd;mtiqQ^VHPM1g~IuGq70hM%XXbyp%!QwT~leA zV=@Xyp~LGaqK{X8I=h)d4yOwa6vFD|up2hP=21n(qf5q&9XB3+gH=9Q^K2<>gDqvx zJ^uo9!wOglJ<#iaW(ur@b+8^bz($X^0Dgt7lVCgSfSs_*4SQfO?1TLiCc?qV0XT$5 z@E9J#!*~>r|AhUxreap`jj6BVX*`2x@f4oN3wROFVc+1v!Aq~d_R%+QRpLtQ#co`I zJ-F&C+A4qXTJCT2XF=VzleKrAM^z| zTf|N7Wm+aiy^D*##R;1UOahAzQ&{5CWpb4s`ti`#nMi6@Um)#6e0lU`mpycr)ir0k bXkm`~7&Sh3sjt*s>MnDYc?wIs_l5f}Y1w9+ diff --git a/PythonHome/Lib/encodings/cp1140.py b/PythonHome/Lib/encodings/cp1140.py new file mode 100644 index 0000000000..7e507fd853 --- /dev/null +++ b/PythonHome/Lib/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/PythonHome/Lib/encodings/cp1140.pyc b/PythonHome/Lib/encodings/cp1140.pyc deleted file mode 100644 index fafaf2cd8ab10c93d89ba79cae836c71b42e0583..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2694 zcmc&$30GTH5WZOnVe786sHq!qDJ@#}T9LF>v_*VDX(O73ycY;&^W`C;)fPhcecyMx z)4hf6J!j^h_!s;Eb>_Y%571L=&+(Y>E_3g^J9p-r@6N>WXPI}fWoa-f9)2A3zmA^l z5DlsjAsTH$wTpyJgh+4*%_chSB1W=P^b3&_VoAs@RF_mZq{3ZLID}dx6;7$}6ckRO z77NWTbuJMj1KxtpCDf9<&MkGN1)W={WjqNL3AJ2=JkkJJ@`xNc=w(lX{t6BtMuV@Z z$LL6>e1VRL9*G*7?pqYeWa6oIUm&e&QC~DuTRVG}uU$)Ndc@FFUrbLYebpJcYev$1 zH#;-X#IMyfFK({(b;pek-VkL2HJP3ouQ&dHK8=Qp4wPmKVA^S=o_+DrppnxAn#8l8 ze5H^{whNXWLJ9gAdc)1H8+tryM0w7Slb!%CPo%*RqSGdp(Vtxyc9C;XxHejEw6;sn zvPLlOe=YnJz>6q3L>B&-zIz9)&iDVtTTCfZJZ`FeZ@Dkc#SB zQcD?;#C(aJ9;H?JDX?b}O-=UDg;9mY7*71(0iH^$7EOpR#1scJg)VYs(9dQY<1`2v zssvkMo=NZ&_D-_GLRHct7EeVIR>Wfj%NTKZ!$DO_`H(Uiq`?J|L{^hvT2}uJj-0FU zdDCv&XcXs3s{B7Fa(Yb^nKGkLRJbZxp^gC{^J@w{{|ulqj#N*;LB?%z-YQ|o83`J? z7D=|~aVn1m?lH6K`9)5o$vvu2Bn!zOE0tD2QW_&FrUVxe8P$mM6)mFv_vdp3t+LK9 zgv+T3@Om8$=G`&79`!q}vUG{)`Z)74H7^&FSaoy3rVeLNH}Y`R$cdt$pJ~u&@I~SR zBI}}AC9TpSSsSc)v=CM z`0^;s0)?SaI3JIdL4$eOu8}L$0u8-qI!&`oMqw+qxoxHNb<1y8FH^{7cff&SShXB> z!$#OtQd(ACF>d^XiEt2BdSLa_m9PyqS3UFWbFcz>p$~GJq{98cgWybQ-`=J;P*_A;Kqvv>|q z<9WP*7jXa&Pk-^%S3ZD&88fjD`*8*KVh&g0YTODZUwG>Z(6{9`{7rqN)~a?})=WxQ&R-2Cn*}Zvd|U zmNmM5?Eb0eXE+M?aSI;ALvZ0cI1VRZ2+qJM7=$};7w&!YEnI}ta1D3=@^O7&-uwlh zeA)o#@fr@|6}*bqfBo$9g^L=$X!=rtn|K@V;7z=R_gir&*!s^ax+uYQEFaX{Y_F>RA3gEe3-@(*Diz0 zbpF>vTUR`xnvH>0hY{w{w_P^TIcD3O>!6KUZe-N?oRywRXQi{sQROPGa6b^vzW|<> BWa0n- diff --git a/PythonHome/Lib/encodings/cp1250.py b/PythonHome/Lib/encodings/cp1250.py new file mode 100644 index 0000000000..d620b89335 --- /dev/null +++ b/PythonHome/Lib/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/PythonHome/Lib/encodings/cp1250.pyc b/PythonHome/Lib/encodings/cp1250.pyc deleted file mode 100644 index d0cb7437de6aba9f1170dfc859ca5c78314f7c12..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2731 zcmc&$dskFd6hHH17(jd%N;URkdVyN@G(!e3N=CXvqC}0Cxp!b_UfsD!l+_3nwMx?^ z84pn*(p)Ox${;D0&1sVNvFLKe?WBj0ZbA+=T8ZS~1{*gx zvj!WHa=5|H4X&)gPNZBSTe;0a!mxomYjY4OZ^7o|w*0KkNu&atH0BU#6=`(w4PYl1 z=>`Yg=xM-Phyfgi!Bf|%wkF~pU#qByAyrm9wPG?EiMM!s2}urlLdk90cWm{v$Z=T_ zRax?cl|;-_QoFmZuExJ7P`1CyU%5{Rl-1Vw0@d|p4K*-r2$cEia9L^nf%+0pM?`JK z4MMnKX|l7_?T*}n$FDlT0e(ytTq|fQ&^HeZG6Vr2a(sKhcYpw7D?!;tgn$=Qp*r#F zsuBsQA)MoDhu4Sdbug%ev{}dz__Gq#O1fP2ylpr$)MpbS8)*# z394dqR5n)O2`M=m<{?Dl$##|dAuCEkNqNCY_>d|BskCWtq`7HfmsFDhDF9(C;ke}C zei%Hl+)ES!E?we3Kn-wn6&IKKFCg*)A}8d)a90i+J0n)N9rhv^stbl-FfPXAU{H1Q zNh~3?M`0?UO~4S%gSd2Ocm!BLa^X$k0ZwbaOo#sB&6_ zBXKcmM!Z6>h!KXj7*ru24=I3wZ&)oxQ!)qB-1Xn!h`Cy`u(i{&9K}jbmH!7tOs|0= zQf3*70#+$A)D-|ker<&Jp8*tBgXtbPh`4Q7*cGtDj099g7Gn)c1j=QWd&sN`{30gO z;2u;ckO}9HnMyMtF0Bw1QUZ$zk7~*Jf-Fk^{rOlyi_P=1;bLlhs4s`XxI0D{g#L$B z7A_H7ANzs~&CG!$mYi6yq2sC0om^Nox=BvJi!|`7c#*Jx@VaPJNwait)<(>`Zxm={ zx!R~s3eOXC1;`V;fYTyH2TvS7)2N$xI&VWY@o<7y9rIWLFOPsM5D*Fh^Kn-hRFRi0 zGPnXQP*pm&z%+$qB$ix@(~=J#C;zmcMhaQ1HoL=_gi`n%eHRY{_Jx*o`2!RmtKBl=c~J3E8kt=tE{Tt z^Lou2Z|<%2@2h)D2-Ls5zu~~a#&??DeJ^-OYz|3sxTQ7H_I@-LPb5E3Qfm9*jt@IO z`uNBvpMI9UC=ISKWUfPS?#iRMZ2nvvm4rk zc5Qx$b!peNU$seXO8ZU!oSoBd=(F>~`W(B-`sh*GrFYRDeOmv5_Uhlzuk?QUwLVCX z(c}7Y{RHb~z4R3AV<+fo`aSDs<8+Ws&@*(HjnZ@MJ32x~^=>+*&*;7MqJE5C(g)~e zeTZJA?EC}Q*40!OlR0NdXvtwALa+Vm_uMJb~q^!f{unQ!C;EX z52S`clFcY#K~u4IFZ`rvZjVGIqg#M>5sU6z0(fWLY4p-vHdvU#?gs79UgRpW7ukz# M#g5!U=PhFY3#txy3jhEB diff --git a/PythonHome/Lib/encodings/cp1251.py b/PythonHome/Lib/encodings/cp1251.py new file mode 100644 index 0000000000..216771fa4c --- /dev/null +++ b/PythonHome/Lib/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/PythonHome/Lib/encodings/cp1251.pyc b/PythonHome/Lib/encodings/cp1251.pyc deleted file mode 100644 index c51e6e08bf0b079ee7a68ab3912bc935d9cf91b4..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2728 zcmc&$d3O{=5br&+SrTs0K-9&H^-2WA6A`iyjFKhJMglRqOm=3I#l4)JfKk*T2{!^E z93g}dB7(?aPyqpj_vRB+^AY9?_=g_=t9r-|pbv!ie9mS%-BsJwRloXm)q4Ic4_;_m z9ZRsAj|cxR#J6w}2Zga_99>Ltv$Tsfti>VJ(5biQvY|-3tjP&o)k5`hKA+0Ag(5jcO@tEpIdkXD3AL$NRg-m9 z2_>~$CN#T#QA0yrbZM-5#ggdaFs17 zK?bYxomIhL>IObh-G>f{V~XIqQBp&`g>X5K`HEhc5h3H7%zV!l-0oC{*CAs%2TKwPnmop~Z$2fv~p-T*i?- z3ZA(hBnpYP-sV3-jc^N*nBMNcM952ooK%9teK~AfCai8c940XI01okZR?evLxE>UX zOit-Y<5D7>L?Jo{iP_!Zk#GYm#kW8Q_}yh5eKJn!vI$Mis99Z3FA>;j36zSb$eyXV zwAq6fNMR0RDDi&>cm_%xnjl}0DIQ`9UhIlkn9N2~I4}{a09zuS3GgKHPO!p3RnQ`t z%F1ac;(G*37*Tk)f-05KA>}v-gSB$Hpb9V@tN#W^%GIPX(|*^TC@vOM`F~KP^x7yA zW$r*xqAKNtdJh1JU(@mZX8@&%sCobn5^mGRtRi-lk(jQja;8a3VYw`FkC;_MU!+9Z z+`|fmb0+xXq|ymU%Crq3)dCJsj(;s@c zV#dtMM;?7FH0$vvo_y-*+2LoNeeU@es;Xa{Gxw#J=e_dkYp=iY=KQx7yuENyO=R(s z+NJN*z5Cv>`snh8_oZ0l2P>LZu4?|U<)e?|tL4^&q9)tgQ)@m+XR^8cr&>YpSiA1C z&d#2kj5dFct339`}hIa4ZW}j`d}~YgZ*#-`r#l9z#$lf z!!QI#U>J_V2z(32;5#@DC*XTH2|vIoI1OjuEc^(ga1MTgpWzoc4;SDf{0f)gGF*Y* z;CHwR*SNtq@GjoXd-z7aiErjx_*TA+Z|6JsH+(1G6{Z9tU8%h(xdgT|>IXJW9C8pZ zY=+FF8C5f#3isIWiPnx(TCrONN^hai-S59>tMlzfy1;`Q3)I@M7kVoK72XPOrKi$Y KI>CQ~dH(_hS9iz& diff --git a/PythonHome/Lib/encodings/cp1252.py b/PythonHome/Lib/encodings/cp1252.py new file mode 100644 index 0000000000..e60a328db4 --- /dev/null +++ b/PythonHome/Lib/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/PythonHome/Lib/encodings/cp1252.pyc b/PythonHome/Lib/encodings/cp1252.pyc deleted file mode 100644 index 3eac5e525436d11e740c432348fb3715c24aa85a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2731 zcmc&$dskFd6hHH17(jd%N;URkdO=$DG(*Nml#FzTM2Q+NbML^|yt;FdD65;0yj$P>2~C;`m@ zfw-1Q1uE)R)YsRB*F>t;uL`eRCq=62YD1CL4ONY`IBkqnh3aWrWy6Msia2+O8 z#Pk@=>2c!|qUAX_=!|W4u&wy#WV(}exiEYOu7~aI!n2${16N~+LrTs@EqBF|5D}56 zF1I9AYZsl6QHQAo7)CjSv?gj*~L@n-)eLS7=|qyil7$YIMeVRhZ%Ac3L#aEM0Ja!QRxb-$RT zGD>?ArxNKT3ei4DNVkVa!VRntpBx?Fbr!qy*(lVeW15;$)4H5oC9uK_DZxP)TrDSassPir`fqTgT+Ny??RDIW;z~i4{|7}%uZ1E} z<`xtss#12S(*Q{Pnvc&v11QZz)m?CqaGN(}6|tj?M08D+Q;k{z%VnN>#H<>6krHWf z4=WVPOz_7}r5%uvriqFuK}AGFb<_EhDl7l}`BXv6?ep{DQffl9UX6owcdRam{g0|F zULw3c?kO3YnTJTMc&T7x$J4Pp`KW4iv4TjDXb{%vB2fVmbRRU_oaTs(%u(p@I*Re@72ozZ~9^KNvL+!9mNcxzi?^LxouI+J~0%jxY~IzH(9 z@T09CfAXohZRn3H6Q;5E_Z_CO-!ukIqt7(@uWmPu;YpOnCU>BI@-hzMz1^m<$259P zW1ndZm`0Cj?7Z4*b`MPUo5uKL54}4vIm-KZKOf)+_(6V%5AwtO2tUe?@#B1mpWr9? zDL%|k^E3P`KgZAW5q^P>@-aTnFY-(LGN0gAz<|$S8+1W8d=A^;3-}Vgg0JBl_!ho{ z@8Jjd5q^Rl&;vW+XV?Y5z;4(Bd*N5;g?+FeeuF;fhXFVM2jLJ5!eKZ9N8uP8haort zC*c$f!)Z7JXW<;2hY`2{qc8^Ja1k!SWte~~LCPUAmO7l0iD5^hmS8c(<_A&3BFRFM zsG#XoyQh9qw6rIZiq$P}^#&H*z66NQy3FdO%U!rJN8JtEp}Wji<}P!WyUIO 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/PythonHome/Lib/encodings/cp1253.pyc b/PythonHome/Lib/encodings/cp1253.pyc deleted file mode 100644 index 3657cfea9c455d05a789a893a3dee49f66a5c055..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2744 zcmc&$>vt1X5WjggO<%mVP&N2!e6<4N6R|XHu}VYTR0_2kw%JXanwOg`wTiORf`Ew1 zLjeIRg#uErfV2Vv=j;bR&i)Vk5BR}90B7#fY+F54ILBj>y}fs4@7$T+{O(L$f0p>i zS~o^w?Dofne{1l`jpHCO)`p{lNlun@ur{2ynCxKPP8P?xn+-75&)9}GCzCu};o=H! zUg2U=0av)W!k1ULnN-MRC)asc91ZyMIuDbICUjn|E6(e@OeTLF_wS(}d=KubQ> zj}H3D(@3z40@#E@pt(=&%A^CKE>RI#B4T^?hJ%7k{k=fvP+gOUl!<;)3PF} zvJ{9bnN*;%X;pJ`V|aC>dR=|EZmkfhZfXog8d|Db8*$khsSY*MwyKu(EtP@ZgxW<0 zVq~x?+gIiHCvM>ZR9J zB@t6&w5G?6Pl&{GaZnlScCgL(b28P*`dt{l1La|RJNGQ7mZCIcClugtR}Nd239H)<2MG+-heI@)7E^LGs`~jN zm63XqxD-eyP>A+He0FDe1l+(1@yXEvUT3jOor9CcbWD*`a#|IW^&C4ThEo2?vu7SI zE%x9Al9BZ~lV&?k``s zsN#VK9||mf_>o5+d%QCE#FI}w{Y+K$vrCpPdv5vjFTD8D%df0>b>(X{t7=1a^$n|E zZ+zp;HBI5Q&2I^jmbcfnuHVr1PW!v>MK_8aF-eYhb|t#sPo~nD><3Ct?b+1(Vc$m| zZ~o-dE#}sdKW^SIwZp&fHML`=Hf(BxruHM3jq>pdj+1|;cF@!gnc5LkJ8EjjO>Lj4 z?WZ>fj`R1gPJUS*gl({0AJR|gC-q_dlzv)2gL?g}KBAw~&zsr-eN?}oU(_$bfPPsY z)5l>4?1WwVHQ23RhduBWd=1~gUf2iw;Q)LK-@!pR1c%{!I08rE82kW(K;FU-oPd)s z45#2UoPnR^8nM_Mqt?B^2pP?M}+Xu)R@#uxMkGg?M5yW)aP(x~WviC;q?a w=t(3ct977s5~c234|tnhVKvs3F5H--R)@XOUG6J)m%A%m6`sN}?=9y33$;mz9{>OV diff --git a/PythonHome/Lib/encodings/cp1254.py b/PythonHome/Lib/encodings/cp1254.py new file mode 100644 index 0000000000..65530ab546 --- /dev/null +++ b/PythonHome/Lib/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/PythonHome/Lib/encodings/cp1254.pyc b/PythonHome/Lib/encodings/cp1254.pyc deleted file mode 100644 index d174941e8194e72b15957916b301d7a26825f11f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2733 zcmc&$d3O{=5br&+*(BVcfvAfY>y-$CCt_feV3aIzHWG-@WwJAyY~0J)2^d8kNyJ;9 z32MNYkO1Kd_k9TOb!GjBZ!urMKl}h#)kAh5`apQk=k89Yx@)?+>Q}$6itEoZ|C#2E zkr=!FapB);d~#=TP#9~$(ZLiaOFCE!3NEHPSf`W4QFgOl#(Egr(Bfo@M<`rE;Vmd! zOeqoyw@~;B3O7@Vnd%fe4~wG#e?jMAO39?oD|Dp=otG(PG-)Yf$~4yE69&+dkM*E~ ze)2RDoK693!XePut#@S7fl!C6$uV8k0u6FDn@G0@LK#Jk1!CF7OO`DSw5w@VlXX=I z#I;N+u&7~WV`F`Ib);%tZMbHw6sc;c4@K&ls+#L@+8n70HPW`qru9vW0-FG{70w}Zm}f9oBfvvd5Msdig36ihb_y5)pdu11cvUzAsS7~DK#3^{bG{J zC|yaMN~Du0MEf8i-5MSVH?U%Sa&&;#S?bbfp-`WWX=+MM>vFPIV5h}!ReTEUnS)b{ zJ$Qi>W;2Eo|961rC~}CPEcpOT;q)ozImSjiAc^gCeEZLXjvl z1x1OflpX4A03?3R!{?s?lxCpnE;vZI&7HK0*il9zx~9shW-Wo`vcNrJ)+&0D5@~S{ zD-_C1@W)Q29gvW26BSW{iin8nrt>9LR{s0*se)G6=NH1I)P!ig8VBp{SX~hNA5~er zM0kDNlQK3l50O~$Qo+WKr(<{WQPt>SMUf!UAgt3xq5>l7qE#jB(ji!zuL#5o+E9Huo)J~YK31a3BM}QEf|> zLB)OdKM+{>;6o2T^5~-AV~;=a0om{>PQerm^$)KGPU7jWN^MWf~(_x0%MVJWA*DeW)+|Ok=<_c9_PXY5Zy$ zqo&bs8r!c9n!Tg>5!1Mk@3-E}pX0mu2p{FU`5wNPkMVtcKR>_^@ 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/PythonHome/Lib/encodings/cp1255.pyc b/PythonHome/Lib/encodings/cp1255.pyc deleted file mode 100644 index ba580edeb979573bc91d46567c0eb35d14c1bda3..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2752 zcmc&$=~o+76n|L>Ve786sHq!q16#$lR!V@1mJ}yg+K8q@W&)|%oD4;@>IfV^y0q0U z(hAhlRb?x*wuN(E&+$vY&-*_AfFJw=>b-B8Oh8YuJ;!5`dEEEzy!-C`-QT+x$Dd{1 z*^a%TD7pP{z~6d!vU4yWMO@+J3Qu0)BvLVv?Of*~F)-lG>s&-C$?4o&SDM$kiByJ@a1oKpN!Y^;fF%zZ z1P8t7X~U`aDN>)Tw zmV7ZKo%B_=Zfk3632qP7?rI7)?i50`tu292b9-$^3rssgwShL=R@1(_z1r6oS9{Pv z6b;s7`fI%2_$~MZRTntGkI92;hm{8O%?E=FK>&yx-y!fFAOP7;P<9X@_oMbK?j6ygY}@boqLv5%V9MNI3&eP#B`T0aS;%S zsA5+_Hh19(Sve8oA;eReUX}YHD@t0)`awzfkgWu%rgKNUt21XM+i5}yK$u%NE+uFW zgD19oi9*1wi~I+u0dBs;#l`*$h`fNv2}Lm6mBXfG#Ok)gegs4Hzz~U~#H1XFs9ruv zrlsBlOa;^l7@~C$m+lOY02@d#JXt)zZ7+4Gt3YT;MHM+Ir&KY~#IaMNu*yGq_N;-a z$sV{s60sPAiT^vm>tWTR3GfA&;y|Xr#jXtb(QGgd1L2`^um$892TwrnI4dkvIW1!G zl$fw0UM5(?2*WD`RVc+n%3$CIo5e&{=3rV@{|%0qtCcy^Zrf568#z_}9~3dYCW=Uz zB`6A5rL0hw0TB7M4xWDoP*?$~d*C4Awl-%Ku)~amR7Dn(9ZDR^WuAM;tOk4$6KQe} zDip|s^T$f16%dz}i3%x!MTAGS=zKvIrT_kXte{oa`T1}$H33|&hrzr%W*3D1hgB9X z5nLZP1Xa99SU`APG^?alIyh_N*4;M?w6b*B ztWFBg6Lba06Fh)Z!9pKT96!^nn|L~JLoKOTnpYj`SOG7OfGiLY3IX$RR~b~1m)$bB z0xeKg`ZvNfi)19WVw>Am3ST$>_Fg~=+3XId%U$Ft_Lh{El~=4-xoY*Awd?M?zjFPC zss|o?$hYy~M;?9b@oN7QPd@eZGc~o(Zrc3Z^K~!0_|nU-yt?JJt*_T_YX~$pHE(~T z<;}Ntv<7#!y)A^=-`Ul%dr$b?&iCGr>=nDBk{s*qiSPR$kxZpCA1Yb3cYohU{U3jF z;M31OHwG^Lu`q9F$A3R)XeSMA+|Wi0ZS>}shBmuU)Iqd{i=RVzpl^g3ru5QumLv6 zCfFpKV$*D<@cg{YzG2_8gX|DH%)Vpavm@*%JI0Q)AJ{NE!A`Ot*$5kDW9$_BiJfNS z>Eh(7p!QkBJ2uW80I`QD}46CrtWSq(Q!z%-MhvRyh?5dhY*>uHJY; tGFu3&7EtTXb%D3rEoOt=>VS<|Y 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/PythonHome/Lib/encodings/cp1256.pyc b/PythonHome/Lib/encodings/cp1256.pyc deleted file mode 100644 index 1d473405414a82561ef05f1118b8a324d31a1754..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2730 zcmc&$>30-G5br&+*(BVcfvAfY>y-!!UWkF^FiMs<8wtedGTE6;Htyx@1dO5%BqAz@ zM1A57;YvtI0)&JF%!i(bU;GDpmT&Vf_y=HB57{B;1K~ZNvzbnH*LHQ)uYO&%u0PBC zqYc|4F>?KJ!T)M_b7L?_gfznFAd-_L9i$Ni7m*#L%}L@QyGa)zorG*{bP~zK6)vvu z78EWb6>)`|D|`ion@Gh(c54dy3&HqOQbTKG!_wQ25Izh17OKV zI>A9ddKwAN!~nL#5UA@=TQliEs8v+Nm?|rQS}~hVq+0@^j3mbbvFy@i%U1+iHHhubRax705Q>`17s zXds3LE3+Myet+T`JYm%X4)9|N;5uPt4f+;G4_zn<&>?A0=h!6>4DpW6i zT~!h>HHLG1-SCERc`ghpA#Dz_6aJh;b&^gOgztd$u)UpomQ!cIY7B5liP@;-E??pz zAQDx@=A>-x!V_|GGR{Ltq_gcR_d`~cjFJn2lJFr{4pL>)#zb?|l$BhQ1t|bwZQ;0- zpgjzpIPNA20k=-`AD{-f`4ShW`!68!0wO0A!Ei?oTb2>4>kbDI4AloiG@2Guax|*? z`6QK*+LJI9P$yuB_CZ{_H9P`rAjRVBEqAZcD^8s(tm$GR?rIj{6e^xnh>s6!(iPVs|!N^ z!zv4x2(FKNN`_|UK@v+|EZETTROn7VtQwu9C=x^(gjKvqSU`APw5p_CIyh?+_T9G% zv~u&ZRh<-`C+G^0CwKv;8y0r(#PKt&x{0UrHdK?2XL!}Ij}`Fp2*?5fp%5@1ca%XD zdD$X^E6@T}rDHKnb4W(wD0X-qrSS3cPy4q>A&1lD_IQhY#r~4gvKcdH&7L!N-uwmk z+*`hIQN?}tKM+{_;6o2T^5~M_V~;=ac zyKeo4S8HB-ePeBSQ{5Xvr2fs#4O_N0zSZ>hJJD@ob4-%sEv<>Rcay1fCi|X}Q`@)i zc)#O=4|jg_@h9f)0b|nCe)zrH)P6CwlcsjW)QleQj#rt_S(3>#!aY?z&8=h%5R!Y;5;{W~_sF0yepVQ9uKW4F<%A2GW09^+GEkMWtY zS3jlq>V5iYz2ErU_(C7lhm0?cea3#{fIeazG``Zuj6?dk(XC(7FPqu{Q#*LIJBTR+ z!eWDyGBIdq*bywE*z`bVSR7e|64o;nOZU_-istr2QnH!_tlmJPTUP+ySXWxDbd?J> a=CHXzH*}Z#%H8Ge3Ri`vc&7InasLHj27A~5 diff --git a/PythonHome/Lib/encodings/cp1257.py b/PythonHome/Lib/encodings/cp1257.py new file mode 100644 index 0000000000..53a6b29d5b --- /dev/null +++ b/PythonHome/Lib/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/PythonHome/Lib/encodings/cp1257.pyc b/PythonHome/Lib/encodings/cp1257.pyc deleted file mode 100644 index 830e5139251975e55aefab9a69eedb0d2a8a198c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2738 zcmc&$>vt1X5WmSLX_~%xYoKcI)%a=!MSLKZrY%NksGCY5R>O98(+2Z$v!zy115L~E z9Qb0j4<1?yR-p(;rKPmgbN2D6|3&@*KllgW%w3XgtA`5bcucyJxp(&7JM)|0ohkEY znQN-`V2~$wKMefV!jql`ArKM*X(57@#4IEP3PVH-Ib-Q}=xNYffdL!_;c4!XJCg~IualEFUKS-!6PHRw6CEC3QV@9$pW3o@+jdWfm=GmS z76ng4O2$1^O}m<#{ej)Vntcs{`n_zhrpfOMHn!BX`eE1_tnoGDvg(%oEmfZGsN9Jg z@VH@hs;AoJir#@wK(>Pe^q2y;R+y%9r(H| zMR}RWF+MhUd^o)pgiOdG3poORRw7$TF9YFQU_M|jr=F$da+u`-hd7rC8}8C6ssbWm znQM=U#wt7^Eyf}=glHnwB~w2{NlHp-FBl0GX*X!qZF{2aZTVf&Z3d(Ogt3I;QiA(o z@Wk>UQLwmliT?mKz)h#9y3~Ibk!KM(wg|+1Ic)5VSlxBli(tr35aDowi;Ll~?4pBs zQs|1okVPAdA({tK?cVUPuz(c9lg0xa)>1}Z1BySvOJZD1$Xu*}Vkhx1OFsqntb?J! z9=JdPF&Tr2|2x1NVb-Jx@CBH{AXDICyMtcbHV_3tXs8ry7I{X&W6?Xx3KLaIi%2xV z#mtCT2o^EI@D_v0mf|60An1mTTr4e8FwI^64UU+r)%mR*mgOkcQ>y$wC}MgI6p=E^ zP-L-6nW3%#Ao6PiJpT+Jy9!JXz(K@qeSTNK4l@#zC6SA_N>M161@0lU>hMKOq`^I? zP@ogaA2XF^KvY{HDx?G!5gOH!^I4G-{`>Q>f>xU67sAEV_;9`!gmHI_E(rY(t1Mh1 zxIVVL4$aJtBo-W4u%YA0(4CxEHF`-=(2Fz($as;kfY7>VR7taRP}WAxyKfX|Y5BBK zog|tk=n9Z0cmStG6Wug%^h~2};_0*v`4f>OtvcqhEM6WKS->I`Eav0BGAJW2J4A2= zTA(cTY=&VP$w(~47Kf!2z7G2BI*SytSQ(q$QRFOkm6Vp1SFBpSX6?H58yV0J zBac4j+5GquPd@c@mG_xvpL_m=>Y5j~Y<=nFZLe&9^|jaE*zxAhw`zCQ`RW@Qcfaj_ z=iNO`fxXS|vB8%2_qFan5c;6)!;iuTxprO%DJ^#$?*6prv(Jxw z@#R;!W0(K+EqwXv!fE^&MKPwFS1zD3uKc79D;M=aWkR{E{Gwb@`;}|TugZ00Qu$4} zp-d^$>P=-vA5vzOIpwx8ua0Y3?TVJs`qix3rwwc0XeZRK^%-qY8`Gw=OWLeHs`u)B z>VSSi{Z1WJhxF_EQT>#DNj;;_>bKP&v_9>sc2qmAUQmD3MzjI#q68N+2#aIw8qJW5dp15XPhlGQ{A@ zCe*O5$ymbk|5>zmMPq`|G+=fSneJT)XoKBhwA7spEKFmQgRW?EJKZ+7t&*v<7gsp$ G5Zhn={(zhS diff --git a/PythonHome/Lib/encodings/cp1258.py b/PythonHome/Lib/encodings/cp1258.py new file mode 100644 index 0000000000..4b25d8e7e8 --- /dev/null +++ b/PythonHome/Lib/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/PythonHome/Lib/encodings/cp1258.pyc b/PythonHome/Lib/encodings/cp1258.pyc deleted file mode 100644 index f5a90b175120562f60f18536efa0dc25391494c2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2736 zcmc&$d3O{=5br&+*(BVcfvAfY>y-$Kq9O)10i$GzvyniIE|Z8t?Krv5k#Rrg((HB^2Jg z!o`#Vp>PX@FRySjrI4vkq4Tgf8t~_J9;Osc>byc%oY#4oQbLo)0;Wu3jXq%jE%{g% zI_M`)Bf;quz-Al*bsc(ZCLIX1%9ntC)=80y+L};gb$vxc4Ne;(6`?xXR$jlMeo=n zQSi)hFHuOeb&CH8HNq{HggDiIiIA5FIjI1LyK>mFOjzA;I7ndVJ{+Raw473-QQa>l zsf^N|#HmC&i9)mw64LGAk#GYm#3x4wc%8*AeHIEe>6oUb)U+-qs|9vi3|GY`&z?Cr zwb+9fNMSZ(DDi&>cs{P$G(o-~Q(VLpyx66YAejv(a9|=-0k%Xu6W~eYonVEHs-Q(Y zk(QHo#CHgmFrx5o230DiLrQQE23O0;oGQSyt^OMvDOWQmO?w@;qF5!U^8cVn>9tTK z%G`pYL{-WT^$q|Mzvkid&j3m@P<0O+B;4jsT1D(ABN1IweC_zO;L^b7nNtKoV{(P#SW%l{`a49t*TCc>xx;s`E#QsNB z7B3NAANQn;&CEk2R=iZOvE%93oqSX^x>!LZNHhrRbdjilh`MN1NxO6i)+X$`Zxv|m z)@7?YX(CV96);cuAWklNSj14JQ*)8+Pf3w(wCqT-Ti(`U?_HG9t7dH3C4 zI)6dg0}nnFSorWGk3RPJqTmxxKK1l7@YOJ8_#*-J0Kvi#K*uT`#G6{@OU zz2^0rH{M)Z8(vrUmK3Rfdws)(jg9X#z58BtliVCr)Obs4qV4@;DxJxGpyl-T&09X~ z_~_%UpM3h6*?H=Z(JQ90e|(o|{A?OWOrzH{`mSv^jRBz;zPby4^M9tX*EIH-MvrOy zWE%aZvD-BETlULE4SypQ+ugZvOb%#ZM+{1`vZPwY$u$XI0)zA!gwECgh3dBVHkl+aCv;d>^uphK}sajmfD<>iD6r#zF^VCCJFJw zV#)%NsH*8yz$gE&Xl_p=6{}_7>P=L-eH{?(b-C40SGaIvj#?b{M0csL)LrT>bCr1t Jr+cq6_g|Upef|Id diff --git a/PythonHome/Lib/encodings/cp424.py b/PythonHome/Lib/encodings/cp424.py new file mode 100644 index 0000000000..d3ade22776 --- /dev/null +++ b/PythonHome/Lib/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 -> + u'\x91' # 0x31 -> + 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 -> + 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/PythonHome/Lib/encodings/cp424.pyc b/PythonHome/Lib/encodings/cp424.pyc deleted file mode 100644 index 67ec0c44e32e230119c0d6ce997f1a43ce69c92f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2724 zcmc&$>2e!I5FTkIS(dNdM2P`~%i^*jm^%c=vJ(ukVpb+jgh5&FuIx3sSdB4;Kms=R zmD{-!ayj8XV<;e0bsl2=^8)wqYwyV`ngy#NNXUFUxpX5(R~s9yaV{X_S3zg0XSNwkEyI@Jodv6@jusVMdiy z_@p9OR`{4v%}lS<`B@qbgvvTUGipk@fYjBNbpdA7(I8pHjCz&~N&{#q$i~sZ5P6!2 zHc$Y=*hPBA_)tC@@ePTV&7JX%O=_a0yDJfEiS^*S&AnTCn;n3R4qNf}aQIb#7Za*J(`6hb>0ai?QR34SU#j z{CXMpvT+4N_TYTnT`oN<@_L-rG4`xhNICAxDJdcfDXtAsNt6EvLpodsL*h#XhAJf`H`2M`BW^9j_V@6q3s5zG z{t;?ROGXhnI*tUlO)cAJTbLWmydze%(~ES94(~8Eq0A(A+;eopk<#2T5go$VWK6TR zS53|M&$p+<+30Rx4wjB3M)PghIk(0scv$Kvx#IP~i{mTFShxJdUn4+y8jBmpLKLKQ zG0v(IQKCSc(-or3A$cy7qnk1$VJ-L4J89XjoOZI3Ee{E60Ui=IL}|vvs5~{frIRjc zb6I@4a_PKGH}1A7-5ZrCpb`=)oyL5Qj}s*aP4ooo9=FF<;jl%0>akL3nF<81}$Njn`gxJ?w>iO@AG z;ca*a-i7zzeSe?|cERptuow2hemLNRgK!8A!;vLR;rNP(*d=z0Jz}reC-#d2Vp1H0 zQ_X9lw{O2i91@4c5ph%;6UW5~aZ-G|>ZaRneHcEwvqhW|r^Oj@R-6-4;=H&3=kB;U zwf529f4w9=!4AK0()q>yx1E#Q9=fru>5&_7pbhATnI0Un;8Xai{0e*xUkyK($>#Ef z=WTcP2NdB9eE({ZkGwGY;@C@Nl_S6x&%$Xq3)64`rr;v{48Opor=Ni@;XHhIdGh6T z?Xix|^&1}Rg3l{fzVi4J8@uD1dY)9_#|l;d<>^H4Q=9v?Y)!&96}r3bUVTsNz4zV! zz=QDZOck7n(xD=OsnQvF9V;8v28TH=Ux+FWX;zX%xs6j6Fa5C?7_l;jQ#NpR2CL@G j2eQDfaZ2i11=kg+%3)dbg@a*V*w?5u`l}lPSD5cl 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/PythonHome/Lib/encodings/cp437.pyc b/PythonHome/Lib/encodings/cp437.pyc deleted file mode 100644 index b344da6d6638043fc4e313c6bef697700ce6dcd2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 7929 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 hX7+5+x@}j?MlC 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/PythonHome/Lib/encodings/cp500.pyc b/PythonHome/Lib/encodings/cp500.pyc deleted file mode 100644 index 8f4731c87aef7a6079d58258fe09ef7f407f01c9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2694 zcmc&$2X`Aq5MEWwic30CVnCr;G&__~LvW%v!4NCvWa7jal(X(+%cyZW6AXbkvD16+ zz4vaX=e?Pq#19BFdy&pDJU_yFJS6XWZs&G(=9_P4>>R;SQBQsI&cZ&BeAT8UJ+rNUQKxP?|K zbf?sLM1lPoYmCS5SbUP zU05HPvp|W~Ha3K#bDL}HXNTuBglof1w5g_fQFC>0Y0~WE?QynNlk2JR`;(996EQt> zx;&$Ztdmw|vtvP;bc%owl;HN0;}k#1PQkKEDA5q-!SwR$rjd-Baen6ErV-}laWt7i zbUDN_`g01?Df(O#yMxvv_IBx6-mIY2IDwE>b1}|P1Q@}j5w{zPmwy~>CvJNT^&u>bm6T372e6T zYIB6hLNswPP3TGoq9HaLNzx=_q!Ma{NhYCF*gHuH8&k=NL^7kM?0`p(l@a3ThC-^8 z@fqbbNqckER9=@*+D88Yikzr11dIRJc0Xk&X->b88}v zzlTp5O{!<-AEP#*V3d&KbVN-8!E#!{yk19>b!)87M?H^=D_tMDIPQW>4a~#*)x2D% zsmqzvk$hY(`b0@I#1x2_e1*7jNS@2$XqOC0*ra{wt+H$kU$&}}A(KSCfRaRmP#UtZ zRAx;cX_ZSpTsEJEOd>1GjeV@b_eNm~D2#-{*?5-pnM}zJojjqwXBs_I=`qhd6pm7d z*HK1aul#oRGJPCQ7aS~w)yrWIY=X_B%E~J$M~@jh4i3R8AFP=afbFoQ>iHL5gkD$y zE1?hi{m)H-wXhD>!v@&s@s_|=*ftS%z)si&yWOxC_Q8HQFn$6Yo*aaucpOjSQ9Onx z@D!fGYv0z)2)#M=H9Uvs@dBR3OL!Tt;6*(0-79ar{^|E`*Wya-$6j24eYgtO;5In@ z)~m6ZpW|&@hwE_zuEkBb8MolZC7--pSN+*bxL0kDYkH!iGYJ>q9$v)<_z z=}b2FqXFmPE}n+lxEfBvt>5!z_fJcI?)e3d!6V#?hww05hU0JoPQf6YgEKGy_u&CN zgp14I3Y>+TxaZed^wXk#?z}G=;1b@%0lbbk@YZi%el@=_vY_c}1@7QIypMPAEEOF5?xjYwsF|>ClQ<~KeXmto(M!e{Fa diff --git a/PythonHome/Lib/encodings/cp720.py b/PythonHome/Lib/encodings/cp720.py new file mode 100644 index 0000000000..5c96d9813c --- /dev/null +++ b/PythonHome/Lib/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/PythonHome/Lib/encodings/cp720.pyc b/PythonHome/Lib/encodings/cp720.pyc deleted file mode 100644 index b1a08b17377aad51467ab5764764833958d749cb..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2791 zcmc&$dvg>;5TASIawNPJ0*I^lIA0+~1w}+8fT9p_4~fL+vDw`ui+6kH?w&D<8c4*T zJOb>TfQTWy2?8Py5v#1)`x3kV&R6gQVD~I{3uvXpD$BdAuJx^~o!3 z8`Cnm`H8^)rSOj=Q1_>D;WJ7zHC^4>xa7DbT zh!CZQE23PHs4AjFsU>Qd>tdt}4oFsYF``VU=;B;gSJlOdQje4N8lp@j?FoJWoRlB~ z;9wFxO{XSd0Eb~%+h_IUb)lt4G9=kj4PlK`C}?`O(2`eFS&$10o127gRaXtkQWXJS zZPRom-)k;PuGdUU5*9QzH7;msY8KLKn}s#Stfdur`3vqquifr62h>u3}X;r zP$5_Vo9AH=Vg#r_4il6kL`$mvMEG1!(W(KVKNW_ zm_o4L8f@pjnbt&Dl>xAvRLH2@VZOvgfG%T6omti2g%(UT+r>lB^g_|%eyE0#H_Q|$ z2_MXvAT@TZ);c>Xr}Oh&pis41pakjSG$l?-Sf);`#A# zUBsFS!YW-h)SRkYQg#JL&X8f1f2!1(4pW~xaLW`D&;_&pS9oW^YQPa73(zEjG=baS zkWS&Ttr`r3N6MiVkz^b?5xwJ-2r%WG=+bm48w5OltcVbLeJiA59oj%*@bgwmSySau z28aFw6p_++3HZtJ(481A=QR0$Fs#M+kbWZaUojUN+|eKtIm#0BO> zRZ{+Q^T?UGf%$5%n3fh?UkZbNYy2h&?GcMBTpzeN(TWVcE{6P7;#jAlAzIM95?C$< zNKHD06lk^Z3Ss5oJmflv&^#)a-Y?6>oy&ezGI)}p7eJEW0hDf8=;c}CCjD}W z#(DEurFZ3dxe3gQcyC0cfQU$ln2ozhpM{j{R>2c!ewNWU52hyakc4VO@lYLn3(&Q;qr%k`--Wf9+X3d^+-`x9!2OgaF(8G^BntJTV{w1<`UveG_gZ)Nr|MvpK$%4msE%IHx>_b~b` zqu(=nh|%wuJ~Tg9FuI@7y^QW-bd1q6%-+xJ9jr9ON`tHf!Z0iKyI0(+?l0~&_g8O=bJ^SK4S0jz zm) 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/PythonHome/Lib/encodings/cp737.pyc b/PythonHome/Lib/encodings/cp737.pyc deleted file mode 100644 index a04c4d97ca10d36f91b92a57819886b156cbb183..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8157 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 DKhV{$ diff --git a/PythonHome/Lib/encodings/cp775.py b/PythonHome/Lib/encodings/cp775.py new file mode 100644 index 0000000000..6a456a5825 --- /dev/null +++ b/PythonHome/Lib/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/PythonHome/Lib/encodings/cp775.pyc b/PythonHome/Lib/encodings/cp775.pyc deleted file mode 100644 index bbf977e30fe9c85793f6dcc7503a49c61aa14c16..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 7943 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 DQcQio diff --git a/PythonHome/Lib/encodings/cp850.py b/PythonHome/Lib/encodings/cp850.py new file mode 100644 index 0000000000..0c8478c8b2 --- /dev/null +++ b/PythonHome/Lib/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/PythonHome/Lib/encodings/cp850.pyc b/PythonHome/Lib/encodings/cp850.pyc deleted file mode 100644 index 69d4f6b491ac263f9dd6374f7f89e836910c330b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 7676 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 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/PythonHome/Lib/encodings/cp852.pyc b/PythonHome/Lib/encodings/cp852.pyc deleted file mode 100644 index 24383e76c52ea0afa09e9a62e71fd43ceda0a61d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 7945 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 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/PythonHome/Lib/encodings/cp855.pyc b/PythonHome/Lib/encodings/cp855.pyc deleted file mode 100644 index e75ba1a519c0136b96c082f7d2dd196a49896441..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8126 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 diff --git a/PythonHome/Lib/encodings/cp856.py b/PythonHome/Lib/encodings/cp856.py new file mode 100644 index 0000000000..203c2c4ca0 --- /dev/null +++ b/PythonHome/Lib/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/PythonHome/Lib/encodings/cp856.pyc b/PythonHome/Lib/encodings/cp856.pyc deleted file mode 100644 index dd163eb8e26a3be58247227c99a4f7b5e8eb2569..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2756 zcmc&$TUQ%Z6h65U!mW3k7B%%oyn(mYsW ze%s(7YK<^>g&|-YyhN=fnp@a>Bn1wFw#`S>x{A#&Z1uLyPt*o{NYoIukt71b0eA|K zNeD2Ak;WrUn7{~#aPPP=oX>@$!?G?bhNg#m+S819f-Fb?uvCDlHzSW-SKE!v=`oO?K{%f5*|w%!?;R8C#{9?)?hGw z13ods2b&7lHlS{p>A-lxAT$UZfD@QbLA;PQ=x&0#he+`V!f*KTbwf`phJw#HyfC6T zy%B^#$cT#^ho74mZZheClwB|%bC!$9ibf;MDv*0tE+nmR#gtG1g`^=5W;AOR?oiY+ zDUm`tR~R)!9Gb4@^;ZAz-OPcbGeI{hK5tT)HBB zKpM~%Q$k%CzJ$O_2%J;{VlDAnjuEMw@kS5|BLE_q%*k0TnKXjpA)8l6Gw>*(O~MSF zeS}sO90}ehwJ?h4-|w#X7#l$8&MCT<)pCZM=@Q843e1X+O`T2fXi*1lj7l83;Hm!= z-fb}Ja0JK#H1Qx!;3kLS5p)|%gCHVP0kwoA6VOQ*ouGt+so+E^os%<8!qsy{gfP41 zkV^HqM*|4qZ@-)=Y642f=|4ab4{CkIv){EE!%jhy{|7@nTnj_w%PI^dEJ{wM)!{>K zZGrLk@JZ{yw08a>YMU!g0XaO5xS?xuwqH*}ZM1oZtm?oQ@f0oIL1_Y=2<|xN=%gdG z>Nz1DLNG*5E4G(3S^dwq$HLj{Y;Pxv#}dW)b`aLBu^Jwf!4b-_hTYJ}$S%>+{zHYJ+w44UJ9f)^FIjY4es_wuZKCZ@%@m+rvBVxbv>N z?`etLd*A&JJlNXy(8G^B`q<80kMDls$*1-_z4w{+eI3!xuKfp|?SAh0gFUfBy)Q`d zz84SoA32(MY2f8olE>shMb%P6!|9P%Gud3e@S0vUMqeL$WBkpxj=%lRyKI`xuoLVg zGg*n1*(^K7K4hoaN9+tc%RXkGusQZAJIChPd3J#n!o5LJHk zOS(vZp+DpMpVOasd4`uy@bXD+zQ@h;_Ck7@m*#nChL>h}=`1}*FK~03neM&tF3VJ6gNNM<@b4ciY}mw@`P=)75crc zE?4MR^a}lge#0kb={0(lUcA0Uf1qE}OLU3;NWY`s^70&=i{POH!Lbvnc?CKj_700# z4xf-p7OA$QhPBVYDqs1>V{kN`QLVNDv&&dlwO)t@yvJ&}dp)qOh+PocrZ*G_c|+c2 NPqVMK$$x`*{{#-qq~QPn diff --git a/PythonHome/Lib/encodings/cp857.py b/PythonHome/Lib/encodings/cp857.py new file mode 100644 index 0000000000..c24191b04d --- /dev/null +++ b/PythonHome/Lib/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/PythonHome/Lib/encodings/cp857.pyc b/PythonHome/Lib/encodings/cp857.pyc deleted file mode 100644 index 8418831b7f16b47fdc6fab62f00e2bb034cf8d64..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 7666 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 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/PythonHome/Lib/encodings/cp858.pyc b/PythonHome/Lib/encodings/cp858.pyc deleted file mode 100644 index a3807c4f83a31d9b6113b4a5ad86e65d99f39f7e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 7646 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 KPj&_H>Hh)ss#&Q3 diff --git a/PythonHome/Lib/encodings/cp860.py b/PythonHome/Lib/encodings/cp860.py new file mode 100644 index 0000000000..4acb0cf362 --- /dev/null +++ b/PythonHome/Lib/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/PythonHome/Lib/encodings/cp860.pyc b/PythonHome/Lib/encodings/cp860.pyc deleted file mode 100644 index fe5c8e465fd9513dd2f1b67faa48553f62915ae4..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 7912 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 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/PythonHome/Lib/encodings/cp861.pyc b/PythonHome/Lib/encodings/cp861.pyc deleted file mode 100644 index 531f1fcdcc89344a49cff9751e5a8a548a0be56e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 7923 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 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/PythonHome/Lib/encodings/cp862.pyc b/PythonHome/Lib/encodings/cp862.pyc deleted file mode 100644 index 8a7d27ac8fedf081c0c61b4c26e074e58a0ba128..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8058 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 diff --git a/PythonHome/Lib/encodings/cp863.py b/PythonHome/Lib/encodings/cp863.py new file mode 100644 index 0000000000..62dfabf66a --- /dev/null +++ b/PythonHome/Lib/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/PythonHome/Lib/encodings/cp863.pyc b/PythonHome/Lib/encodings/cp863.pyc deleted file mode 100644 index 1874c58cb5855163664ac9a6f0dfd8aa1e373456..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 7923 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 diff --git a/PythonHome/Lib/encodings/cp864.py b/PythonHome/Lib/encodings/cp864.py new file mode 100644 index 0000000000..02a0e733a8 --- /dev/null +++ b/PythonHome/Lib/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/PythonHome/Lib/encodings/cp864.pyc b/PythonHome/Lib/encodings/cp864.pyc deleted file mode 100644 index 52ea66432ae4ebb20634c472704c3123c5dc0e1f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8054 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 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/PythonHome/Lib/encodings/cp865.pyc b/PythonHome/Lib/encodings/cp865.pyc deleted file mode 100644 index da1103e3d19767eab28681a776b6ee55eaff4690..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 7923 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 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/PythonHome/Lib/encodings/cp866.pyc b/PythonHome/Lib/encodings/cp866.pyc deleted file mode 100644 index 7f2b355ef736ddb3410d9cf2b3175f1bde6f4254..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8158 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 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/PythonHome/Lib/encodings/cp869.pyc b/PythonHome/Lib/encodings/cp869.pyc deleted file mode 100644 index 2719b17c99f13b706b8a8b02931d8fa60695ce1a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 7970 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

QMl?k1n5X zG2H_0;C{MpT(^X7A=f=Xw}@^j-D7mi=oZs0r&~cvkd|;=6WuntX1cAUm81u_ZWY~b z(rVHk(i+lsZheq$18FU32iL8mdz|hex+mx!rhAQUJ>62eN9f+5`x4!objwH^xwxF} zQMwg$3DRaRHqmXNYo=RCdW?&QNZUxOxNbFR2NxeF9UwhHT6Q{UC*5+oU34qxGDxS9 z_Hx}C?%+wf2kG|Ft)*K>dWwtXeDl+E6X>3yn?yI2bdZY=@y!pD4s)?1HyoksO7|?? z0J`Vs&Y?@v^`d*8PUv2s8%p;g-FoitCAvrGUZyMM)>r5z(!EL-rF)I8g6?&?>2z<< zji-B)u9D89+ra&$=r+=QneI`#uh4Cx`zqaLy06h~q5C@BR=RJ{?V|f8-EO*X(e0u8 zHeC;X+jr>l=)Oz0fbK22M!L7@_VN?&&^<}_J-P;N{XX43uKNMqe!3shJw=zMdz$V? zbkESeOLu_o$8-njenNMM?x%Ez>3&9cgzi1MXX)OjdyeksbkEcMf-Xt-OS%{6KA>x) z`;hKeq+gR>T-b8f%>=beASg#!laMS})kJY?u4mkt|#*@&W%qefqT#h5Fv8auA| z>hTjoB@?f?cGBeQO0Sp)cup+rXxjnfl-LNX%u-aRYZfNordW*cryv4zry(QkZSTbf#&y5C#oE%#P<39rd(_Eshjd8@qD$!*C4>E>nW=H=<;73sv?>BL5F zjrX9p)?1fu+K_HqmTp>^Zd&I(BQc2VtYEVHl1ilCk}e+y+_hbYtl`L zbko*!)24LO`gGIMbklZkgSXLp)Z653_O^Iiyd z3sd)bJ5x*2&FhovqqtTQQ6e4bUx_<(uJe}q=6(QT|^p08ce#FG=wyibP4HF(lF9+(q*I(q$1Kt z(kRks(&eNpNMlG>lCC0+C5Cru!QNF}6+q-#jmk|vQRlddC`lCCFBAx$Ms zBbAY+lftAKq;isxBBTn^Owue8t06j@bOWi9R7I*L)sSjQHVWl_VN zC>pOXGd!{TlfGEE8j~d!=COxWJZbyS$8%~8zcTo9#NwLjNGO;4W2v)rK1H87oAw`1 zhXxO%m-1$*%K_t|GAqAzepY@~ugqTAZQ6Ci+^p3X`oC>X&L@(c`Gp>XFIols9RV(* AYXATM diff --git a/PythonHome/Lib/encodings/cp874.py b/PythonHome/Lib/encodings/cp874.py new file mode 100644 index 0000000000..6110f46e5b --- /dev/null +++ b/PythonHome/Lib/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/PythonHome/Lib/encodings/cp874.pyc b/PythonHome/Lib/encodings/cp874.pyc deleted file mode 100644 index 6bbbc580dde50fd6dee65d2a6905e57a7c7ea488..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2822 zcmc&$d3RG)5WiWQhL*BRp=xj=ZmkOnDk2aTt2ES?N}*Q6Yu-znn$4G2YZWEXvhS3A zaY4lmcZIqBA?Nr>=Hv_bhaUiE?xT4HrN?@X$0YZ5?w$AM&iv+gXX^W-K76@zb0Q_K ze|+?JIgQd4nhYVjX!Z!hE3zKZMS@S59?|a=X_Eb7M2KM_Hg$Q05l{-BQUt3CpD=2a z!mkves=_afT48#XE+EomAY9c2gfV4I7gV~ssxByudR}zZ2xF?~3Mm6*DI|u;!7zK8 zh&FHlHcgTCA-k`TkHq?POHbLR6=~Cp#Z1085-S*HDv~NLS-dFHYvxT$w@o9GwhFn( z!nPId?XB^(iIxqkBXeuuG&%};gPiUo~-G- z#V3@^Y+8ko$rlG~<%elm1*;S#rBG98E=kSZ>oPsvV^&Jt3Q)qqc|*Z6h0Ss7!t-x} z(D>CG+$W?7ZMCJu8{O9!c#VP6YG|5_zm8!>>bk#ChQbcfluYLJoS978VYSE=jDajI zHP&eyp?i*!CIm;L=S3}z659`Y>wNYM5?b>q%gmX1ThFdm$XO}cRi7$#X3^524&5C? zxOCyH{}tYOwCi$&$U-#nF-_=BHzuNNHlCqLs7Mvm8k0;xr?Gd65-z5S6X{G|&$xO3~#1!H|>dV90#A2}6y` zlN;&8@G-aM(D-}!v}vT8JpUNA*<(ftIZj8ywoEqCVe(jvezU}sPEa< z&;nYPn1{ks>j`@5=o?hufon`3kJsl91ZzUI;VE_XQyZpDpD}aR>^Zm1ZJam1>GnJB zj4Zh8?tAXNZ(;QQ2OfOr;pUb{9)0ZbMNd4rc*#>wKeP1NWzQ{Nu`;%5^_sQMx4!V= zy0-ZG_LsCo$IBZ!H*V^BrTf*_lAHCOlwqcO`!fBnXLI>N@eQkF54<_}*3jGUY^rPoX@G@(jwe;Q>X_Vf97ei4WC}WDoX-;1 zOq;vI*gq^i1DUMhv?JOb$JPn!jB4CVomRcfNAH!mds4ggH-;Mhjs7NIQ=qmXcun~K E1TvV>xc~qF diff --git a/PythonHome/Lib/encodings/cp875.py b/PythonHome/Lib/encodings/cp875.py new file mode 100644 index 0000000000..72b160b02f --- /dev/null +++ b/PythonHome/Lib/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/PythonHome/Lib/encodings/cp875.pyc b/PythonHome/Lib/encodings/cp875.pyc deleted file mode 100644 index af78feb2dc98a01e15871c7489164e40d593b693..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2691 zcmc&$30E9N5bix$mMgb`pl-ZaFYt2xgF<_n}0HR6k;*R5USYg3b|ChMx=i)yKa zudIG!LqlC~Q>bEVO|W{46soAN3xsMLD{86&)pdc2Km#r+Z`{^c=Ie^-?X)~X-pbS6 z>K7N9_3wIZLWRbO_riu>c!%4*m5J3TMA08azN7>Fub}%XAr#$FxdR^CI5j{fB zG@LjBq+W`X&RBlV$Wm)J715gq#kW#}z6eA{=2|ZjGzv zD%v5V#-k#HSTfzIi*u-&meMkQG%_(|R-#nivN_h;GVLYPBJe~U%oPHbJaR{|Guyuj zLZYR!j*mzq+CnA7*~ga%c!_|Ma&TJ6c}>TJ)PwW-2@2hVQ#hQI6KXiDd&NT{rF6#e zQ6if}5nB5QXQ`(L7^@g(bR;R)a7`MKu(LGR(!J5S%!}$b@1va z%%Tfr{jczrpw{9Dk_BnvAe!KnE)Mz0Z7_xt6Ojt2B_f%CPNLHZN?4c*PDEo#Ic^0! zf2@QMMK=>tDWCQzz)AS4mE##zKxsMs2Pjga7EgP2+vZ|eEok!pU`WX|F(kgs!BC>= zWJNkZe8jC4IQ||!X%U(h&ObtJ`Lt6+j?xj*HC0YDX)!F4S>6$=s^~?^qRBffO(-+L z9V?GkI6|5~CZake?_J)aeRQwV|*VU%gZk)ELya9$x?ob_j~x@%3^+q z?=OA$kw8f|Nj!F9L+ zH{lli2)FsQj*sJsWGelM26x~m_!)kIyYMT&^<_ry{Iu({?$6;K{06@pJ;rXMm!E?x za238cM&Jiy)Yxb2HO7oRMxW7d3>bsP&=(u=r$tTernl?(RbvE&0}yt;PXYy2j^ zgu1)@jGt14w50x}q$1d_sN$P^uvkC@FsZPLB&t|C)#mA+3$2~8xMDT~)Xw0_ytiDm i&GlxZ+~B}<8R}iw?3~4(VrQ|l)KTinEpp#y&OZTad|&+l diff --git a/PythonHome/Lib/encodings/cp932.py b/PythonHome/Lib/encodings/cp932.py new file mode 100644 index 0000000000..e01f59b719 --- /dev/null +++ b/PythonHome/Lib/encodings/cp932.py @@ -0,0 +1,39 @@ +# +# cp932.py: Python Unicode Codec for CP932 +# +# Written by Hye-Shik Chang +# + +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/PythonHome/Lib/encodings/cp932.pyc b/PythonHome/Lib/encodings/cp932.pyc deleted file mode 100644 index 1108060af0d83d3193136b49b2f732280da91e16..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1673 zcmcgs&2G~`5FY=;`Kgm21gL<-fm2RBz^M{K6@^13=wWlHup*hnyNMjdPGoO|at_bL z%kUUH0DLoUoT!CEF0sAq+4;t^GqdyA``zvQy!kdv=`>%v z^)5vo8KSvQ+NBMk25D#0YV~`r;yG@pVP@mOw)W;jwH~t)mm|6Ax6nZ7C3FkK8A3WCxyvO zZpVvH;=Xv83a4JD61jEw9`wrPNhJ1rP()39@Cc)1AAx&6o{y5_5#!;Lc(NA{S8Hes zGtQJ5Yjea%+Sr*7v#N|^cahu_sXb;S+>kGKk<`u6hwhT~7nm$K4f^5%OFgn6H#8ue zzm>uG2BDq7Ve~J^Yn!B7-25AA4hNj?wdDq49w@v?aqlZ`d+CdG*QXT?iu>w{5{1;N zlvBgW;nemN-=%o6o3MyEl$4ft7ZzXT)1~lax4GgbRooeh%@o(;kS4b$_+Vxb&kQ6h z)~~QEx#mAoqZk75}TS;`vI6j!PY9w+ow2)>b%?SSDOHN#y4N@A8G>`bqef zPwdO~i-#1Kr2cDk$2&>dKHc}UPX;N+zu>AvrBI6hFb7qO3;nM8{k`YPm(0ggCv^Mn NbHD98^LV_*{TF@RGrRx* diff --git a/PythonHome/Lib/encodings/cp949.py b/PythonHome/Lib/encodings/cp949.py new file mode 100644 index 0000000000..627c87125e --- /dev/null +++ b/PythonHome/Lib/encodings/cp949.py @@ -0,0 +1,39 @@ +# +# cp949.py: Python Unicode Codec for CP949 +# +# Written by Hye-Shik Chang +# + +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/PythonHome/Lib/encodings/cp949.pyc b/PythonHome/Lib/encodings/cp949.pyc deleted file mode 100644 index f566ccbfd7a87a0fa1ef1632ba8e6bbd77d2ba3d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1673 zcmcgs&2G~`5FY=;`Kgms2v7lu1E-vN;!+8rio&51^sqTpSdmQP-9!$tQ`uXgoYQCG zWq1r80KOSFPSnC7m)PF*?0n$ak%%?k|HPP27Al)G2(Yz^ei>5B=poUwd0RV0b+!44{ z!yVE90-BPs32BefRIS#38d4}=X5d>(=?xzBMJ2MW~Df?5ToQH3!JuNpFp_Glfq;s zx8ubpabG-6g;TFniQGDT4|?VDBoh1GE21VoIL0X1N8mn;=cD9!z4_Gv|f;-R{tL?N{* z<NpY3|uC4-dXUvSl-QYgiLn7yjSg??B4{@!!tOXlN=6S{r( Nh2M6bdpzFY{tHdPGyebp diff --git a/PythonHome/Lib/encodings/cp950.py b/PythonHome/Lib/encodings/cp950.py new file mode 100644 index 0000000000..39eec5ed0d --- /dev/null +++ b/PythonHome/Lib/encodings/cp950.py @@ -0,0 +1,39 @@ +# +# cp950.py: Python Unicode Codec for CP950 +# +# Written by Hye-Shik Chang +# + +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/PythonHome/Lib/encodings/cp950.pyc b/PythonHome/Lib/encodings/cp950.pyc deleted file mode 100644 index b0929a5892fb4a64c4c8c9088b98b8f3ade3a6cd..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1673 zcmcgs&2G~`5FY=;`Kgm21gL<-fm2Qu7Y;}WRV^GUK@Xclg%!yp-c95vb}D zco`mp2Y_$JjT5zS$R)OSJv-lcc4l@yd%wG#pI1MI3Ef{l-lrJlFH9PbLkps)mK}=Jr^qKY8~~*OJF+cIah#7c6UVkAi)^WH7QB?5 z*uM<`m^^_jB2*A7FF;77@)**|=xaI|iD{b8%8>+ma=lUjfc@l~J?iEoJA3VV**+<|$jOVlDc))o0B%bZW!_^wv z!i+Oz#@ZY(k~Vhc!>lUf*li?NMQRTj2{+{HZ6tMb^r1Uv{V663PJ_O9z*3Ja$PEn$ z=Wk>%zCmbba2Wjy^4ccp7B~Nzn!^F-duh3Wm4L3v6y&?ekqvyJV1Z{0pu+R0^f|53^UbxX>S~-`^*$e93$~c0#xB OzVzG93y;TJ+ +# + +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/PythonHome/Lib/encodings/euc_jis_2004.pyc b/PythonHome/Lib/encodings/euc_jis_2004.pyc deleted file mode 100644 index cc5e9a9c8dc68d49d9098d00cd72179d727e8e27..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1729 zcmc&!&2G~`5FY=;`Kgm21gL-n5~rN13UNfJB5nH<6>*sqBqV&gGeS z86JZNfN#c)6SZ*3q1fK_?9A-${C(s7>UMryejO!r^Z59mVU#~HX?zYXiK3czC~~%Z zmm-f0(ZVO~(lta4(%?9>2xta1pS}}a6McyS(hV{mEt(>3(aa?s)Z!Lt2q12YxFh0L zE$)zpAP|is(Fkegk?zzQA!!IIjjm|)L?f&2Ew2HUw$bNxVqQ z`1R@O8`}V5xY8!6!{UJR9;1B5x;Vul7EXeGf27J}Pi;oAp6FzJIeg zJ&*Rx;@FLBVJ4X}6K(F_pf(IRt_^aeC@X_5i`4!HgScj&?+mI7rw`tc`Dd6c&<~*F z1D-vyXanE?n*NqXZ)gxI9%x621Ln3#y2bdorsinCZeLg~E{2N2pA^GGF*2lB(p?Q# zNGWc!E7TMcvQl!0JR*mCjBgS{xlMp3=qoMXK4c)C=d+byXm`2d%2iw^iq#ay;{X8I zBkY?Sm^B9ui_HrxO9li1q=6IS4dfj#v+5L;b@Ad#36CQlXX~X+ryDDHNi1VBn Vp=7KcJE7ZmpZaa*iO1s=-app;NTdJ& diff --git a/PythonHome/Lib/encodings/euc_jisx0213.py b/PythonHome/Lib/encodings/euc_jisx0213.py new file mode 100644 index 0000000000..cc47d04112 --- /dev/null +++ b/PythonHome/Lib/encodings/euc_jisx0213.py @@ -0,0 +1,39 @@ +# +# euc_jisx0213.py: Python Unicode Codec for EUC_JISX0213 +# +# Written by Hye-Shik Chang +# + +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/PythonHome/Lib/encodings/euc_jisx0213.pyc b/PythonHome/Lib/encodings/euc_jisx0213.pyc deleted file mode 100644 index 6873ab5e892384020800b90a623c1a9a47d4bce2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1729 zcmc&!OK;Oa5FS6`JemhWfC@+;amuNpa7CyhaHs@5Yz`GxB$IeIk*&n3?2RDj@SFHE z{0x2od^2vGsD(=o#rCdeXJ&Wj^^Nzd)B17wWf;@-M*k(XKSQq&vI_d+gJ&--Un4Z#);a4brUQC{2oQ zFJGO$wly#YOKsvREDkvDFp4Lvi&GpjE~TDC0EADWPiokQl={5gHZVm|HeQ%0vMpIG zmU=bkB`d^yz70T`jA_@=~44kH8 z?}Iqc;@m7uX2OBMwC6QRr4)c;G9SC!zScLr63(*tk7{4-1z=m*g8 z0nZ*;v;lAcO@B+HH`E9f545Ai0drd?-C%rds6Ono+ZUFLi=m?MC&lnkj0`E3WLLu_ zQu3SZ5;eJmtdJZckI3O3ouw+Fh==auwH!Vl~C_H~;|l z2>WIRX3c=ZeEkf|f&oDQY2dW+2J-fqS$2xjx+uL;!sCcXi`CpFleHDR#FjC+n8ea% zaJuYJ97gfNa^gO1ciip*;@dx!t}!XT+lTun?IT2@@;7l=uM#iCP3VxIaoFFK{qim6 Wp +# + +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/PythonHome/Lib/encodings/euc_jp.pyc b/PythonHome/Lib/encodings/euc_jp.pyc deleted file mode 100644 index 0a882836f7d7b454c662d16e82b24b5c3935672c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1681 zcmcgs&2G~`5FY=;`Kgm21gHgx1E-w&1PE0G4wayX&7s1IWD@Ttauhq2y-}5OcqU$k z$KV0rn{nerEgW)*?Oo5#%gwD3v0w1ufb8XAWd0nOm%(+{F8(YGid-5}%9qABJU&0Nw!ZElf<0p_-tJ7R9t z<_>8X0`WK#kC0{_=}zqtl7^x3=!!>AJi^+eN4m>{sLwHt20g@={=su&1Bhmw#EU!I zfH+)flhg@up!tYazGg4XcgVQ3@FaE!K1DvM(EwH&@O0Zk7svS|GjVJ?GRRhXz2qS~ zB)opLY0k2UP(iF#fe(pPUO>7We@Ulf!>(yQFUJ+q%e#$YXdzn3hZZ<($3BN}ohOCK zOl~L3&$52;G!_oNjwNzy{2uhmH_IQH)Q=4Ityll#Q4Bfk1Qw-4QS`@ zWbnR0sA(`6MGOktCg~P4U`x%>fCIj#@#V|B%gLXuU= zx#8?^ZU>5c$)4;cR1$ubmUkaA)voi|O1QG$TydQ$t_{U*it}+)q1!Xem>U3^gK5R) zErul*K7odT6XFfz9k8;x1u9&)Wt8YR*KxL9+H|_H!i&T*>#}JgR|r;@8Hy7q_$?pV z*WHY#JeR2c>-4}qiQ2wAT +# + +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/PythonHome/Lib/encodings/euc_kr.pyc b/PythonHome/Lib/encodings/euc_kr.pyc deleted file mode 100644 index f2fad89a65e0b8bcbd61e275ce98c9abad96d7cd..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1681 zcmcgs&5qMB5T5)r{n@ld2+%G_960r~Pk_*B3x}0p5AI<_R4KHvTctE9N?f6y%QNvZ zJO&Q{-%Pe?wF`${n#9g{W^8{mp3mOzZs+ISmr+9ZkB|QqTKNl|#^=zID5_I|Eq+zH$y5i9jkFfUWk?!&!>T^t^K@ahzfAHMe0HRqZ@z=sO zAP!gBBy~a@Xs*%9m+Xc44jGpgp2QBpr^qKY8o){eo^D&{;y9mVCXQ`K2H8rlmpo*L zgx9Y&%~=)^Du~r8@F9`P3rLsakLh%5*fq`P<+wt6`E8>ZT8LKip#@Icu}>k~F+OnBBMXW{1KRmJ z8N6>0Y8p&N5re|ENxH=h*iv&e;DB!}7ZH;|;ZKSQpqOw{8tJ}PrNB+`P+jq&kYtr| zZa6!f+kxV{WKVVzDha>;0u?UYGD>uu>o{94Z93gp;YDJZb=fqLD+H^{48;i){FaaG z({9FNo=a5!b-L%CL~WlRu5`!;$;ZFURgFrf6kjvPrHfPjwz>u1aqdgz +# + +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/PythonHome/Lib/encodings/gb18030.pyc b/PythonHome/Lib/encodings/gb18030.pyc deleted file mode 100644 index dae6efaeb6adb3b0c6e83e7ca523e3bc4137158e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1689 zcmcgs&5qMB5T5)r{n@ld2+#r&2Tnb$7IEQ#(2BxgCD?;|SP@kUZR}R5niM5op`Mp# z;$?UY9ss_Xv}v^qhhCb*&Uj{Q&o`dW-tTVb=k?c7LYv3O{{pT2g-+vhXh{^+vO|%x z)w>jVWQZ0%X_szcYLJG;p+!J5xcT&h=$7b96p(I^@o3Q$bBks!>7X{ZNW%bgTg)9X zw`y~TGz@`woQOwAGmmtq_6SMCP$_|iXku51(HeERCm z`RjArfIM7jlhhe;pm~p0K0^nzz;9eycmf`RPmxb*G=P-`Jl(d?#c@8#OdQ*e46>EJ zS@Mt_5?XGc+e}CJCS(Z17qTBK0qsZmB76l(FehK)QI>z9_>ZM z85`NcOfqFA+8i~OHugTPV{z;*mg^$5$Bl(c^Z728x=8xa4OxGI&Vt{dGCnZYBMYKK z1M>M>8SHNm3LAVzC4*E5C?>?>=O{UFNfu@MX8T;!;&y9g5u)=i{(qw;mh*P8?_^vrHU!3f>)n)jOvtKeVPo2>1 OyHEYL^Tgx!67OG3^fqGv diff --git a/PythonHome/Lib/encodings/gb2312.py b/PythonHome/Lib/encodings/gb2312.py new file mode 100644 index 0000000000..3c3b837d61 --- /dev/null +++ b/PythonHome/Lib/encodings/gb2312.py @@ -0,0 +1,39 @@ +# +# gb2312.py: Python Unicode Codec for GB2312 +# +# Written by Hye-Shik Chang +# + +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/PythonHome/Lib/encodings/gb2312.pyc b/PythonHome/Lib/encodings/gb2312.pyc deleted file mode 100644 index aaf77109740a3d2466cc561c0265c37d8ee79f7f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1681 zcmcgs&2G~`5FY=;`Kgm21gHgx1E-uSQLYG81P+y;hs~kFiewV+CUO)z$leO&9G;1n z;W2ms_-5QVQ45D$Vtd!KGqbzj%+9yo?{4Sk&DT*vcaM+%C0h9loyO66_uCz(&ggDT=M=PJBL$C_FRvPeh+d>z|`6M%OY&$Z@R{D0y zLv~1bec9CHEQ<&g#A+4zkVxejr1SBobUGH-G@qB_3hDW`wPI)?TFHkNIBmy1hH#Z9 zg~?2AC(Dnre(^9C4!({ha%=n^^vdN;d9@ zjcj2inKBb?jtQlWtxszxj@?1IDN=h>C|s27BgT&&C!4ZzP4OMOa_HNDJFno!bxeQyIQTdP~2BnyeK4D zrJNhi4(GO~_%7L#-GoZQuhR1FL#EnQK3fS_cAG1%Q^mER*iCUh4k~nef*ErIKyxsy zSii)uR-7al9U0dNrVwrW>G?6O=tIG_<2^9R6 zkL>ey#zUSbS*OXlRM6S{r( N%x^o-JZ`V>{smcHG`j!* diff --git a/PythonHome/Lib/encodings/gbk.py b/PythonHome/Lib/encodings/gbk.py new file mode 100644 index 0000000000..1b45db8985 --- /dev/null +++ b/PythonHome/Lib/encodings/gbk.py @@ -0,0 +1,39 @@ +# +# gbk.py: Python Unicode Codec for GBK +# +# Written by Hye-Shik Chang +# + +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/PythonHome/Lib/encodings/gbk.pyc b/PythonHome/Lib/encodings/gbk.pyc index 26905d35fe9a8930b16b4319b40b9782442c5afd..f45478a92e0feebdef8e0aee97a30239c731d32e 100644 GIT binary patch delta 411 zcmdnbyOw{$97aPY1_lOKtC;l6l8n-%nDG1xJ+EMYzn}o;82{3eg3^*0m(--v^q7Fk zl8pR3kNn)!$&4&wlMgbMlBqMAshCWipP6#W)Y-~RhR)55ELP+NkLc!jRv|LAPM*r9 F1pt`biZB2G delta 153 zcmZ3>zn^!*97cWx1_lOatC)bwl8pR3BlF2;8M`sWI+;2##GIL%F~q)OifvxaVufi* O9=q6P9X3I167~QLB`R|O diff --git a/PythonHome/Lib/encodings/hex_codec.py b/PythonHome/Lib/encodings/hex_codec.py new file mode 100644 index 0000000000..91b38d952e --- /dev/null +++ b/PythonHome/Lib/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/PythonHome/Lib/encodings/hex_codec.pyc b/PythonHome/Lib/encodings/hex_codec.pyc index 4d91f2aac7d1a6a334ddc4f27c85d73cf66e9d92..1aabdbd20b3e9bbd8a7c04062e56953540b56040 100644 GIT binary patch delta 759 zcmZpc-K((SIJ2P#0|P^On82Uo>#EHUr>N^jDKlKL1{^hOKMVSdQ3oN zNk)F2M}BVVWCuQ(&7YWSnaI;Rc^2DVGIchwr<18ugd>0~ozj#0IBt-sa{{LWnL2-Q nUL;fJS1xNZbw+U~ld1DLxjHwO@Q5>#WvR^MZM@ZF>2wAF%bN#^ delta 317 zcmdn1&@8**I5WQ*0|SGzRZKu-Nk)F2k@;jtF6qg4**G`Lu#__4klcq={5g9DR`J;! zfmp<4CR=h|$08n$MNDS$ORfu8#o2hQFvJUa>M+C{xnw5W@Frms-~5_aj1h~3^kiTD K8m!`?0vZ6@jaIb) diff --git a/PythonHome/Lib/encodings/hp_roman8.py b/PythonHome/Lib/encodings/hp_roman8.py new file mode 100644 index 0000000000..dbaaa72d76 --- /dev/null +++ b/PythonHome/Lib/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/PythonHome/Lib/encodings/hp_roman8.pyc b/PythonHome/Lib/encodings/hp_roman8.pyc deleted file mode 100644 index 084489767f3b8ee5bd65536a6b6e9950da03eff2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3977 zcmdUx=X)I06~@mNt%@x-jBSB10|{7wC0Q}KNT#@mVi{W&Bfy{-*5f@RX{_DZ&CD#e zo`-MdFW@hrIDzy)5|U68dhh9`rclyDdL!?9$I?2spU1!lcvxwE=gz$|cg}gwxpyY_ zPJ7!O+jfkWaXav(LR_@38po=TJ%hq zPm3Cuvqbx07KjeOtPwpMW{K!IFpEXcg;^$g9!#g`T9|dB>tPlNE;hP>u^Al{Js;)* zL5M~#6uk&$qv#OKCee#wHj8e785a0qbgMuGqa&i1z_9j5%_O(yXaLgTSTvhfzCT%JkgynB~gX(MaN-=1Q#2f5XfdQpp!6x zKs^Hw&@#G9Ae+%C(K5^qLCYX2xM~m%qA^+#1Z>~|T1G>Gs|HTu$p$XtSq6?kU<0=h zn}H(;-)L2!kkOhTD5IYh_+j7yTs0aAqA?l^958q^rZt)f5@V1VNMn#LsArHa2yCD} z<}+FsNMn#0y#{8jAYg+kfrtjlgU$xUf>apYEl|%Om8b`Uy1?uPiwKW2sM8GBP&;dt zMLUnnYqV<*SKY#lh%+*sOjbi@aMFvsQsPI>7Oz$d!U<=vs(#6t@IycH5?`J1s9JGW zOxB99UfAE0>`7KQyMtts*OYj1Pi?xVtG);nTM@(mu#QVNjyN?hN}RB2JzBl`%(MEs2UZQN>Rah-^mmv2 zq7bT-vP-{~9ZAAtM8yZ8+!O%TW`FuPf0(X)ZFIe?E%0h^NDudaivP#f*6 zu$>ckv^~8GNM^QD3yD%sgaVJ_m+cyV0x6jNGZ*Szb zHl5yO^SXdjGJ45;kT6`{`hNkSR8TH90NXq`0GGnM6wYl1-mk~$)YSHX$6XX8X#tAG z(5v{xV$x<$DpjqQaq4o+odYzUWm`v;$i+Rv#Ke3?Av-shEJ9-_EJc3B4->C^fz>Z6 zq1XOqOK34p(-Oj4Nu^OX%>LmbABWyXt)OU7E;*J9-j*GsU7U6}0K`UX1$S9&RzjEF z+2UwuYpY|NOR5p{(c`63OK}`5t;;fW+W|Z0g>l>h0LK^o^Olh zqtUXJF|r(8*3KbXy7SqG<2|k{TWiPT@*~UWa=Cr5dR&M*St@p7D9F@|CXw$|wnYJU z$k{q%m2KdK%xGGN*s{13@t zeKj_=6kEhWV?#){?&bk~Y(!tlO8!gkw)9n^tN$Y&p$Zm4{seL)R{<5jyAH6H77 zEx9ZQmkDtx$@@)Z!Yy&ahc|e=C(-n&IE`7Gl4;EpGIQ})uz!J|oPzIRAh?mZpSX#5 zl(?CAoY+S^L41yQn)p2N3~>wbP2yJK32bV?7ub53tuM0mC1O8Mzs%N8h_4VoBfd)P zbAYe0^>yMU;x^(x#O=g4h)0Mwh;I?k5qA)OB)(02hq#aUE^#Mu7jZXn4{<#szn87o ziMNUG6MrWDMLa;fMm$KoMLa~jLp)6UlX#VQlX#5y6Y&q?7sQjquZgFKzY_l@o+W-q z{Fr#2c!BsO@gnhC;s?avi60WbB7Q{thWIJ5pZGoT3h^@WbK(!gUx*!y*CX~2@3QZ| z#9{~d8(TM=f>N807M2U&xmqpZ9gCcai$ji7nJ)J%yCf>!lwS-K^%f-4Ma6fMeW^rV zIN{r^*M61MYxt`4?b;izhJM02w|CBb$?$6^ee3a&jlw_b_GP~l&Pl%v&TGNFF$Kk& bJ>SvNk?+WN<~o~N+mFQpX#N=g&1w1{?2rV0 diff --git a/PythonHome/Lib/encodings/hz.py b/PythonHome/Lib/encodings/hz.py new file mode 100644 index 0000000000..383442a3c9 --- /dev/null +++ b/PythonHome/Lib/encodings/hz.py @@ -0,0 +1,39 @@ +# +# hz.py: Python Unicode Codec for HZ +# +# Written by Hye-Shik Chang +# + +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/PythonHome/Lib/encodings/hz.pyc b/PythonHome/Lib/encodings/hz.pyc deleted file mode 100644 index 9a9ae50a658516e43b9d91c8acd2bd5f58d1e078..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1649 zcmcgs&2G~`5FY=;`Kgm21gL<-fm2R>0)(mt4wayX&7s1IWD@Ttbrd_u-U_AH@Jzf6 zkHG`LH{-^MT99&z*Snsb8Sl=_e&2e(yPcocUq=buKR&+a=;bdA8m~i3qNtV~ikz+9 zrN|>gwD3v0w1KHX8XAWd0nOm%(+{Ez(U&M7-5}%9qABJU&0Nw!ZElf<0p_-tJ7R9t z<_>8X0`WKzkC0{_=}zqtl7^x3=!!>AJi^+eN4m?CsLwf#20i4L{=su)U5Gb#wt>%Z zrA<;7!-3`ky?liMi6V95(!!IxA@~&eq(%c+X~4hR7KS*^Cz*+3+mT7O(zi>VvO~h_ z+W?ZuSr!p0h}9~vkVxfoNN3|u>2xfvX+AH){4Ul(Mvw8z-c@7DTK>BDNJT^ zJ6V2|wTs7jaME=ikz2>^L9e(BN+e$Q@Nk;&eu7@|0)hK5m=BWOv4Y_Pc(xY|*J)%6 zGs%>hXmhME+SvBA4#Tm#Fs_T#9xV(;;Oku&H6Z%X4OxGV!GggcD_(HYBhX<34d~@> zW$?Q}z%LjJz=Eo_NxH>o-%xWj;AF2XgNA{x@Fm4ySB!IkL%PFeh5O>6y5c|~g(~H| zaAr8KJ;isaoa`pF5iXUMcONpXF7w$+xUt(@F*X%rLb03TdK?UFdjjvdK`?W$s#w3l zv}B+YC>J;(S|Dw}%8Kn(OmUJc(Q%#Q>~?9>>Dmep63YzBriok?SY7^5Ts(>0@^O9M z{_&X8lF@&i?ztuzTfRW*mG(IxwfL90!lqP7@s)CTskp@Ns+;aT*Sus7o;so1cVGH# K=Y_}pE!tmEO)nz= diff --git a/PythonHome/Lib/encodings/idna.py b/PythonHome/Lib/encodings/idna.py new file mode 100644 index 0000000000..ea90d67142 --- /dev/null +++ b/PythonHome/Lib/encodings/idna.py @@ -0,0 +1,288 @@ +# This module implements the RFCs 3490 (IDNA) and 3491 (Nameprep) + +import stringprep, re, codecs +from unicodedata import ucd_3_2_0 as unicodedata + +# IDNA section 3.1 +dots = re.compile(u"[\u002E\u3002\uFF0E\uFF61]") + +# IDNA section 5 +ace_prefix = "xn--" +uace_prefix = unicode(ace_prefix, "ascii") + +# This assumes query strings, so AllowUnassigned is true +def nameprep(label): + # Map + newlabel = [] + for c in label: + if stringprep.in_table_b1(c): + # Map to nothing + continue + newlabel.append(stringprep.map_table_b2(c)) + label = u"".join(newlabel) + + # Normalize + label = unicodedata.normalize("NFKC", label) + + # Prohibit + for c in label: + if stringprep.in_table_c12(c) or \ + stringprep.in_table_c22(c) or \ + stringprep.in_table_c3(c) or \ + stringprep.in_table_c4(c) or \ + stringprep.in_table_c5(c) or \ + stringprep.in_table_c6(c) or \ + stringprep.in_table_c7(c) or \ + stringprep.in_table_c8(c) or \ + stringprep.in_table_c9(c): + raise UnicodeError("Invalid character %r" % c) + + # Check bidi + RandAL = map(stringprep.in_table_d1, label) + for c in RandAL: + if c: + # There is a RandAL char in the string. Must perform further + # tests: + # 1) The characters in section 5.8 MUST be prohibited. + # This is table C.8, which was already checked + # 2) If a string contains any RandALCat character, the string + # MUST NOT contain any LCat character. + if filter(stringprep.in_table_d2, label): + raise UnicodeError("Violation of BIDI requirement 2") + + # 3) If a string contains any RandALCat character, a + # RandALCat character MUST be the first character of the + # string, and a RandALCat character MUST be the last + # character of the string. + if not RandAL[0] or not RandAL[-1]: + raise UnicodeError("Violation of BIDI requirement 3") + + return label + +def ToASCII(label): + try: + # Step 1: try ASCII + label = label.encode("ascii") + except UnicodeError: + pass + else: + # Skip to step 3: UseSTD3ASCIIRules is false, so + # Skip to step 8. + if 0 < len(label) < 64: + return label + raise UnicodeError("label empty or too long") + + # Step 2: nameprep + label = nameprep(label) + + # Step 3: UseSTD3ASCIIRules is false + # Step 4: try ASCII + try: + label = label.encode("ascii") + except UnicodeError: + pass + else: + # Skip to step 8. + if 0 < len(label) < 64: + return label + raise UnicodeError("label empty or too long") + + # Step 5: Check ACE prefix + if label.startswith(uace_prefix): + raise UnicodeError("Label starts with ACE prefix") + + # Step 6: Encode with PUNYCODE + label = label.encode("punycode") + + # Step 7: Prepend ACE prefix + label = ace_prefix + label + + # Step 8: Check size + if 0 < len(label) < 64: + return label + raise UnicodeError("label empty or too long") + +def ToUnicode(label): + # Step 1: Check for ASCII + if isinstance(label, str): + pure_ascii = True + else: + try: + label = label.encode("ascii") + pure_ascii = True + except UnicodeError: + pure_ascii = False + if not pure_ascii: + # Step 2: Perform nameprep + label = nameprep(label) + # It doesn't say this, but apparently, it should be ASCII now + try: + label = label.encode("ascii") + except UnicodeError: + raise UnicodeError("Invalid character in IDN label") + # Step 3: Check for ACE prefix + if not label.startswith(ace_prefix): + return unicode(label, "ascii") + + # Step 4: Remove ACE prefix + label1 = label[len(ace_prefix):] + + # Step 5: Decode using PUNYCODE + result = label1.decode("punycode") + + # Step 6: Apply ToASCII + label2 = ToASCII(result) + + # Step 7: Compare the result of step 6 with the one of step 3 + # label2 will already be in lower case. + if label.lower() != label2: + raise UnicodeError("IDNA does not round-trip", label, label2) + + # Step 8: return the result of step 5 + return result + +### 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/PythonHome/Lib/encodings/idna.pyc b/PythonHome/Lib/encodings/idna.pyc index 5470ccc29a833e3e17d80c1dc0d6526c04c3367d..260b5bcb7f5c94ad57bd2cbc36cc5ea4bde30db2 100644 GIT binary patch delta 847 zcmdmIILmZH4kIJa=3K@WW|I(6z(vldL z)TGk%n1ITXjQl*0{M^*Zf}&!R#aM$G**0gf{$?c4fX!X(DNN*Poh-~Xi;;EnIRz%-s+fj)?9vMSSy)UJ-+YPR0K0X2M0qEN2_<9I r#3)>XOH&0l4U=oclCX$ZVi6PHd_i0Tn-|0;+e<#dqCsqOmXrYicE@6% diff --git a/PythonHome/Lib/encodings/iso2022_jp.py b/PythonHome/Lib/encodings/iso2022_jp.py new file mode 100644 index 0000000000..ab04060693 --- /dev/null +++ b/PythonHome/Lib/encodings/iso2022_jp.py @@ -0,0 +1,39 @@ +# +# iso2022_jp.py: Python Unicode Codec for ISO2022_JP +# +# Written by Hye-Shik Chang +# + +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/PythonHome/Lib/encodings/iso2022_jp.pyc b/PythonHome/Lib/encodings/iso2022_jp.pyc deleted file mode 100644 index 188d09d03391e12241009a6b4c44dba43aa23732..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1718 zcmcgs&5qMB5T5)r{n@ld2+#t81E-!=sAq&$6b>uF9^AuatHdkRb9p9S zhR5Im;G0RCRJ(BKrAh3J=NsEIco!dtCf4(TZQ_G(L+~L_sB66j*z` zO@Tu((b6St(-u&JG&B}1J(|PJr5{9FqOXBRx>)?Ahv1gNc<373S3g-0Z>CZChpL`;)xQA}!YFK#!A-Sg23K0MEATjnu@ zt1QanG|tR)^-1=~AI8H;sNxCiDh3C7WpgJIuY0^(P0V_PR`5ceec!2%678v-;)8i| z;1uU=Z1Q-Ts(7m7Q@hi~_UDy5mZ{yj$rE#OcbEw;Yj>)G=|eYS{UtgB#)I7Wz+s0B zs1FV3=@$!L!94%;=5!}b`yFD=L*BSkC=W}*?cYBsW(?#vx;j(v607wtwW@*iZe^0$#t2y=!*on%k=!rXLZ&Is zqy%F4?7r-0JiGuTy#E^Q2r1#4r-v&Y5=0X7FSsmNNtxpN=lHyF-rtqi +# + +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/PythonHome/Lib/encodings/iso2022_jp_1.pyc b/PythonHome/Lib/encodings/iso2022_jp_1.pyc deleted file mode 100644 index 8264d7112dc15d131646eee41e31daff9bda4151..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1734 zcmc&!&5qMB5T5)r{n@ld2+#r&NSu0FLC*-SC>&OTJ-CMzQKitvZk4J{SBY1s=kiRv z43EJBz&DdNt#;wk!;-|#cxG(Re4fwVuXgLl)z@J{+sDWM9Ig0?PUCZEK@?T8Ly@!7 zyA*k3h~_?Nmo_lfNJHb$JfJDueELqbA^H*pq-$h6n%BkLps7nbsLT!0Fu>dtb4$#P z%G@FiLm(a};t|r+Bi*VzLeeml9&PdHh(}m?bV#>(5Oq1HVXuSy(%*P4ZOCG=>c8&y z+eY`ipaY+Eu| zuJp}`Zj=MGL}Vz3SzkmEF@C#64Ke|Q#u)mYnsi9(P6x2*K5TAavlXAVBjGCN*;lwI<>88Hx5Mv+@(;X$ul?nL5sj|r@fc@NMEUMg^JhxI`+zW=cJ zcpe>u#n=sPZpKSx#@gI}KurX2S_R}tQI-K+<*EG-0ddVf-v?9`P8YfX>(9|yupdOn z2R?gbaScENYWh1FcSDU(@nAbj95lCe(hcUvhU&u}r+sO;xR@#me^N{j#mtamN%u8e zG9|yQE?JWcWQCj|&JkyLp!g;j%5Fk5VP9c+_W={}BAc#+L;KAYSFYkZQS7D|k0S_R zPcUz05Y`Ml%-1h4ESL}kk_JwQH;}i-O3UcRWpweD<7#hM-Yjf7Sz94ZVwsrBNg{U* zwvcIxv6NISpWf%)jJsEXB=}FKEinZE`}lCBLz)OQe>0awE1)U9iH<>zv42}$n(z29 V3MTBS6S`gZso!*-c-&s${R4TDNO%AM diff --git a/PythonHome/Lib/encodings/iso2022_jp_2.py b/PythonHome/Lib/encodings/iso2022_jp_2.py new file mode 100644 index 0000000000..9106bf7625 --- /dev/null +++ b/PythonHome/Lib/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 +# + +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/PythonHome/Lib/encodings/iso2022_jp_2.pyc b/PythonHome/Lib/encodings/iso2022_jp_2.pyc deleted file mode 100644 index d8e1404948e5c7f65820d1af82c81bab3163e804..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1734 zcmc&!&2G~`5FY=;`Kgm21gL-n5~rLhlyikD0*6Y_!{$(7MKXzZ6FG{L%H9g)9G;1n z;W2ms_-33qQ45zGitSy`&dl!4d^_KIzuK)I*I$PTZ66>13$)@VI*rev1yNMV4n@vR z?^5KEA)5Q7UE07@BMps1^MIys^XWU$hUiNakgk#OXkHg{gQhO&pfWc|!vJ$r%q=lD zDszi841su@h(}0Mk94c@2uZ_GdbGu(BOYPp(IMUDLDc1(hP@8*OMm0JvLTDbs{gj% zkLNdW-`1cQth7lgSR82HqZKdEA!UGIT$+1=00f^RpVY7iEA@D~ZJ>+e3yc&Wg>8`cNO_~FCi z<9Tur7GpQGxfy55jJ0|AfSL&4v;u?Sk)bw{U?uHtn;=y*5IB0I`q#MkS4b_J|PW#GoaWPdC{-l^5ikTtBlJ0A` zWJ-QlU9u(@$O<__oFmTgK=Dm5l--1A!oI@t?gJ*`<#M_b4(&HrT)B$tM6sJ0awE1)U9iH<>zu|F>_&3Akl V1rzqv3Ei&y+;2M1JZ^9B{sEK-NPqwU diff --git a/PythonHome/Lib/encodings/iso2022_jp_2004.py b/PythonHome/Lib/encodings/iso2022_jp_2004.py new file mode 100644 index 0000000000..40198bf098 --- /dev/null +++ b/PythonHome/Lib/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 +# + +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/PythonHome/Lib/encodings/iso2022_jp_2004.pyc b/PythonHome/Lib/encodings/iso2022_jp_2004.pyc deleted file mode 100644 index d53918cb50835e29562f13cd9ad1e8ed6ccde8dd..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1758 zcmc&!&2G~`5FY=;`Kgm21gL<-p{JaxDB_4vMc_~gde|H)tVkyDI+3H;sqC##&f%GO z86JZNfN#c$6QywJCAN1xJ2SgGf8RL2+pV9s-$oH_9~b{CjN%t2jnASbQBctq1=fyl zQ{Yfcv~Wq=w1KEb8XSuj9?hWU(hs5y(bvEuU8C5cMP0-Vn%ShiO57j~0mMxaw?y2i z#4XYgc%pG88a~Y&(ydCvCk;WV(H4!4X!w;zhjg14L6?0R^*Zn``Ge=ibeSwxgZ^L; zF7CoXzyH?Mz#Fb~995CA!1;htyut*p5r^2Og(E=#;Zop|8ucKh9&a}dOktQ!(l`uF zOBU%$-!FN|3K5@gJWz4Qw2)wdEKh-igeopTU5-B|)3K-~*}NDZnS6P-R&1k>QE(bP zt7)01Ag;40kJC6aljSG5D1Yb_hof>Tuq#I#@RiMzP<-wqZL4GJ6O4jS^Xy~GK8oKb zv5fQd?7%XP;K=0hBvtW5$0xC=2^-EUn=G@p={8TyX>8&We!aJ;Dk8?ukoi}b4Eh0} zj}HiU$e=NR1F*U~8r`Bs008ihiU;sbopgiYvZ4B@$DZF9E;L4t!k-kQMKMsMYLb0D zm%z!7*(Hc_iCQ6HX3q)3p%*MTT*jP9y0) zxI(rm4ySlyIDubwJ05lh@$tV(TaZc&%=5#O4)G$<`IopXU5T6G#`MVGaR%O%o%B7Y Vq+sx#TfW`3U%E}}g~Q_l?_WDbO*jAm diff --git a/PythonHome/Lib/encodings/iso2022_jp_3.py b/PythonHome/Lib/encodings/iso2022_jp_3.py new file mode 100644 index 0000000000..346e08becc --- /dev/null +++ b/PythonHome/Lib/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 +# + +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/PythonHome/Lib/encodings/iso2022_jp_3.pyc b/PythonHome/Lib/encodings/iso2022_jp_3.pyc deleted file mode 100644 index e4f7313a94fa5065a9d4531db918c8643277d260..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1734 zcmc&!&5qMB5T5)r{n@ld2+#r&NSu0Fp>joNMd7d#?7=;(h$@9PcB@ovx=Or4J(p+V zWq1r80KS>DX|)TN9+o6_#xrAk=JR~^ezjXauD%Wv+CD!1=V--GbQ+&S3!y{1R(en`J{$DSgFU;Z3A5#XXB-bW80F! za;0w;JYHyIv~}knIPFWz#l=)n_>*FKC}xHfOS-S& zk}3IZb;+7sAS>hyagI2{1I0JNP<9id3Hu7myAPO%7uj?r9NKTLxN;TOiDEa!cpO0h zdxCj0gRo}cVZMHWVZnqTkTh^Yyn(zuR$4|kE~AUL99Mh8@@8Sv$=V8O63fI~P7=9m zu!T%hjHRSv`Sd>TX576BB*A|=ZHXxW*vE$}9nwUg`J1^cS^-V*O>_)$jQ!j4(tO8< VQ7~aoozU&NPyMFz#N+k~?;oyyNQeLc diff --git a/PythonHome/Lib/encodings/iso2022_jp_ext.py b/PythonHome/Lib/encodings/iso2022_jp_ext.py new file mode 100644 index 0000000000..752bab9813 --- /dev/null +++ b/PythonHome/Lib/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 +# + +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/PythonHome/Lib/encodings/iso2022_jp_ext.pyc b/PythonHome/Lib/encodings/iso2022_jp_ext.pyc deleted file mode 100644 index f5db188579074a57110548f332910eed2de94809..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1750 zcmc&!&5qMB5T5)r{n>Pj5TFGlBslf7LOmn2qHtIV_TU~?M3q7tyH%>DT_s*Y&*hnT z86JZNfNv&kT6W>mOOx0c&y4Mv&-2;))o%T`{xV2t^Z58*pcOySX?zaNiK0q&C~~%X zmm-f0(ab09(i)~3X=ogp1vG)1Pv42wM4zL8bd8Khv$~iYG;v7>mAOG02AG>-Zi%^3 znOme`2*l$=JVKgyq+69oNE(LHqb(k%;t^IJr=;6Fh&r6ppnHn^(%*Qltcb<3_qx}M zXE(9=W^E1D{!*Ky0>**n9a`}W9g+qN#-*7j7(nnT@<|Q4uu_+&+XlKgUW_sm$F?Pd zY^iVOJYP9&Qp7okhprE??S2yr~_S}^%v+YZUT@V zAGqz2#gzaJXzFie+!HlI?SuI!c2M5dNjI1&YpM^rocNXHB4g4h{7ErU6mvvMCf(I? z$(j7Fy5vtTpcQhCI7^)4p5m*ZD7y*egolOY-TO?*%f)0VT-t4}xPBGaiefj#cpO9o zdxDu$gTSU>WWIWVVZp>8&^2&Eyn(!3R$9h4F5` +# + +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/PythonHome/Lib/encodings/iso2022_kr.pyc b/PythonHome/Lib/encodings/iso2022_kr.pyc deleted file mode 100644 index 07f1ff3697c7c2bb790a2d0f291c63ebd8fcfcc5..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1718 zcmcgs&5qMB5T5)r{n@ld2+#t81E-!=sAq&$6b>uF9^AuM(@d}DiNJfEH4-OkUOFXM=IkBk2$TJZ~=#%IxrD5zwM0&B0g zDR3wzTDqid+5&2jhQ^|$M{}6D^n++i^f~ZIHz;;!*%Y`%bDOkR!7b7N0JjD12;8dR z4ru_MSe%K4PjiQKr?T)#11K%JV$l-|zq06&?(!h$b4=qw5Ah{`@LZb?i^Y2QdN>Tf z=B9z+XszR@N{R)|JG9~%Is}Xq#5OG*i64SXflF#U07?U%Zd&NVFq@`v7|Qx#n6CBh ziid0v@%qMt6lW}p2o=O~6(A&1@dDDtmKh`6SE$m6}*sV-*xJ}M0;wd_+TC# zIK_Dzn>?PTDxT{2)b6yg{dwh%WombB^2D6n9cIGw+MTLk`p}J7e~He3@gO%oaM&RO z>O%uMx_cS-L4#1|U^ogJ)HY4hEoQ}*n&SZneQmg?m>>#&QcMcPe2_9p>e?;&k>6F9 zT*)P2g`6MG5a)NG_%0cg-GpAkxx(=7Bc|U~HeU;O>dh6`tl}C`Y^FFLM;E?1!>mON zrxsvezIlmZ!9*ZX)3bcMp1cEA8qRH4`WEhZt!f~>U72LIF+!HeFdfrbB=-xpkZFoD zDS;S1yHEQW_b&hm@4rSnLQ44N@!?8`1d+u23oZ**Ql|L+IX-Wk_c!G=`IZl&V4|K| QzTLN 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 -> + u'\x81' # 0x81 -> + u'\x82' # 0x82 -> + u'\x83' # 0x83 -> + u'\x84' # 0x84 -> + u'\x85' # 0x85 -> + u'\x86' # 0x86 -> + u'\x87' # 0x87 -> + u'\x88' # 0x88 -> + u'\x89' # 0x89 -> + u'\x8a' # 0x8A -> + u'\x8b' # 0x8B -> + u'\x8c' # 0x8C -> + u'\x8d' # 0x8D -> + u'\x8e' # 0x8E -> + u'\x8f' # 0x8F -> + u'\x90' # 0x90 -> + u'\x91' # 0x91 -> + u'\x92' # 0x92 -> + u'\x93' # 0x93 -> + u'\x94' # 0x94 -> + u'\x95' # 0x95 -> + u'\x96' # 0x96 -> + u'\x97' # 0x97 -> + u'\x98' # 0x98 -> + u'\x99' # 0x99 -> + u'\x9a' # 0x9A -> + u'\x9b' # 0x9B -> + u'\x9c' # 0x9C -> + u'\x9d' # 0x9D -> + u'\x9e' # 0x9E -> + u'\x9f' # 0x9F -> + 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/PythonHome/Lib/encodings/iso8859_1.pyc b/PythonHome/Lib/encodings/iso8859_1.pyc deleted file mode 100644 index d3f1dba1a3574dd6a914c08649cff927fe37a7f8..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2733 zcmc&$`Bxl85bix$Hjq2fji?(h)&meVnrMs!a)<_kvnUCon_*`b2KT_3!H7mpvgE$+ z`@ZiRa_7COKgmBJR`tM65`7PoA9SIM>aOkTs;|GU!uMxsxW8plJShf0KKffj!x|u= z3DHW@BQ&o_dqgWKKB0R=msg}n_lrIu@m0Z6yU;P-vw*X)O}kNYNUS4#-nTvrgWBC~WILjDIZaPS4J$Ww>Xd1T>S%|a)lJpbwP?!BWuoN`Gn<;~ z8|TKW>f`hID^)Bisw~vBy1tNJYos`dWG#3c^{?h zq4h?0yNt}TN78DNa?hyU2`5~+BvnEoVXN(F-Py$_Sb91oQ!ujKJ+_QPH_e=B#mFe6 zu*yiQY@27aw+(r*+6pid7S1jS%?NhM`3ujpB%<)v$5J4)330h3)yGp%7<`4nQ;JAD zZOo2yMr<(V7(-%*NF)+jHKQjIc34g_Ijtv6Q-y5`XX&0LwP8V0XpbnSVeuJ3Z;8(y zOGPS4s zZW|2}LS`!=SD0`TLWQG~^l-72{74yDHSH!ne7=knXZR?zN(rA+N<#XaqoyrgLh3sH zmuT{(jT!PD^gM~>EJ>UH2TQ(W2TSJ86Id!-sN8IahmpB9k;Xs6sEj7lv+AbwDqExr$tCwr-L#}Od~QsS2o0IrV<9NIs{JP+ zaB=1OHW)%7X}+d9UaukHye6k9Qaj`VOwWoQlz&L4-WFg^YeBB%)BtU2Rv|7Wc~KOP zF(n#pep*~rES?S)(28oeq(~AQZb5L$xB29`yWjC@S~~IKK^9-r!zjQnOR#mYxbPEpVxo!<-CT*`AuIb@#e3;X<4wa_1m`Z zzE3Pt+mo7}>gY7Oen@Asx$YlL%kKGU@z1@#{JP|~-~WK6und+%9{OMftb|pt8rHyC zSO@E218js%uo0NjLIa2xKxUAPDL;Q=niWw;#k*oP}{C9cBNxCYna zI$Vz%a3gNQ&A0`(;x^olJ8&oN!rizB_u@X>j|cD|9>T+T1drk|JdP*uB%Z?4cm~hn zIXsUS@FHHq%XkH^;x)XEH?SWE@Fw2E+js}>;yt{N4`O^<#87T?S}sX#jhli)3zrPc z1BVgZQ4}s_Hka<9|1R2ljI`$T3tD}IGQ&Q6*3jbeQOK{f! diff --git a/PythonHome/Lib/encodings/iso8859_10.py b/PythonHome/Lib/encodings/iso8859_10.py new file mode 100644 index 0000000000..757e5c5eb9 --- /dev/null +++ b/PythonHome/Lib/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 -> + u'\x81' # 0x81 -> + u'\x82' # 0x82 -> + u'\x83' # 0x83 -> + u'\x84' # 0x84 -> + u'\x85' # 0x85 -> + u'\x86' # 0x86 -> + u'\x87' # 0x87 -> + u'\x88' # 0x88 -> + u'\x89' # 0x89 -> + u'\x8a' # 0x8A -> + u'\x8b' # 0x8B -> + u'\x8c' # 0x8C -> + u'\x8d' # 0x8D -> + u'\x8e' # 0x8E -> + u'\x8f' # 0x8F -> + u'\x90' # 0x90 -> + u'\x91' # 0x91 -> + u'\x92' # 0x92 -> + u'\x93' # 0x93 -> + u'\x94' # 0x94 -> + u'\x95' # 0x95 -> + u'\x96' # 0x96 -> + u'\x97' # 0x97 -> + u'\x98' # 0x98 -> + u'\x99' # 0x99 -> + u'\x9a' # 0x9A -> + u'\x9b' # 0x9B -> + u'\x9c' # 0x9C -> + u'\x9d' # 0x9D -> + u'\x9e' # 0x9E -> + u'\x9f' # 0x9F -> + 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/PythonHome/Lib/encodings/iso8859_10.pyc b/PythonHome/Lib/encodings/iso8859_10.pyc deleted file mode 100644 index c03466e447f8aff8a68f82036e31635059ccc779..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2748 zcmc&$c~=}o5br%%mMgasiEg}Dj{s4liN=^f4$-i|S(Ic&H^a^>4DNw5gNR0j0MUey zi$KVIX%fQA@r**AIsWMG`67M=KR~SNft>_>FC>5HF5UE0O;=a_>ep54`Ku^6(YQUD zAX6U?{9g;hn1o3oBnGpKC~lH+kr*sIM0JriH%Y?UOZo`uC1hL7O%$I{c!a{AQ+SAy zClp?x2;>xAqU00REp$GT1OvgG&PSAjX`Nr_3UfL?QHt;(mPeFg5(@|eU@1U)!NDMU z8V#3V04bP4^<8FbHWR98m328`s(PqSZg1BzEuosMq9#I`kzKiR#j5!7s!)rXQFYl= zl~7X8rbFd*>+0)kBb%a?wb3p3P9;vumRD6YY;7nHb!uiSZb_h-iuSIGU{JdUpNQ#$ zV}*Ys@aHC`oAi1hXcx#M&UWFMVHSfl0nw-B_PFh?5Q!z=5I5!Klxpw76AU$#6d`Dt z_6}3{q3U{8H^QJKVltM%s-kJL*4#90#b|PX1TgGv0-FM~i2xAS<3u9i)(2t$xB+q@ z63Yi;kPv+d(UbCEdSs_<>xkKu(_sX~48RnRXXLaRkDEd9kj^R{DR`7nCt;Y*VPf@g zm?YRl@?jWwh~Hi4G3UXeHj~iRw3;#H)CPf}o&c%%KmF>iCH&HG(5(OfU6^Z%fUX|~Zs`piI6!g}R|I}0F@Z;N33 zJCM>GP(3Cm5x<4gmH|V|PSn&@Io+shP(X8BM5a~aiE%~mT~<+9wfwc$-&pbHTPs(+{m$xl*SxoOU3Ja+4I4MTU;Dv_o9iN5>OYdA z4Ih8fxOH3X)27cpk8hWo6N;K_Y1P`kNToB`_AhnA?D(ql>#lFU-SOS`KhSR4LwC|% z+DH58F8U+=iSDL*=m6bI2kAb#pB|tG=^;8q57S{fLXXfxhgf+%)S~u7q z>=wJt?y$T3W*E~2B*liOWE0TfushhqaOi+cusMOPMMB=1Si+}&X*73eDaCFaAia+? m55N7Q*{-(R>lzPiHn7=2cl4G9O1-7tGEbQ=zr=r!c>f0cM{=kD diff --git a/PythonHome/Lib/encodings/iso8859_11.py b/PythonHome/Lib/encodings/iso8859_11.py new file mode 100644 index 0000000000..27ece8dc7b --- /dev/null +++ b/PythonHome/Lib/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 -> + u'\x81' # 0x81 -> + u'\x82' # 0x82 -> + u'\x83' # 0x83 -> + u'\x84' # 0x84 -> + u'\x85' # 0x85 -> + u'\x86' # 0x86 -> + u'\x87' # 0x87 -> + u'\x88' # 0x88 -> + u'\x89' # 0x89 -> + u'\x8a' # 0x8A -> + u'\x8b' # 0x8B -> + u'\x8c' # 0x8C -> + u'\x8d' # 0x8D -> + u'\x8e' # 0x8E -> + u'\x8f' # 0x8F -> + u'\x90' # 0x90 -> + u'\x91' # 0x91 -> + u'\x92' # 0x92 -> + u'\x93' # 0x93 -> + u'\x94' # 0x94 -> + u'\x95' # 0x95 -> + u'\x96' # 0x96 -> + u'\x97' # 0x97 -> + u'\x98' # 0x98 -> + u'\x99' # 0x99 -> + u'\x9a' # 0x9A -> + u'\x9b' # 0x9B -> + u'\x9c' # 0x9C -> + u'\x9d' # 0x9D -> + u'\x9e' # 0x9E -> + u'\x9f' # 0x9F -> + 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/PythonHome/Lib/encodings/iso8859_11.pyc b/PythonHome/Lib/encodings/iso8859_11.pyc deleted file mode 100644 index 4f91741fd24c11b6133e47f5230d0cafb58598c1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2842 zcmc&$X?qk!5biy*SrWpn!Jvy5>p?Io3W^AX!zhF}ivlsaOm=3I!9C*aM2w;W8}9qQ z!TY`ssP=|DyJl;_NuJvZCdmg=)hwrhH}mCC#2 zVrs^UgwPw|f)CR}v=OsCI(>gHJnoK&E>C@@OXj|>P z25Fcyi#VbbO*Vy2&}meMDPl^Tz?c6yc|FCh|*|h^+cLHA=Zb) zM*4+?7Z%kBB^@GtXRusHR`JG?Hb>bP&4H{Ru2yN0aL9UQZ^8Cg@eUQckk=_VrGY_D z$6>o}*{!6>DD+gBMpA3fa;LXv#7m_o0FuD)muYOquuld+gl;7hgO^^D1Hny@Yn2wS z&B0*w4MxwXqv@uD_PsM^SAtG6C|-i5Y_?<;?QGUd>W5<48Z6MG!8U`_3^vo!jbSoq zk*KFp;Z5Sg- zcZf9+W({5K=1iL1b~-c(ovsGmV9sd}4USGTBtTbFB=3~WLXh<+5@xJ8#jC+J8hE2d znzYlUW}#whPy^4S#gor%{D}K_=z264YwG+zX!0@pXfl1SL(|}T6{I@~AenDdX#6{n z#yB$FA}1NY$s?W#Lq461=h|j*wd+s;t#Of=wuoQkL-n~x)r(}I`4k*$keHT6ksVW{ znTF2pnive*wEmkIxXQK!G1SuLqiSdU0-F3g<@ZPGj9iK7a?!Plj>y#JVoYo+&PAPi zp+|iy!4;({>N07jMW@FXjEhT!xpAeEQl|+@i)OMD)CIqgyVtAz>gDP)qwYaxMuYIW zO0hv7qTbi9tsH@FR~@B%Sy!ZBTZ1o@!Hh5%4uj9-rccvjuJ+j!4z)|q9hy#$6(*<% z)raDt2KvVJckmCUR45#Y#^QB}`sA2~#<5M~#!r|yY4ViYZf~A?N6WN3?@CR-`<{F6 zyMIRdfd?OYcxLOYN7^2J?D5%8JUM6XQ%}!(X8yAa7A|UEykzOJ=Q^H$Vfl*Am0d3y znN=^nyn4;r?pJzVeJ#7r?9EwrzOUa||9YWVDi6HjR=mMCH@r3U_B$KjeeZp>No`hJ zR8XbUI&Zx8MoI0;Q zK-i411)+*CjIb498^U&k9SA!Sb|LIW*n_YaVIRVNgaZf%5e^|7MmU0S6yX@cafA~H zClO8|oJKftthvl+>UYw%AF{8 zq1=sf56ZnL_o3X6@&L+%C=a1LjPeM|qbQG|JdW}N%9AKhp*&slPePi>Kv#g 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 -> + u'\x81' # 0x81 -> + u'\x82' # 0x82 -> + u'\x83' # 0x83 -> + u'\x84' # 0x84 -> + u'\x85' # 0x85 -> + u'\x86' # 0x86 -> + u'\x87' # 0x87 -> + u'\x88' # 0x88 -> + u'\x89' # 0x89 -> + u'\x8a' # 0x8A -> + u'\x8b' # 0x8B -> + u'\x8c' # 0x8C -> + u'\x8d' # 0x8D -> + u'\x8e' # 0x8E -> + u'\x8f' # 0x8F -> + u'\x90' # 0x90 -> + u'\x91' # 0x91 -> + u'\x92' # 0x92 -> + u'\x93' # 0x93 -> + u'\x94' # 0x94 -> + u'\x95' # 0x95 -> + u'\x96' # 0x96 -> + u'\x97' # 0x97 -> + u'\x98' # 0x98 -> + u'\x99' # 0x99 -> + u'\x9a' # 0x9A -> + u'\x9b' # 0x9B -> + u'\x9c' # 0x9C -> + u'\x9d' # 0x9D -> + u'\x9e' # 0x9E -> + u'\x9f' # 0x9F -> + 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/PythonHome/Lib/encodings/iso8859_13.pyc b/PythonHome/Lib/encodings/iso8859_13.pyc deleted file mode 100644 index 64ecc406b8b42e1185daf8bfaeec48d7e71e3ca6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2751 zcmc&$`(G4Q6u?Sp29jIsn5FiU%A z^6;ISeblm&kC1`>aAxKo;a}(vuygLf4p^U$=nu8az1%rx?z!iD&-b3Qp1(?iquY1I zl5FbZ!TTKtpX?ht-lNfzQ>`2(|auHu54hdasP0RK!Izf}uDIS87 z?da6GAF`_ER4sx^#wTq#uBuwLD6K8iR*(FTPMt>oQ@DEdH|EWjoG9sXXLCdrZ;j7)g(&!r@*Ae_-Hc;uaLwX_7DmF3G_0Q zI+Q`~AZt9t8ob(}ScJ?*6`U9kmxC@4=QxN0dB+*zpvx(eQnF&&iFytJ6IK-BOmKw~ zI;a#UZgi8F)?^Nh7qv}36N%$?9wu~53c4E3Ji<#}Jf(5j|MPk}|dXbW9a}lc-t{LZ(lU64%zM4aH zM3E2<9^EV-1X+~+8y~33RyaNs!lqO;kh~rz`%c;Y5j!JQV!T{jAq7gTyDk*jvr?hY;D^6Xo3%Poy*sfkG&lz?P%oz^E zYldJCPa;3puC3$&Z&!`kRE}39=U9O*lt7FS2o8bra?jb+iK}fgx`XXfSG!i=qecW} zu40$pRf1nX|8`;vM4{W`_4$he#ld+crDf&w7c5+~c*)WS9tgi{mU0GHAT+Q>fFRXg;rMlHGzq01lwXfB$Ti>u@YUY z=C|M3zGG+n-In*>PwWy~laicjYgcxEkj`Xt9UrQi-ucmDY7jOz97YfsY+6uv5s11vRq^Q`8?Bv6TC#fw pN@wuq?gfDN+ckEFUF*Tk8udGDkls)r 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 -> + u'\x81' # 0x81 -> + u'\x82' # 0x82 -> + u'\x83' # 0x83 -> + u'\x84' # 0x84 -> + u'\x85' # 0x85 -> + u'\x86' # 0x86 -> + u'\x87' # 0x87 -> + u'\x88' # 0x88 -> + u'\x89' # 0x89 -> + u'\x8a' # 0x8A -> + u'\x8b' # 0x8B -> + u'\x8c' # 0x8C -> + u'\x8d' # 0x8D -> + u'\x8e' # 0x8E -> + u'\x8f' # 0x8F -> + u'\x90' # 0x90 -> + u'\x91' # 0x91 -> + u'\x92' # 0x92 -> + u'\x93' # 0x93 -> + u'\x94' # 0x94 -> + u'\x95' # 0x95 -> + u'\x96' # 0x96 -> + u'\x97' # 0x97 -> + u'\x98' # 0x98 -> + u'\x99' # 0x99 -> + u'\x9a' # 0x9A -> + u'\x9b' # 0x9B -> + u'\x9c' # 0x9C -> + u'\x9d' # 0x9D -> + u'\x9e' # 0x9E -> + u'\x9f' # 0x9F -> + 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/PythonHome/Lib/encodings/iso8859_14.pyc b/PythonHome/Lib/encodings/iso8859_14.pyc deleted file mode 100644 index 4635b4412916ef171f83d46cb6e8962aab727e86..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2769 zcmc&$d3O{=5br&+*(8KpgFzQB)`MUa6ciB>4xE|5fuT!C+F^>&-c2L4>F&@4}euYWG6)5Bk+grraL`V)74eK`gPTM{wfRJ+O#zi zWA{ED{J#Q+aT_Ovu|}L-OmVY>i#6iH!&Db*bF(sK~3)YY$zEUb%cpm!G1w4i!X)yB;m=Z88qvz4~Q$V^pxS5+{m-NjG6 z>BD1%@dBi7l+=(%A)Hin9ibDb_MyiZIIi7{)*dEB!ju5hPp_N07Bge?Ov8(#mc%n~ zG8t=gv2FP0W~Q5EJQ%bK<@L^X;hAAhL1_%5Ps;64+g%|NOT-~+%FPMY-bE)EY9cN| z&{FLkrtm}6^|Wq;QOU$)%*9nz(>krWY0Qez0ZobOl@snHfF!=n z#_{h!N>fqwh@2$+W{p`!3@JMiQ&;8WCSAh>V<12_~fM32~4ae z5gk#a0*8q1J|84iR{k3wsLED4J`}>HRMnDv1y1&zvil=;MykYkx$s(f$JW^9d_-); zPemPjp^1GfKoup!iXvg6MZHNEjEajv+_+asvC}xEMKD=&>VjR!^@(D;dg&r(*gY_3 zI1sOKf=-b{ajsok$pg`@>QeEvs7TJS5?v^X7$FfH66NKgvuP4nTU2xh+oh>@&BI57 z2+CZ=F2Ac3zkc!U7$i!$+#avbUlb?~mXwxFDW5uR`iz;gW7x%_war`!1wZfd_OEaXk^&Rbz8X}e#^=Y zTKOI;cg)IXtlW@w=em{ev+_Hv+%R-Q5A;F?`d|m_gk7*3_CP-jz+Tt~`{BUo4LAsg z;4mD4qcCXYF2Qj)0Vm-UoQ5-_x8NKM!7zLe=ivwV5q^RT@H1S5OK=%}fh%woejU9D zzri)Q4maQ?peL6h3pvQc9rzvo7`+XDhAD^0T 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 -> + u'\x81' # 0x81 -> + u'\x82' # 0x82 -> + u'\x83' # 0x83 -> + u'\x84' # 0x84 -> + u'\x85' # 0x85 -> + u'\x86' # 0x86 -> + u'\x87' # 0x87 -> + u'\x88' # 0x88 -> + u'\x89' # 0x89 -> + u'\x8a' # 0x8A -> + u'\x8b' # 0x8B -> + u'\x8c' # 0x8C -> + u'\x8d' # 0x8D -> + u'\x8e' # 0x8E -> + u'\x8f' # 0x8F -> + u'\x90' # 0x90 -> + u'\x91' # 0x91 -> + u'\x92' # 0x92 -> + u'\x93' # 0x93 -> + u'\x94' # 0x94 -> + u'\x95' # 0x95 -> + u'\x96' # 0x96 -> + u'\x97' # 0x97 -> + u'\x98' # 0x98 -> + u'\x99' # 0x99 -> + u'\x9a' # 0x9A -> + u'\x9b' # 0x9B -> + u'\x9c' # 0x9C -> + u'\x9d' # 0x9D -> + u'\x9e' # 0x9E -> + u'\x9f' # 0x9F -> + 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/PythonHome/Lib/encodings/iso8859_15.pyc b/PythonHome/Lib/encodings/iso8859_15.pyc deleted file mode 100644 index bc94680a2202ba4cac164c2dbb987e6e639c23e0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2748 zcmc&$d3O{=5br&+SrWpn!Jvy*)`P^TQBcH?a2SOUXQP1_T_!uT$>1JwW+FyWfrR_M z?;{{05N=601m3H9`$hZ;egLfMAv*zmkH8ep54`>QxS(7ZI35cfYm z`d>rC8l*`RqJ?IU(7Yn$5iPXv3Ed->c}0@ee$gvLj}S{*yg~~|g-jFX>HKYqlT~S^a6k0Jqv=j(!v}g%Q17s;AddR^rdm4+D zZ~!TqB8}a4M>Z3w>rhQKVe4jOq1xGLWZENjSxrww3@bZ*di9KWRdu9Y&*-LV>slmf zX48@Kg|izQ>l^0BD(hp5_?=3grd3r}G%ao_k1RLr4&IVrGZmfP72&XPk3J1{fR2^M z^N@N;Qp+AiXwu1bf=;5^OCD3;wDt;K`-BpUasuoiziyjG!cOor4?m4M7LTXN7Gjx4 zte`)yu)U(kM?rf?-r#PRo>}&2k|rqnwAvYW+?67^Bpl+l+LqFtU3`M2r;;)RBh%Ss zOFwke%$in|ltNC{6k1iZE->0!hpbqwE|3Isv$_;k}Kr-JZ(fD^D zl`*7xLQXP%6NfAlhMb+4ZR%>e*)*tt=DEmBtK}CtsSX#ZdeK@)KDlXi1Cy%}M8^~< zr6Hqxzz0QFwg1KkuCisW5Bab;Rdp<{p~<;ZPJg7%$d#Bb7hNm=(3;v@fQhXIxu{bw zw5e}}xT5rkf>@Mk(O~lhNIX?kxVw+y5JOY^I@@5y-b-i>K>Fc8idy{ z!E%{Id9G7i*#p_G>NCl#tVr&$3STIN8KE#73g_jqvuQI|+jVk>+NEuFPo+nT2`W5= zo}j0QzCrozTE&#|czymrupm?z9#vF4x@64QapNaUob=SwrIVj2oAT^)k*UwW@Zw7^ zmq%ZD^|jZhRaCxF_2ye|SHJV_^cnBHKl6iGAJ)vSt(!A<-u#d1KmKIF!iGhSpDMAY z&pvNnyrkue)-S(`FIC$Tnx1U$FqVCtN@ud2-w%02^TwY=$kc6}G{4*a16X7wm>Tuow2hemDRJ;Sd~#BXAUs!Exw=6L9j+ z)%|cPcN|XV`rr(lg>%pk=ivfegiCN4uE5pYZMX&lFqpdoH{d4R%I(bU%3X)MxDr?4 zYV5&YT!U+I9j?a>xDhwuX54~XaT{*O9k>&B;cnc6dvPD`#{+l}58+`vf=BTf9>+dB zfhX}7JcYmFY5Wb(;8{F}{dgWP;6=QIm+=Z-#ozH74&WeO#~XMPZ{Z(!8}H!VD5r}^ z$_-D;CaA%2cW{W|(t(-aaDrQl!o0P)gb)4FXzMakn$tK)I*c@rzWuV<&UD)AEFW#Q ZxY<#6^p}Q8{iXggUs<5ABzRBw{|4H+bTa?| diff --git a/PythonHome/Lib/encodings/iso8859_16.py b/PythonHome/Lib/encodings/iso8859_16.py new file mode 100644 index 0000000000..00b9ac8055 --- /dev/null +++ b/PythonHome/Lib/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 -> + u'\x81' # 0x81 -> + u'\x82' # 0x82 -> + u'\x83' # 0x83 -> + u'\x84' # 0x84 -> + u'\x85' # 0x85 -> + u'\x86' # 0x86 -> + u'\x87' # 0x87 -> + u'\x88' # 0x88 -> + u'\x89' # 0x89 -> + u'\x8a' # 0x8A -> + u'\x8b' # 0x8B -> + u'\x8c' # 0x8C -> + u'\x8d' # 0x8D -> + u'\x8e' # 0x8E -> + u'\x8f' # 0x8F -> + u'\x90' # 0x90 -> + u'\x91' # 0x91 -> + u'\x92' # 0x92 -> + u'\x93' # 0x93 -> + u'\x94' # 0x94 -> + u'\x95' # 0x95 -> + u'\x96' # 0x96 -> + u'\x97' # 0x97 -> + u'\x98' # 0x98 -> + u'\x99' # 0x99 -> + u'\x9a' # 0x9A -> + u'\x9b' # 0x9B -> + u'\x9c' # 0x9C -> + u'\x9d' # 0x9D -> + u'\x9e' # 0x9E -> + u'\x9f' # 0x9F -> + 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/PythonHome/Lib/encodings/iso8859_16.pyc b/PythonHome/Lib/encodings/iso8859_16.pyc deleted file mode 100644 index b8329e7aa31558bf751c7300cbab65b028a591d1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2750 zcmc&$c~=}o5br%%mMgasiEg}DkASE_qA?Q4AsPtIq9iN28Fpr2a1WdrL^K*;3FLr; zBSwxK#OE`{B$}u%F(K-E-8=8`Irs{GfLPVT?g08;NdC}Wy6LH!uCDskudCMaSDyDq zOa6DEm}Aj~!**-6w!g0OH9*+$yzBm!$E=_4db$o`<6NG`5$aD_Xg za1berE1X>6$tave$|ka%>s%xP2D}-ai%2_oSdqyvJsfxOPz&OOuge2|7A`k2@rGTr4Oz62aXy4W0*&0TncCPyPY z1SQ_yp>scERZXaxAC!bo+6GvaH0@EEo6=UaCJRUa!`#NP$w8Y40I@wtBm!<-6a&Bw zkaH1VE{;J!^aVsu$b#vA&#-t89_wLndrYRW-^hVKVQO*&m@ZVkL&l1=q@%UPGI6A+aSl z7Io-_I`l0MR+J>k3iy#0bvj-!EG`;yW4@9?r?E;4XR>0|1+$Q=OT}jOQhCmxdqB=$ z0A33Ooji&BT(h>K2fSU?#3Kn_k*s3{yifu%LO?hK%*%aeQ%A10$lwmNOI_{S2#*>P zl-ROuZd)#V-Td1D4IG4ahtuWG@??8+a`W;FR;*mLdd=E(4?SGC{*j^$k3Qzx`1lh~ zKJ|35|Cwi>dwx?%=?i5qzV!0u@>eRhy!zVK*SEbiA-?LD=1d+Xm3 z0uArJ*SK$g@cpI_J`5cYo5PYEX=zp3K8nWTiT00GP4D=m^V6=+K0o-ymxpLK?V-Ii zN&Dzw+D`}Q5qgv!qsQqW9ik`bNjgkN=qMedr|4JoH2s>6(+N6Br|21amY$>M>2#_u zb=c^c>%B79ea@Js7mW+_((E|BY}}$(joZcyy+*I628~|h_qpz~^aj0Y{E-@(ouD(u zs4-^zX53-jtcUfcdRbqppY^i=c7z>e$JlW;$cESnb}}_=B-tn%W2cN^cG{RUuCWO= z$)?zu)cEWqJI|)s1@=uU$-YeuuV$bL$V7=7$#_6z&f7-2Vz zDdRf3#cs11b|*D4JH`I=W5R%@*z%-A7+M_m2a_5WA&?6uE3ml;$Xp$Zc>1?SbB7X@ s%+>+Y1+=;M{pam=tJz?;IbgGf?GE~*v(QuMEOZt*id@+R?z_bKH?MhfqW}N^ diff --git a/PythonHome/Lib/encodings/iso8859_2.py b/PythonHome/Lib/encodings/iso8859_2.py new file mode 100644 index 0000000000..38e91d8e17 --- /dev/null +++ b/PythonHome/Lib/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 -> + u'\x81' # 0x81 -> + u'\x82' # 0x82 -> + u'\x83' # 0x83 -> + u'\x84' # 0x84 -> + u'\x85' # 0x85 -> + u'\x86' # 0x86 -> + u'\x87' # 0x87 -> + u'\x88' # 0x88 -> + u'\x89' # 0x89 -> + u'\x8a' # 0x8A -> + u'\x8b' # 0x8B -> + u'\x8c' # 0x8C -> + u'\x8d' # 0x8D -> + u'\x8e' # 0x8E -> + u'\x8f' # 0x8F -> + u'\x90' # 0x90 -> + u'\x91' # 0x91 -> + u'\x92' # 0x92 -> + u'\x93' # 0x93 -> + u'\x94' # 0x94 -> + u'\x95' # 0x95 -> + u'\x96' # 0x96 -> + u'\x97' # 0x97 -> + u'\x98' # 0x98 -> + u'\x99' # 0x99 -> + u'\x9a' # 0x9A -> + u'\x9b' # 0x9B -> + u'\x9c' # 0x9C -> + u'\x9d' # 0x9D -> + u'\x9e' # 0x9E -> + u'\x9f' # 0x9F -> + 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/PythonHome/Lib/encodings/iso8859_2.pyc b/PythonHome/Lib/encodings/iso8859_2.pyc deleted file mode 100644 index 42b7edc2e41e3357e2001a75ff3ed65d763ba076..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2733 zcmc&$>sM4&6hHH17(sj&Mm6?gdI&{XSY`-5q6FyO&OUqp&hPAv=g;Ecjh4NU z7@7Nc;BO5K<0c4&kXDc`qPR)IMOs1e5Yt#wSXu~Noznj08asug#d#X zX(U{N33P!7HT9aE=~Sq$Q`Y5}sp_EyIg`;+9ih6kqQ*j+k*==ZurXQ{>QGavE}NC7 zod?tnE43I;2!slO18@S<0f-mU2Hj0i_Yf%(M)*xXe%;iym>I)44lj&4TwV#nB&5ql z_Q9{4m~N8wK*}yyZ*;bc$P9BSti~Ysq@0P`;ff`p0t!)6ZcnK8E_dV=o0fMt_Mj(!mSHZ0JH&du_V-m zDM$#ugy2a9AnrG2+c_dO7jqaPF#{l?(UhE2qfs*`CdstYoq(x?HVLzI&Jx<9AW5)? z6v8m@48Oa`W3B+DJ{8l|q?$72#5RGT9)nf!$rse99b~}YVO|TX4qt#c zKp78G23~b(B#dqwH4sE(DYbiP5B)xdPh!kcxA6lsh&nX5W zd~TN$hAJR+9REu+@zR#(y!&1EV!2h&=KsMGFWJTtxpNPe5*8{a+r?o-uC0Ob&oD~M z!1Q2zMD$kY90P)QH4#%+U&I@=c?e|-bRxLq+^Lh6&=$`P=}`(p zEFGbvbc~MEb9929r<3%8H84BE z`{?jfzGZRa9?!SxnZY`nM{Q_3!QD)JH jFFNcdyQgmUz+MAe9P~tQX`s|w>Miq>`3g(?cZv5e-U@E| diff --git a/PythonHome/Lib/encodings/iso8859_3.py b/PythonHome/Lib/encodings/iso8859_3.py new file mode 100644 index 0000000000..23daafdbb1 --- /dev/null +++ b/PythonHome/Lib/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 -> + u'\x81' # 0x81 -> + u'\x82' # 0x82 -> + u'\x83' # 0x83 -> + u'\x84' # 0x84 -> + u'\x85' # 0x85 -> + u'\x86' # 0x86 -> + u'\x87' # 0x87 -> + u'\x88' # 0x88 -> + u'\x89' # 0x89 -> + u'\x8a' # 0x8A -> + u'\x8b' # 0x8B -> + u'\x8c' # 0x8C -> + u'\x8d' # 0x8D -> + u'\x8e' # 0x8E -> + u'\x8f' # 0x8F -> + u'\x90' # 0x90 -> + u'\x91' # 0x91 -> + u'\x92' # 0x92 -> + u'\x93' # 0x93 -> + u'\x94' # 0x94 -> + u'\x95' # 0x95 -> + u'\x96' # 0x96 -> + u'\x97' # 0x97 -> + u'\x98' # 0x98 -> + u'\x99' # 0x99 -> + u'\x9a' # 0x9A -> + u'\x9b' # 0x9B -> + u'\x9c' # 0x9C -> + u'\x9d' # 0x9D -> + u'\x9e' # 0x9E -> + u'\x9f' # 0x9F -> + 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/PythonHome/Lib/encodings/iso8859_3.pyc b/PythonHome/Lib/encodings/iso8859_3.pyc deleted file mode 100644 index 43fd69a31820ed3deef0d718ab271690d8534d91..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2740 zcmc&$X$Dc*sYt4H? zQ8M>&!2cQ;+AK^GAz_$pM6#2(jf6pP5ZOjL>?8)Vlk^hOL&)y1ok%WjaBzb=XK)ZH zj~kra;K>=BM9L?!o!eX_1`fPAn~O*VS(}^N3Uf9$k&18;&LdJW346E$@Z=#q5TF+$ z4FyUtfex7bjoo^CD(SCl7gaH;%c{RYOsAD(o4+n4$x*+erK+pfZ-`X++vKFIin=WM zV`?hlFKgJ`*jOLj9;&Pl?ZihaaVoE>Xxi0O=I>JUc6=j>PAbyf6<)7$3qC>J1)Fl$ zIY8~8sl|BwFv$=&0LL-yg?J%tknIFz2N6O6gkN{#LcAssfd z7yj%-x046?jY94TF�(|^VneNni z9I~pWR4o8T!Y8d1q>7duN^48ji`J5Z5wI}d;?NYJOU$3x?j#WbUtN#_pbdy~6&Dw# zARzbxf+ys`bh|N|&JnS>m;(rj?tv*1Ns0+M64AYUkw{6Maaamy6EI6_FD@+!k^t|J zd>9(;;kFk#^c5h~C!?yIkdwL?-^vkGqoC!V9F11N(xegG9*J1gK?eLC=Cz=;_yWWM z$~cfRaI1Zx0J;q-FcF?Dhg?9yaR>#Bj?=@!mh&T~B*nOu^wRkvQkdaCX6w=&jB=1_beFLb@u8iDp%Sx|!o4vaA*##1l1n2xSXo!ntIfsg)L&md*|7;e)|* zTM&XEi_(7*0v1=SZ*w8!lE!1ILwyZQ=4~>YBD6y+z;LbLLOHWC^fniAT5@A8hX$xa zv+`gm=^=Tc08%2TCRLw|rFbc_wiWO$2}lP4(Gc)dZucm4q-mQB(Lj&X)$Vn$)R3FRmTz<0 z3gPSK-_Aaylg;jMy4-o5d~ZQvQE|z#tA_wM?-LD<7+~w>Ge07 zckK?p+49!gkv(E-RFY$D?MlZx@kBC}epl7>&iA_B@BZM!y&rx23EfBc(*v}J_R>%3 zXS9#@(*Zh2hv-3ih#sa#=;!n(Jw}hy6Z8vulAfZc=`cM*&(aY(O2_CpoiM(+d76Gj zC;#~UH)E1c(euW|%$PA|%+P62Wv#>xJrM;2X3%^ zY(F~yBI`8}z~zo?oj#Ax>2sDkN?rLS?pwt97lw;>V*mgE diff --git a/PythonHome/Lib/encodings/iso8859_4.py b/PythonHome/Lib/encodings/iso8859_4.py new file mode 100644 index 0000000000..c8e03b566a --- /dev/null +++ b/PythonHome/Lib/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 -> + u'\x81' # 0x81 -> + u'\x82' # 0x82 -> + u'\x83' # 0x83 -> + u'\x84' # 0x84 -> + u'\x85' # 0x85 -> + u'\x86' # 0x86 -> + u'\x87' # 0x87 -> + u'\x88' # 0x88 -> + u'\x89' # 0x89 -> + u'\x8a' # 0x8A -> + u'\x8b' # 0x8B -> + u'\x8c' # 0x8C -> + u'\x8d' # 0x8D -> + u'\x8e' # 0x8E -> + u'\x8f' # 0x8F -> + u'\x90' # 0x90 -> + u'\x91' # 0x91 -> + u'\x92' # 0x92 -> + u'\x93' # 0x93 -> + u'\x94' # 0x94 -> + u'\x95' # 0x95 -> + u'\x96' # 0x96 -> + u'\x97' # 0x97 -> + u'\x98' # 0x98 -> + u'\x99' # 0x99 -> + u'\x9a' # 0x9A -> + u'\x9b' # 0x9B -> + u'\x9c' # 0x9C -> + u'\x9d' # 0x9D -> + u'\x9e' # 0x9E -> + u'\x9f' # 0x9F -> + 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/PythonHome/Lib/encodings/iso8859_4.pyc b/PythonHome/Lib/encodings/iso8859_4.pyc deleted file mode 100644 index 162ff0dbd25d5057d0bc2a12e82d0d37cf3a9715..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2733 zcmc&$>sM4&6hHH17(sm37}eN|=>hb>(lS%<5v3#Dq0osMFLUp}rFqc3myEIk2Q&rD zCl9fFrl3o0l_@K&59gfwi9e@5!1g{D=AyM0>4zFPn|;onv(MhY^E-Rv`Li^5qiJU> zNv1y@_`42NF1b#C~lH=kvJ$GqPj@Co1{SZl3qgcgzSjBiQ*Fmk1+TP1`kn+ zguyEefr7zHlwzW~h0RA&;2>DA`G_)a#^x8cl7h`olv13;i-eQ>C7 zT>#V#E43I;7=#Le18@S2$WQI8(R+Er>M(#-1;ff`p0tyLJZb_^5E? zMI5TG=X4_iMk0h!4q8?77Okau#*5KhfDy2;cL`|bp-ar4xE>@C3Af&r0-z0uizT7n zoq~kmO9-A+1mb>Uww)tl(=kU75;FiIk;uv!HIXobVv@-zooSd#Xp=BY=PaSk36cbR zNHGip&+xlTJmw-$>a$5*&8S&ZPHz+l>Pc7?p8}1Rz|^J@ydH%()IkRP9p>e*>hJ}K z1C;R~W#CnZVi9y3)j$xDt$)cRar`gQ#7kQ^R}(XJRn9c&8r01K50PcH_(i-?n}<-gKqrDr&Ye1G32pA&kRBlz zBDcFjkW^XuPeQ=riuG+eghJAIO?9}w4ut)h?4}6q5DPFoD|k@e86A3?4>_&)v6e#v zG@)4qu$1IUQ7nR#h?@Acu&Nk1oi3o2HBLzpB-WgQV3%+G-etRL>EgnmXTXKQ0JLT; z>=HL9jR>0IiZW33q z%kL_IAHVqN>_$4d+#avbUlb?~&MPUMU$$W3qQy&=E_>+V(DFyhAARic@QNp%eCp|E zDk9H5_xuZ$Rn;%P^zth;D_?zW)#}&ZSo7xEx7Mw%t=q71)8@D9-+6b-*66l|_oP_k z`yVuI-x2??`J;~$JLQ(7qNZBgwDwQZnQX4(Q{6B-Kil(i3!yo}}N?ALuE1n)mWa zYlxob{8Ge+Xvo2Z(tUs)N z-pzX09+qdltdH&GSNQ-Aiu;9S$)<3zrl{N<7|ixvk~iOc7lzulh(L( ziJjs-> 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 -> + u'\x81' # 0x81 -> + u'\x82' # 0x82 -> + u'\x83' # 0x83 -> + u'\x84' # 0x84 -> + u'\x85' # 0x85 -> + u'\x86' # 0x86 -> + u'\x87' # 0x87 -> + u'\x88' # 0x88 -> + u'\x89' # 0x89 -> + u'\x8a' # 0x8A -> + u'\x8b' # 0x8B -> + u'\x8c' # 0x8C -> + u'\x8d' # 0x8D -> + u'\x8e' # 0x8E -> + u'\x8f' # 0x8F -> + u'\x90' # 0x90 -> + u'\x91' # 0x91 -> + u'\x92' # 0x92 -> + u'\x93' # 0x93 -> + u'\x94' # 0x94 -> + u'\x95' # 0x95 -> + u'\x96' # 0x96 -> + u'\x97' # 0x97 -> + u'\x98' # 0x98 -> + u'\x99' # 0x99 -> + u'\x9a' # 0x9A -> + u'\x9b' # 0x9B -> + u'\x9c' # 0x9C -> + u'\x9d' # 0x9D -> + u'\x9e' # 0x9E -> + u'\x9f' # 0x9F -> + 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/PythonHome/Lib/encodings/iso8859_5.pyc b/PythonHome/Lib/encodings/iso8859_5.pyc deleted file mode 100644 index 7c5ab671305e5235d52b8506f9f4f415917bfd83..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2734 zcmc&$c~=}o5br%%76`eOh`RA&JpeB>(HKd{AsPtIq9llJhMid$+yiF@BN|O$NeJW) zS3(HHGhXpF@%Fv`1l3=`uiyuWRXwm1(DyL;Ll?TJ?%J-d`t`4?@cmg5zTC1WmSD3V zAO5YyVO>F?G1iLG!!$2Tc~~ndKBjwEmzO0`_p<@Ua*XY6^)f9W4L)fI<_$ik6-a|$ z8bW!4pJ|0m_exuUCDB1RZwoN3XwDXtw&J`k$g~ogv=%UJ32O~W2k0rpau{HkB8^2$ zDS<8&k)~d|GnS%cd3Y)Pm58H>o zUS@k)&W9;`aJ|vpE+ez-CAgZv+|z1z+zD4MNfl9u+iH7CcXrVUmYzz=6pT!Fk1gZS zO*3m+Q8Y3sta8+<+IAT2ZF63%wmgi8g|kaSQ$#K)f9AQ7L=@UOF9k#!5tmC+ou7h2 z;41{4Qh?%mV|JVqVzV(v2@*SmA|B7EX+0jd!*Y_&YCS2ODr8eAOZP0PEeeu?dsrb3 zi_Qpoi+%QTRO&McQ%~y|TTN}12$~68m7hF~R^rs55xyRcxzr&B{2k^sxa#r+iG!5! z5oPdIm&Kyww$VVrWVRA=g$O4hR46)04;Nd>kED@NQ*P3W=SxUYhSx%?6w^5+D5TGA zYRb|jq^{$Ci6&jzvN`WT&q6G>NZR~ASkfgsSQ2*@V5v}{a z#z#VL)tqBQkgg_Xo4T5AF%7Jnc^(qWHq#gBMjakv*+QL3F1dH=rX{t-b0d0`;gGq_ z3qjFU?LP^DiYwK(*%0zc(>2x6dMyg)H91WY+aVQTd{+3N{Bt_?wg7Qj3sNn|254im z3Q;M^v4U8XDA8!s)1s|Kjfi@3==g`S|N z7=MEDr>BqTN@2QC1 zd*A&JR900#_|U_TJX-VE;9{t=qOgQ~&I9I~p2yHa)MznqPRa zW!LW3m)c%_CB8>(PiT6wqtobmHI>d}yI(UcyXW=2Z}h(T*1osj+0PH~KHkrBe1IS1 zhxi~r%!l|eKf;glWBfQj!B6s2{4^ioqkN2y^9g>2pXHPM9G~Ln`81#57oZRNAqN9+ z5Dvj09EKqnh9hv4UxMRs0#3pyI1M8(3S%%16L1F3!X%u7DL4<)FasChU3d@PhY#RG z_y{h-$M6Y!3ZKE}a0$MEFX1cr8oq&V;XC*qF2fc00e*y^;Ai*+eudxQcX2@UiGGn2 z1LB}KBnHJ{F(ih?5ph%;6UW7gKL*CdDREkih*2>n#>IpLMCrPa zqSWWKYy$flbp?kPE*ppl4kf6iC{)dCs@-${UbOcZDa~mZxOxp|7Jd1$#cpt#>P8># awW!BoQ}maG%KT;ia$k9%urzp;`Tqi}3UcZI diff --git a/PythonHome/Lib/encodings/iso8859_6.py b/PythonHome/Lib/encodings/iso8859_6.py new file mode 100644 index 0000000000..16c34a3f61 --- /dev/null +++ b/PythonHome/Lib/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 -> + u'\x81' # 0x81 -> + u'\x82' # 0x82 -> + u'\x83' # 0x83 -> + u'\x84' # 0x84 -> + u'\x85' # 0x85 -> + u'\x86' # 0x86 -> + u'\x87' # 0x87 -> + u'\x88' # 0x88 -> + u'\x89' # 0x89 -> + u'\x8a' # 0x8A -> + u'\x8b' # 0x8B -> + u'\x8c' # 0x8C -> + u'\x8d' # 0x8D -> + u'\x8e' # 0x8E -> + u'\x8f' # 0x8F -> + u'\x90' # 0x90 -> + u'\x91' # 0x91 -> + u'\x92' # 0x92 -> + u'\x93' # 0x93 -> + u'\x94' # 0x94 -> + u'\x95' # 0x95 -> + u'\x96' # 0x96 -> + u'\x97' # 0x97 -> + u'\x98' # 0x98 -> + u'\x99' # 0x99 -> + u'\x9a' # 0x9A -> + u'\x9b' # 0x9B -> + u'\x9c' # 0x9C -> + u'\x9d' # 0x9D -> + u'\x9e' # 0x9E -> + u'\x9f' # 0x9F -> + 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/PythonHome/Lib/encodings/iso8859_6.pyc b/PythonHome/Lib/encodings/iso8859_6.pyc deleted file mode 100644 index 6cf0f040353aa34d8c9aa3c49bcda9054cf44abe..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2778 zcmc&$`Cl7F6rar|Ap|JBH5GO1MLYnnBGpbx=V(sE0$C0=vcEh+pY|oMbp-(X(&0nR8X3G zH}v)Oq_(8ndeYnQl{V~J+FSd#_ctr!79GJAIvQy$PqfD4)|afnCU`) z6zEKF9Doy;PJ+J>Hpn4@vP{%;65*#&e4W~sPIVk(3q$M1>1EJSLPjOB3%(&jL!=@@ z$P&z_g5|<9hc1Fy9bzwN<*etfm=YqOkfqvC-t<=C4vv}6i4d$}d5j7_OxrHmP7;(v zbWRgUt%F;wp~0#ZXV8Zcu<%w1XzI`;#!sZn2}H%Eb3y>L0dX-U#JM4;2)>HosWs4D zs?VNrL~O?ABtk-C&}Fkltzc%eG%f~(k};Ntp^7>cqYU;E(t;qVu!ht^b8wGns9vT^ zLFg&!wplQXRLgG?2--T#ipQtXau|9vg4<(|fI7&4Kf}BVW&^$eaey*1QU-2yBArCD zDGNFxq7{&rxf}{0g<=)MR8k=|=_FDj zMe%B3R&j7RlR#VAgOnmjYy}CyOW*eVX)kNp;=rJ0z=1&nv}R3=ixU*vdMOom6h*41 zm@A1?6l|;FT~d(_Dx#s{sa)z&Ql#my3En`Br1r#W7&^#JBGpP!sUAL2@fn*&I!Pfp z9EsM%YU6eF4T~BVFIl>5`HGcST$xyPRnyhiT&t|U?)n>Uys0^P^DVdD*3#N``yF@Q zb@!U~dpg$Md*8bI*FVs?p{sl2rp;R(?0M+nt-YyjeUGT={zo4h*uEq4_}~*yW_M~s zx?$#qN37AO@`Yll{Iu=Rv1i7gop|o~T`#=2o9$tH**;cblWadbzz(uQ>@YjRj}~cAJImhv?blztFFWUpvjslIre}}; zLFQ+CB|i%ye~-V^r%0J_u^Dp=`|B`>jzvkcYZ~1rpd;SAI&oA&F z`A__3--0K&d)&S5KDXjdy8GP&?m_pEd)PhV9(AYOWA1VHgnQCG<({6m=PCt`_kBHSc5MQR(P7fJXJ<_e+E diff --git a/PythonHome/Lib/encodings/iso8859_7.py b/PythonHome/Lib/encodings/iso8859_7.py new file mode 100644 index 0000000000..a560023a08 --- /dev/null +++ b/PythonHome/Lib/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 -> + u'\x81' # 0x81 -> + u'\x82' # 0x82 -> + u'\x83' # 0x83 -> + u'\x84' # 0x84 -> + u'\x85' # 0x85 -> + u'\x86' # 0x86 -> + u'\x87' # 0x87 -> + u'\x88' # 0x88 -> + u'\x89' # 0x89 -> + u'\x8a' # 0x8A -> + u'\x8b' # 0x8B -> + u'\x8c' # 0x8C -> + u'\x8d' # 0x8D -> + u'\x8e' # 0x8E -> + u'\x8f' # 0x8F -> + u'\x90' # 0x90 -> + u'\x91' # 0x91 -> + u'\x92' # 0x92 -> + u'\x93' # 0x93 -> + u'\x94' # 0x94 -> + u'\x95' # 0x95 -> + u'\x96' # 0x96 -> + u'\x97' # 0x97 -> + u'\x98' # 0x98 -> + u'\x99' # 0x99 -> + u'\x9a' # 0x9A -> + u'\x9b' # 0x9B -> + u'\x9c' # 0x9C -> + u'\x9d' # 0x9D -> + u'\x9e' # 0x9E -> + u'\x9f' # 0x9F -> + 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/PythonHome/Lib/encodings/iso8859_7.pyc b/PythonHome/Lib/encodings/iso8859_7.pyc deleted file mode 100644 index f9be977965bd580d749af995ef2eb660a477f50a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2741 zcmc&$X4DRL3U__%576=e> z-*3Xf3u3knZY ziiE-|6oG=m%amfKx`ocil4u}U(D|4$WkTl{x{`v<&y-TyG#4>tDr*i1186D0^5|fY zJdH)BQ2-q{g&Vre_G~6x+b-*J!c_Hey`0NwnYM6kR#6jS&B!iXxL{GdI^3paR9!Yz zC7jf=>2P`dvWAAb=&D#%U2F|~rHZDC>dMBojpgADn%Pb#5@e(@*Hsw|YPazdHGO!g zFkJxDjglJjCybMdjw5ga(_Zu!!^X9n(b~hLScKp={q%KH*Aixe_B6aWYDqi`CzG)b z7u$%xZf3e!-h&~#P#$%T3(pL5DoPU=ds@!LZFhx8ED?pcDYvFn`xM<^sHvm~LCfSi zP2q>C>sj51ppuEnD8p4{%WAE)Wx|TlQh*V$uulnSrjSXBpSd0+5Q&c76#}A-hzpTe z-W`HO;7bIaRD{$0`fM8~#KwJ&5F};*r+7Rgr`34e42n%Ut8}JtE0Ip3D4n~+YEqCS zJj04{7<7lG3C?>fuNp1srVFVG#j@zjqvp-%%Ki3;O{WcL#e|T zBo0!>LzKZ+9g0QBY*fREiD(7n5)n>7D3N!99uBsGA4x4Er<|ZCkC%|52=9beDxrHy zaS}FH$|*w?kUEC{C7P79857q1u6wauE@<=rU`a`~u_W%?gQY};%87Pz7>R3har`rk z(sWck7#|6}ITMBvK}t=`)Kxj%q-$6=3p^y2)zB9yqc#t*Y~h*-E;%`M!V;^=VHQ7xO+aVQTd{+3Nyc28eZ9d|(;-^}U z4ba496`)d*XGO6HQ6g&6)1st+NPp6*dtB7Yd&rb;wEzy zyZo*a{PByQ&H5gM5f@;lq3@-^RD|9egL>#dq^Pd@tX}_wxh%AV0(p^CSEyKgN&q6Jy;6 z#<~yklVd$2V?7u6DSn!t;b(up#?SE)e*TYJH^;j7@{9Zuzs#>dFZ4k_AB6!Jgdu(% zhWQQH2HRl=?1Wvg8}`6n*a!RJ033uva2SrjQ8)(2;RJk(mf$3O2j9afI1OjuEc^iH zUy2SKuf38Lq-8`~ttiHMkDH!40?xx2$e!lhtG8tzN6o>bEvq1Jy0X)KZGwH&A*9 nbtWwUqSG$6d+QPpo;9e|VQ=(?0wHh6TjnYA6;JcuX5PO5 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 -> + u'\x81' # 0x81 -> + u'\x82' # 0x82 -> + u'\x83' # 0x83 -> + u'\x84' # 0x84 -> + u'\x85' # 0x85 -> + u'\x86' # 0x86 -> + u'\x87' # 0x87 -> + u'\x88' # 0x88 -> + u'\x89' # 0x89 -> + u'\x8a' # 0x8A -> + u'\x8b' # 0x8B -> + u'\x8c' # 0x8C -> + u'\x8d' # 0x8D -> + u'\x8e' # 0x8E -> + u'\x8f' # 0x8F -> + u'\x90' # 0x90 -> + u'\x91' # 0x91 -> + u'\x92' # 0x92 -> + u'\x93' # 0x93 -> + u'\x94' # 0x94 -> + u'\x95' # 0x95 -> + u'\x96' # 0x96 -> + u'\x97' # 0x97 -> + u'\x98' # 0x98 -> + u'\x99' # 0x99 -> + u'\x9a' # 0x9A -> + u'\x9b' # 0x9B -> + u'\x9c' # 0x9C -> + u'\x9d' # 0x9D -> + u'\x9e' # 0x9E -> + u'\x9f' # 0x9F -> + 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/PythonHome/Lib/encodings/iso8859_8.pyc b/PythonHome/Lib/encodings/iso8859_8.pyc deleted file mode 100644 index 13480516f3b55fcf484cef83831439d83f60609a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2772 zcmc&$dsiDp6rW_15CW9GH5E1WMSK9hs;SmWp%2lL;s&LSXu4!Ku$Y&-gNRm(f^Y4+ zrSI0hXnjA69<`ox`yu9kzJP!D0qVW8Bn#*{*q)F`mu|24Dr4~KGNE!Sz4MKR-|1k7R`Kbq_v4<3;VzCt~Q?W>|kvA-j8+s&T z6>^dK_B9rnbZ;dZmfFhFD|g=Fa-apvn7aMVgE>7Ka)`A@d48aqh=WrRg%D zUYuzmeI8*jAVtWi73I(1N1t#%rsBan3@k;D@`xLjx*NpVcYQQ zW!%d~6b#ve^Ko~%^vve-a5jyx=d@zVaaT@B5m88SttV?Zt7r$?$Yx{+X1+MUr5}c6 z6)Zc7N+vtI4yDHKjb=}G$%@@wh7qxFR!L~8$Rx$jJl7J4N=s*ifM_G)a!QIbLr@8P zmB3Rgu)A8H9pi-9l+RIuga@%prSe+NNTqm44sr#3Ad5qlbSg#Z?j@x;K~ixItHfs0 z9szH)!WW{@mQPzo&d75uyG|l#rEyk1Wg0EUp+h6QJvwu#Lk##U%*$}rj0>%xhUU=(*!1q$tAa(5lt6PYrg`=6Wq_ z8xm62@IOS84sAindcZRq%e9g={|}aQ$PSjoomp6_l&IWj=Z2BEwiMgn!>G`h-nLDCb{IEsT-D*=8lc%5ymECo8f|L zX!?KR0wq_u>bjs=iou?kWu z8DSNPC{ZHL>1t6{v1vG!KpSFiN|7Ws-GtzzZ)^6nleH{)U|2Koz_1}&(^LRC)rQYWxJ` zXJDM@TbO0=E(9}ZoTdHJL;o%-gWmq z4UJ9r-go~453YFV;n>PY9$od=>c^Ycw6v~Ww|>JDZBIV6u|2-2<7qX~`OLFjo3|vN z>wf-))K;x0ts9x%KC}PDY%X6YzGT^a;N`(rhF*Pb+v{&^hhcaV-hvSrg}31yco*J- z_u&Kh5I%yBVF&DlU9cPWz+Tt~`{4kL!9h3#hv5hug=26WPQc0Ef4c;y;53|pvv3Z^ z;XGWpJO-b^=kNu5317k2@C|$m-@*6r16+g&_z`}(JOMw$FYqf|!o~mUcXD`4>=L`h z9Aw2_TR(Hw@&Q4?2ocTc(;#E%R dU9I3+n<^oePG2|}_Jw_QN}a#5HgJXc{sa#ynhpQ} diff --git a/PythonHome/Lib/encodings/iso8859_9.py b/PythonHome/Lib/encodings/iso8859_9.py new file mode 100644 index 0000000000..b8029382c0 --- /dev/null +++ b/PythonHome/Lib/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 -> + u'\x81' # 0x81 -> + u'\x82' # 0x82 -> + u'\x83' # 0x83 -> + u'\x84' # 0x84 -> + u'\x85' # 0x85 -> + u'\x86' # 0x86 -> + u'\x87' # 0x87 -> + u'\x88' # 0x88 -> + u'\x89' # 0x89 -> + u'\x8a' # 0x8A -> + u'\x8b' # 0x8B -> + u'\x8c' # 0x8C -> + u'\x8d' # 0x8D -> + u'\x8e' # 0x8E -> + u'\x8f' # 0x8F -> + u'\x90' # 0x90 -> + u'\x91' # 0x91 -> + u'\x92' # 0x92 -> + u'\x93' # 0x93 -> + u'\x94' # 0x94 -> + u'\x95' # 0x95 -> + u'\x96' # 0x96 -> + u'\x97' # 0x97 -> + u'\x98' # 0x98 -> + u'\x99' # 0x99 -> + u'\x9a' # 0x9A -> + u'\x9b' # 0x9B -> + u'\x9c' # 0x9C -> + u'\x9d' # 0x9D -> + u'\x9e' # 0x9E -> + u'\x9f' # 0x9F -> + 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/PythonHome/Lib/encodings/iso8859_9.pyc b/PythonHome/Lib/encodings/iso8859_9.pyc deleted file mode 100644 index 6792ad8c9738e2e5aaa18cd92b08694e28b00d19..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2733 zcmc&$`Bxl85bix$76`eOh`RC0dW3jIL1QG4Lo^VajV3{KGwjU5;2toI)e0=n`l7@AQ zgeF7-NsrLHBIOYcr1*sH5v^X4B;7B1gy-a z7rIy40wPHc!Z}+&Xa$3|ptKd{Y(b$F@uVS7Xk$b}NID=-A<<0%hB?w$w3riUB@wCb zv|F;7NOg;9stH>+BeiNslmfX48>rwR7t0 zYw8xnX4J$M@mFTBm|jt~cA0=uqi82dI};syLnq z37rBb;3TF!6fdPsx>vC76G|+~@Y_NDx@{T>JHc}vej3%hJb{EQM5{-vpkJ@By`tMk zDSK$W&fP8}v+OannxNd%YFpe1S1w7FP>9=VQ%ZMs@d=imO3DB z_IOfiG6_>p>ls^3&65b430jq(9E~Q@)S(f*9!)l<_fT=v9}* zqU^TLAR%P75^{wJCm~cgI!O-~Tgi{4kx^4_(xd0gNO6Wkp;Zd`oFWp^=X^C~=@L@c z@xMfqFKyhQ_n>DamUAU-{vRy)k{v9WJ0q}ExKO#-jt(PpZ8D92hEW+yrYGYgqc>^L zF(JrT6SGZSO)oJGs+&0;GRvy?i+rOF52>)SvGxup4;s(HPVg!7u5rbz9O3otz^dQkpBoqAhFJPA#YF~>y%VJ zQ8uZXOfoA=k$bGdZ%JV~D2#@}xAM4GX){fmb&7_1q-}OirK!c-6rOxf&{If1LHX0( z#dPv`ef~f&FO(lHC@dONJa*jp2@@wxe(LFxDbJKX``q)9sV}_v(#x+*i@y5W>u*di zoAKsbZ@=^I%=g|eulV4@Ss%^*xN=Ta_1t;$7kpCl>1PXT>lW32uEZ99@#T`G%No9F z{Q8^taB;66qxIWVI+Jbt&a~|I?>m0z{PCw1KmW24x?mNohHmJAHLw=e!Ft#L z8(|Y{hApraw!yEk9d^J@*af>`5A20~upbVdVK@Ru;TRl;6L1nv!D%=H zXW<;2hYN5KF2QBE0$1T0T!$NQ6K=t6xC3|L9^8lD;SYF#UAPKYV>kBT8eEI(a6N9o zjkpOn;}+bC+xmNPJMO@pxC?jV9^8xja6cZvgLtU_^21*2!^3z4kK!>rjwkRWp2E|3 z2G8O-JdYRfB3|n6!z*|dui +# + +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/PythonHome/Lib/encodings/johab.pyc b/PythonHome/Lib/encodings/johab.pyc deleted file mode 100644 index fbd1d8784c909c3df3d1c3f587aa3225bcd01ae9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1673 zcmcgs&2G~`5FY=;`Kgm21gL<-fm2R>0)#38hf2`H=1^fpGKqH+9Ac-kw?a9m&(xRU zF?ay@X52VY3x`}{d)Kowv*VfB@3Z&2+qt{?HcIIJ^6@^$D1TwncpO?1MYZfu9Rh`Cjp zJEUO<#N$LfLYjG`JGDnh8ivZFD;_=Z2y2fX=`Js#KG!rF^iW^=2iK)-KwPZ8Po^Rb zSK1_XKOERTV3e;gp;lCHTv~WiIs~60pVVjoD-Af1ZDESze3F?swjEhyD}A%%B|9V> z-v*FO&a#M5L9C*{LL!x?kj}=R)9F}T(|lfzCDF6%wc^Y|jFOKmaN3T23gIG83X_@K zPL`h}eDSyxF1;=#a_jUx=#|TpNF4W|jGEZ+1f%2_f%`C@k5c0i^Wl?twwDigYh(*E z$&{IBbHq&A_%a`6)fva`GPx>Jd(2E2kgs={)ZpktH)Q=eCJR1*zIeb=k1WUy4G8CN zWiY-$fHOD@{DQo;NxH@0-%xWj;Ce4D1BiK`@FvCBR}6c>MY_XjMT6p@x}roOy(;C@ zaB?`cJ;hIHo_tMMB-AP`e|^X-yU1rN;mPjfib1Lv8H(K$_u~+d+Y@Y<8{{(w$%^$G zEK3GGfq{V&;tu2~j$Jx!&rqi_*P9&BImrWD-c_6y%P~1OB-|~rl z+3t8uaVhG*PWQZ%qV4njNc&`vcKpj+AygWr_z!bXx46;os^8yx?tIC7Jat01@4ocg L&I^ynTikyEG*~!S diff --git a/PythonHome/Lib/encodings/koi8_r.py b/PythonHome/Lib/encodings/koi8_r.py new file mode 100644 index 0000000000..f9eb82c0db --- /dev/null +++ b/PythonHome/Lib/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/PythonHome/Lib/encodings/koi8_r.pyc b/PythonHome/Lib/encodings/koi8_r.pyc deleted file mode 100644 index dfed09e06e7df1d22840d2ee40bfa72acf76a679..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2755 zcmc&$33n7l5biy*SrTs0VAREn^&s&U6%h!B5wgTt=9=tVie^_)I_5O zm|kuO5N=dNB&ewG#Xr#V7wRwg1F))x>;U>ec+cl-rqf-uU0wCn*Hs(%vpRZl^}1x5 zU3~)he?Gp&5gateT5$9+&Cjwv)`F7&(|v5cpJi|!WW9{_Ft)bE&$N(K1f(KdRs@(< zAr(QXh?EsUrd2ZCFLfc7K?BjUF2uBPW4f@^Rh4yNrd89TrGjbWSxZD3KuZzUgAPW? z(`0-C1(3xd*4%A%6!Ni#4%JlCmTtzH)Xq*L-yUlyXnH!fpX)r(oHJXgTe)WCtk_1w>Y#0DGE>*tT^EfS zSMW(#Av{(ZFGK1_$wKldhJ%i-BXkngUi26P$GM-;JiwG>oDyJ#>Fbthq^&fq=?&uB zK;kJlSd6Xru}%2rXO^G!1TbhH$`jsp=~>YlkJ2e-A8!N_-ZS<(;PGz(@ij!GtnVhzsfT9+Gbtz%Y-tuBxVgu6xJGLGy~@XU87Q7E+a zI{y)Bgjoz+|WrY=w9x!BfaP$qEluNsEk;SF>Kkw+NOn zqVTQ-RjHyws&SA8m#EpIF2VGy{u>-ASChs}hkZAqxJXjv|3Q(`>!L`MxdBCmYLgf0 zEdV5bO~?120aPZU>JB(axJ?_gir7&`l9s8fxz(nDMY7C2V%9?XA|=x09#$xvGszz> zm0mz{c8jQp5>!NFRM(xa=&JVLpHCIE);qr(E~Tb{p_J zPuLYOPxvBE*9bPs#K|+=x=E+YHq@BU6lB%$j#cRLD8vGVpin3ux0OMQc-gL_E7$@p zvwJ2ki$q4|tMr9^Rrm?ZPuC@)kk20ohQbw*%ILVN>hTjMPMSPr>a^*1-CZ-|p4xlw zyFWJbfd?OY_>o!hM<09qiP?4aPd@eZGtWNv{0nnleCg%6ugrUO{(^-Kixw|g`dZ`b z%a%7KRy4n%Bv-z+@0Y5CZ0zU%$DDYw6$ABLPeggPO;HQ9}27U(k+0j$ZSK^%b-uYBq z5I;J-;s@swaY_6neipxo%i>q@oA}-N+S%f4b+$P@;-Wb33^-qi5vR}j(&=|Tb3PZ} zib1hm92d6WVp!}H$HZ>2N9+~*#C~x=92AGdcVb8!7DvQUQ4%}ES#d_}5+}ts;*>Zc zPRA+B$Z6_Ahg$4ft9;BB; diff --git a/PythonHome/Lib/encodings/koi8_u.py b/PythonHome/Lib/encodings/koi8_u.py new file mode 100644 index 0000000000..a9317b12b7 --- /dev/null +++ b/PythonHome/Lib/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/PythonHome/Lib/encodings/koi8_u.pyc b/PythonHome/Lib/encodings/koi8_u.pyc deleted file mode 100644 index 58af99f06499ef0aeb1f2f7fff0ba5b723f4be8d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2741 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 diff --git a/PythonHome/Lib/encodings/mac_arabic.py b/PythonHome/Lib/encodings/mac_arabic.py new file mode 100644 index 0000000000..7a7d3c5f7f --- /dev/null +++ b/PythonHome/Lib/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/PythonHome/Lib/encodings/mac_arabic.pyc b/PythonHome/Lib/encodings/mac_arabic.pyc deleted file mode 100644 index 34f77a80e16e7af8cdde204cef189226e8716a8e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 7879 zcmd^@d3aRi6~@n(4G3Y8O?D$9M1+8d2Sh|j*q0C{2pGXIcWY~{%iLhCb>F+#eY5ZTT_I}wJlg)z{$XAIm#?GUkckoIC7ARWazK@Jt`4Cx})71B+tJEVtLPsm|n z`H;iKdO?m5>kT{`eV#IA!} zFSyHUKNPzGa--m8tKB4aGvpSrb&&O98z8reZG_w=wh6LXYzt(o*fz*^L3F6yF17=5 zhuBWYonm)E?iRZTvP%#-YWIrmhTJE1KV*;CUdRJt4?-Ridl>SFAh^^X6?+V_Pb>v_ zT7z})Ls)7JCKqsv!Q<(t^NK3j~3u)+n|g@|qz2)P64ZI^-9EFjRX(5PxdF6nhi$ zmLLq(-WG(R+B;(JLf#XEq1yX`pj7)n5RGad3ZhZ%Be9PmpNM@5`IXqOMX?;6{YJ|3 zBo61d0#o};U~0b;nA-0JruGMcsr^x4YJU=#+Mflc_7{Pv{Z(LUe-oJ6-vy@j4}qzD zE-*EGi8wXqU}_l-rk3eoYFQ4ZmhE6_IS!`Q%)!)}JD6Gv2UE*+FtwHrrk3YmYONeh zt+j)xwQ(@Dwho5$;$VI;PQyhY*-)@1OCi%ki3nDwVtIO*Ay}k}Rq6!`btblEh0@Mh zJDd#bwH!N74F$_~4z}iog4KH(wkkrwBA$n>Xee0A^RZPK3YN5Ct8XanowdiQ7YIzT zy1ih5$Fa326s+^b*s2btgR>6!Kt~5t>*Qd_n+~Sd*};%L9ZapOgCUDLm|AxSLo#(R zzuYgxIWH0{e6^kq=2!g+Y+Wo^|9Q#| zW(QO2?O;gI4yM+}!7ykCQ!8*Vq-zIL>*rv|+771H-@%Z)9Zapz!H~lpOl^>ZA(cCr z+F%DmMt3l^Ar6Mb?qF)_V94(drZ&vMkmemsZMcK^RPYdn@~|K&_>Axfq?;f&_{8ui zWyQhN#yJ?Oi-W06a4-}Z2UDBmV5l_?rZ&aFP;wkht;E3)><)$~cQ8b`gP{O9 z7^2+4P=_20QSM+qTYP{qOcvw~pEN#%po~$FJ3fMZ9Lh{*Gx3304yGvFzQh%T#c5Pn zGuno^zeAYqJB4Y!bC|WehMBp0n0E8S4BIozu)V?z+dE9H{la8g7$(#HVKN;QCey)T zG940T(P3d09Uf-U5n=iq8RpHRFmH|t6Xv)uVNMD&<%BR(P6;z*Nth|C1U1&z{N<2K z1;tKL-%#Zg^$k@{QQuJIkY)r`PEp@ba< zi;#hW66U+6mmseQN|S}L0_WiNYIxkIui6H zijD+*iJ~JxU!v$p(3dDW67(gCjs$&)q9Z|HqUcD_mnfPfv`W4OdjoQ!pe!mXA?l&; zz21Y27nD9leM6P=?b+LqcLmiENk`BhDvBOTpYPz_f~cVRQ?xK>WVE~$Tj;Wa*$$oc zT(sBurOT2F>uU3h7e*7&%495&KQ&rkAFo}IUtDLg%KQbf+E^l*j9GqFqOK;t@653! zW2QyQ297Q*oicXd=*Z}ziN%F8X3yxGzcij)$hTMWbA|QG3UhPgpX0A2nT_x9XFJ&3 zXJAheUJdy`3{A9Si;w<(1$yTU?`L>FQzB&rnRrt&hi^|N;+4rtZu6CeS21_D2a+O- zoSXy8kYt7|&%`J(NGWOhxWBT7WNYlL#Bgh(^%ddeCiAe%yBK%{_J^P0`5R)@Rek{R z+WI9)e-*JrqAt-;fP>=E&;wrKoGJ17a}J!NVNOl7vH~+YKhCKLKjvo!4>Quh;fwok z#u4F1zcK<$HYVKf@-9b^jLxr)`7uN|_Yuxrq#5uZUvzkO&e#_hUBF36HU}yyYNIu= zii%{e->9jxCDquB@K}VyZ2B_qee*O$@F8h|R|CH!CnGO2*$&Rc+R8+%CRUq_R*&^_ zn5e{F|93EsI$$%5BRtBPG{p`>;9n=YEA}=83?c_HlgXGt2zDte;AuGSU`@{>zx;{B=BVX3Qb) zPFXS$i`L9a#E~x##v&uFh;QUg4Pz0x3%>YxYPzjW1M}Xu2or`#7rgxFzH$wbSk(SE z*T5Xxz3Cbb4x6{CnEOWo;hGA6r@=2Y%)?k*SXNmF{4D-JgTS^NrgZ!!lWZo|oEc@g zG%G7$Sd=8Wz?fVb7#ql>1Hw$&lv;cw$D8s(n8p)d-yLSJguiE~9k^$BVZOe!W2wK1 z{(HmR$}8~2YGQ3wozF;3UmM|qiZCJ~oQ??Z%YS?~lgy0^Vz?X>%Vc8N;n-|ofQoD3 za$Fw%bNoLZS4HBF;{bj|0@e{15>F8q5zi2qV~PKiSV6o(Tui)1tR#L(tRmhZRugX$ zYlydrONhNF74b{yZ6_`x-Xkt2J|M0j-Y2dkJ|wOpJ|flxkbG*Assren|Y0xPkZ!aU=0(;wIv+#LdLth+Bw!f^!^SPxK-- z5JwQV61|Cy#3By=HhO)CO+;T}Gr?OO-$EQkY$f^;+lZryJf7fodIN|ZL?LkpF_73v z%;Wp+q!*=k7rpuP?xt5s?;d(sCKBI8FGlZPdR6px(_29AK6(r3-A^x0Zx6lU#9pEs z_l=>M?A~Tqv<_IuRpyX(HlVTd3uHPeoSv5y`RtHUn} z5PC1sJC5GV^pxIE;#F=AqnD<4JiUP4aC(jOP9^pebBMXb&xzBB*NF<^7sM!jY&20s z6ccapz!-XCiFdd;j^4ZU#?zZXOe7`|lZh$B$9&6FdL_g(qLlbG4@{@W7B2os#ZzHjj_!IZ7rniuH%7!(0h^I=kS&+bfC+~%*xJb*1Sb- z%e+>t+q6BTUHc9lJ004&OV@7Qd-Oak|L|T%^ggmr--4t19o>IG;lM%13_f{^O8KdC=AKqDFFL={VpR(k z#uqKFuBol7KRwZqTyn zSQo4hHUzf@8-v?|O~K}1OR#l#`UYHW`j$6ux+J|my&-*TdSm*w^rrOY^p^D2^tSZ& z^zG>#={wRp(|4xtO5dHnC%r3uZ+dt7zV!X+J?XuED8U86g~3I^@?b@9aj-I26|4@{ z1eXMt2A2hw2Ui4F23G}ZgR6swgFTHa_g~Yvv2kbP>c+JgW#e`Gua0A?CC&+tXAqf0 z7LiTho=ChI(VS>Os)-t+ zmZ&4@iPMP$(Lf}LCBzxTQsPWv8F3bI9&tWU!25>AhYwL!SBZxv1_6g8UurShag#SP z!dvBgo0{n2SVi2>H^h_6Dhv<9{uv<=twlq@u<#wv7Z0)isdGua;psiX;0d2w;C!iP z`R3-+KkJPMpYBF7OdC3bcsR@I(!5Jnm#prY-LqS?>WJQ@*?0QCWlqlLlAZaTo`dgp I1aS2K1Vs*D_y7O^ diff --git a/PythonHome/Lib/encodings/mac_centeuro.py b/PythonHome/Lib/encodings/mac_centeuro.py new file mode 100644 index 0000000000..483c8212ac --- /dev/null +++ b/PythonHome/Lib/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/PythonHome/Lib/encodings/mac_centeuro.pyc b/PythonHome/Lib/encodings/mac_centeuro.pyc deleted file mode 100644 index f648c4fcf4b4a2e541456c6376b563612bbcfc4b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2802 zcmc&$Yg<%R6y9@X7;fGRqa3?AU4-seGvuOCIMNxs5j7spIRis;p)+S9%JLwn&?A+p zD5!;sl~QV1@POclIeUNVU!1?t53sfNapnN^frk$@us3V3HGA*1-u3RaaQ#){pWJ&O zERlO37yPY;k)DD{CZq*s2a%m5?jS87xQOB)olX)3*-iQh=_6!+i<8J6Zg6pfH*ate zxquto+~CU_+(a%Uij&(sBnk)k^EMBWi*hzEw-x7YULu#^qNRYyrKH8j4}g<=qz@eQ zqo?6u83vGnDbUoTb)=Gk+73|_B~4KSJH@W9Sh77(o01hNkPxMaq$D*ZqoxAwN>Wip zO_2jpHI)c#+PST%sUfr@T(ze@RJThASHZfmzN)r9)Lg$?*j3rQuX$6TJEnEuP6^Me z?CPoX`(tJ3t?@w{y?ZS}ABHfFU7vMJ#u@ii-e9L=)TM zinR-GNGtIu4r}PGpDq9<4ZLPUe(yj9m1vspY9GxOO6(Jyw z<-{W3)&)@j-~c*TadBZ30^%0E2)#F60ip^zv{Jj}66OB0OLYynxK(Knmy`=ZTFlCrUJy6ytW> zO9~nB!XW1ZEEMBaB{1=0w~O(#!hyBVUOJ|jy_LBOypF|))^Q5`KZs(gEkuz-ix3sC zgxLWv2~6bOIvD>BrmzA`%jPCxxHfk-;D|X2YpNn9_Npo?clhyqzI8JmIT(Q1JViH8CBNCKw&(+IVGYS>iq|LmS^=MyfV>b85CL|!Pd@eZ=E|yPo_+557hZhn!mxO-Wj^lyr03Jm z4u1Z{A)}w_wAUD<{l>6y-ndAQ(BsB99im6+G2<$mW;66F;}`lh{g$4j!^SOo#`xWs zH2yGV=qNpB%$oXG_9i`>y`25g)GuWxjqkJ9vscajOLQdrlQ}p>FVpMv2EAquj+=v5 z=mecK2M(J9C)iz+ot|Qc8m?MZ;aFI z1Uqi(Cr$m7sh>CX3#NY7)JKdd^URlQh@E1m8LX#GeTI#&VRnX%nfj=yf5$GeQFhMg zW#jCMF~sKB9d^w)X`Esc?7A_^Zm^r|SN0pbWn3`k=oGundf6tGj@99+#F<8hBUUV)fyzF4&&No(N6U UUG6J)m%A%m6`sN}?_J{l8|Jj23;+NC diff --git a/PythonHome/Lib/encodings/mac_croatian.py b/PythonHome/Lib/encodings/mac_croatian.py new file mode 100644 index 0000000000..f57f7b4b33 --- /dev/null +++ b/PythonHome/Lib/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/PythonHome/Lib/encodings/mac_croatian.pyc b/PythonHome/Lib/encodings/mac_croatian.pyc deleted file mode 100644 index f306bac955a703ec2b6627fd8f105d532e1e1872..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2810 zcmc&$X?qk!5biy*SrTs0V3fs+^&s&+5eXq+6qYy}Ibw8~%*-Z(d&Jp^7)2RK3>yTI zLxqSK!hOi0+^9Uy)W$D)9{msf2mIgQtfEWsRd(m}70A(*D*~g@Klrmuk>FcJU zE2ctg8h#x0q@IS8$=Es%+kn4bW_nqV52N>>KIU#0p5@Gms8tY#wA`6++!ZPzA|MG< zZcAy-F1jJ7rII29J=57`3O_W%$QrpQ8kv}Kvr(#PU8c9S7Ej5wjz$#Wa5f5bCeWz_ z0rQL}7Kygr76k&1pbM1{Z;wJE{3XIqD#K|UZae1_ZnxZy5-?^6r$iznr?o`F42wlN zt9GSuDUnU0K;7$vG#02N+{Vgrwxf~)Y{1fb1sC9{h3_|Ysh&%YwtKv~QHm2jmM8E=giI^vVl*l{56Bl7Yl%$@K zQ*PX23YqYtAV&i%RnS$HIEiDI$f=wrfOXFvJEoMqDa8wdo;wj;EGYELaICHKirvaBHG@ zwp~Mqu!)*R_Z(d2h^ov}?g@G-@FysKx(*PvJYJta5G)IohbL52PMkD(%G7DoXUx3o z?y6b$RNs5w?8uz^A9(Pghv!BgdGxWz=hf6c@#IraKlAK!&%f~EOE1rVWx=Zp>lW27 zZdkJPwZ_-qShhU2qUlX3-u%|eRjb#uyxscFyNR`Oo1$vT_6~jBd#Q9L+xfncGrK-m z|6%t>A8+{N(~ZyzpTQRBhn?^>?1zIe2t#lf4#5#P1}ES+oP<;G1Du94a2C$PPw*pL zfJ<-@uEABf4nK2i&^~7m*@x_7+#0ek!T0u=;X&RzWM8n4^Zvo%UtllKAF$8!{=>Zg z2+#M~7kPd&&+p{<9m5BC{*-;vzV`cx;a}m3eZxLzpXT|2-*)l-e4)=iRoKR@qxK+J z&;wr$?;74+_>x|1u58bd&@J+pZ^J#8f<<>Rmv#)b&w|$vg z1Kc{mt#h!sumv_1wnHAa!xyjvw!v=LQ`iZ+U;w^_eTDNQeIxtrvwv9d`N)8M1-8P` zku6cmC9;_MqncH)A5trEc;m8#h~iL&`jAA$&!lQ!{O6>tOHZjzmqG0)PK~8Ri0(Y! f>BkFvxIIU`5u2&MDpcjK@>lz+1Lc!~H<|x$Q7)ts diff --git a/PythonHome/Lib/encodings/mac_cyrillic.py b/PythonHome/Lib/encodings/mac_cyrillic.py new file mode 100644 index 0000000000..63324a14b8 --- /dev/null +++ b/PythonHome/Lib/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/PythonHome/Lib/encodings/mac_cyrillic.pyc b/PythonHome/Lib/encodings/mac_cyrillic.pyc deleted file mode 100644 index 3dd71a389221cd1c1c5d7a06f04fd2ab3928ee5c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2800 zcmc&$Yg<%R6y9@X7{I$0Mmct4x(MB`X6k@O;YeplgsAaw&KWp17dmsuD9ce0LCq`P z6$x*dWLk-pU7lxpo<6VbPdI;}A7E?kHto;9;7JZFI8)%3jvbSRZ4pZEmLegux>W{-VLd z)DmIv3PYf1@G`ZOX>MWju>>9vEZTfbEi2gk!d70i`I%Zli?$M`&R}f;aR8naV14Ld zkUWirXHoz?IE9*e&8|#36zP%;Sur&uv_|gk*3+G#NJiC^P)b(fO0S_Ole!Y>)Y6(E zo0=L*7@1V4dd-TariSS1Snay{Xx&;VR*UP#`r1gV)X>=25UFWi-&`Hqq?=u|Q=#)} zx_fJaLH!nfqNWe;7q=9#b)#k_xfa4n!x#`l0dGILjtHRaW+Z!<6bn-(Oh0|yG<3yO zXidY5BSPxAIGK!Xbg|9&>t?2#^?5LQ7wV(VcHvppoPk;eVMxi{aob&?5+VW;H|36` zX78dKvRX1BLeSIQJ*MzOGmMOp4Wp5XDZ2=zn)XJ$qrGrSwtX_92#38DZ`_6B7Xo;3Z<708%3F1Wz1<1yK@uT24A~ zPbp-=i-MdCuvAW0Rp2C!T_q>8ngG^0d+L}{_GT9@@Vo9tv`$dy|3Q>eZ6it~x(iW> zN|+Pyl)xn3Ex_^bU`n&lG;MAYhVu(&BaW1#m}zKos>RT;t`<2-j9W=xq}1A+#9D?j z6TEVg>jWpHDMd(Bsl*{7yu%Aglhyyq3#z+Sju*wyDP~qh*@Zw7^zw+wR*OtA$e8tL0UHz)n zZ#2C5R^yuJ+NQUqSo1sUTGqF=z1#lY`|%BOhoWkU&Mtl92gy`A)BT~5HG4kV^l|Se zpKku_^DVFs_QL@<2*Yp)4#N>R3di6$oPd*X3P#{GjKY^N24~!&^ zuie}agV4{1VFy0~L;M)*${qXTx|JJ&J$wZA^3zuTVc5#|^Sy8duEKZlJ^TRIU;?hgkMI-x z3^(8x_!WMG-+7L2<=c24@8{e30N=p}`4Hd9ck$i)3%^`$$ysOsesPe@Qxe^rUL{7Sv8+(o_nA=*dg%F1*Zx+q2XWv4wgo1C`!N PZ 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/PythonHome/Lib/encodings/mac_farsi.pyc b/PythonHome/Lib/encodings/mac_farsi.pyc deleted file mode 100644 index 047159c4bf66a18e722a94a088e474bd5a391634..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2714 zcmc&$>sK2^6rW_15W=f(O+`(85g!HLk6J75ib9GTENw*7CA)#eJaBgr(W+IjFYAMz zqsMd9V_UHgu%#3Vg?jwJ{1da;Z~Yhi1M0oABn#*{*nZH!3^Vs;?%eykzquFT&$7U5 z=YeQ~EPVv{TMI*&n!W3#BGJ3O_P(!bzNeM&ILTyriznbX@HDqNa5lTymcv8}IHPoYI6iqS| zIh540=}=W$U3+^=WOuY?Z&Rdkj~K0ieQQ%qbDbD%sqWaELNF=dJ)p;d9Ra5yc38U!t_31S!cY&0+xVctSF9sDljn zJIq@_>hJ}K1C$YvGVrv6(J-2gs4x*8Er(o0!f^;i^p4ZR!ItwQsb-{<6ZG2gB2pOP za%ja;yr&E%ZnIfR=?aI`G5jyl#H6jyTlcwEW7)`Q^Z#IpNw%>>?ySO6#A@Y4yEcr- zwJk9I8Afp(sBVvsh~DPBVL%X56E!qNN_T216wd+=k!AJxMa-zpLnvFYCY(!7PMxs$ zYVFvN9zhs9wiPajiX{IhE?{xR`nKdkA!tlf1IlY*vR{+k8KEa)0fuJ<56Y8YLxb}o zr)3}3a_E8vbSyuXl3`L54I?EY20ksUDmreVfNtl_$SEnD#Hv#e?DDOx7TZ-z;|YVF z0SSWvXe|>A@(l88?UIT&@+Q@iNoIK|a;_EeEs0165z!DaE4P|T18Lf$fH%-14Q*%} zY<1)&aTU9Ku2T5%@t=WSq?5}nc)Y$Me{rCsw5+^h-TDn1H*MZ>$DP5gcU9hf&%L2- z_uc=%gAY}OAAaP~$F^73JpRO!Pd)w2v(G*M!j2brzO?J*+PeCN#-`@oue7}ST5DTm zPy6d)wBwDvo%{C3-t2no?f3zyJ0UB{o?f-@om4uL?SEI(je++D-yizm!-F4v{0SXd zJVlStV|0{$M}MTJ=_z`Kj^!2>C+InPfu5)1bb?;Iap)|)L?`JKonE|7XXq@QqYHGN zUZ=lv2hDNYLv{jOv@Tmy))i~onz620v(}t-&6?lAegJRT&o_QL&Q7y4>=!o1er0Fb zId-01VB>6p{l+e`OKg%|W>f46n`SfYDw}0<>>8VA3p^C_kol?knK^8Zn4g=6%_HVf z^O$+u{K7n8erbMXer 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/PythonHome/Lib/encodings/mac_greek.pyc b/PythonHome/Lib/encodings/mac_greek.pyc deleted file mode 100644 index ae631201fbae19866fb0cadc2d2a7cb7b03eb089..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2754 zcmc&$dv_C65WjggO&`3`V%6ZQ@j>hRiC8EFD-i0YQmECi&2HL29(A*|R#77@NDvW4 z5EP_BpR|Sou-Q?chJCmI|^PAtDsq4=Y|3u@? zaFk6yF8o`KBQuGU#8?x~4kkHS!oiww;bO9b?Q*ghuHCGMv2Mn8G&z~%;R+X5c=HMu zlM1-P%@w}9!p)>YCOf&#!(wQ_pVxVqR5YXWa$Rv==Vej}ZJG+0RLYus+yGkgv2JwG zPo9Q@3n+jzPJ#L^wJn_r)U=6;7*%B@utjWdkEdD#HEBtX29jbl(yGYv?m(-Yk`+;v zr9ezcCj%8**4Ee8g*Jw(w$+B#ZxzB-xZhk`wNa?8-Bj7Iy`dt|8CTorwJ2GtZ11Y{ z`{Ot938@}DncL5!>O{#paw>q6jNT)99M~Ro8e_+`lhNA6gm92@pnB=&suGW?QQFgR z$DITs z(5ttEfM_G)T*Q~Rh9D650)ZzK;B>n_TgC~oX`h1xiR!~C5=n_kITBI*e3MK|9SPhD zq!TDg`z*ei7bF4SVTCv{bcWYi>{1uwqAnFxG_HKY1E0#jQmnyh0MQ zsY49-JIpIkYV!q&gOqU*W$M*g?-9 zFCj${&W2VfrgKVg;x;#kiHyu4wGIDEG%0C|W~_T1bFo~{Y4iVJNlCV_B<{??QlM&O zM>{`^#I@x({uxGLA*$|-kA&W`8N-Mmr6#N@vY2dC;#fTMJS3K_qaRX6EgoXo!ZqVu zvU6&O#aHvkM)WAd!DG9{1wj_2|HK6gY7wpc({@n&R~6i(u}T@bADt;`i$ zRZHOs!=8Z&!+~hc5_Iwm@?))%N+4Jre7B5-4Z24Vxm#w&` z{NDTS53GFP!G|7xq$2p}V~;Gs3gZ)+v2-+Cz7dj`+G`8?RdZQgRT!h z+Vk-zpXxo@ly+IqX;<{)`YG6__v&Z$KIqYg^g(@CAJWh3BicE$=d3=aUo^94wHs!3 zT)(PMXanZnQGH6kre8O+y>Jx1g%j`t{0P1J8Es4(hI4RU8#Hsh+PF3eUu&1lT%Vci z*ZScbI0nbzJ2(m7!zmbm5g3AD7=_c?D4c{czxqqh=Pr z$IR?0Gke<1o-nf~^-0LVK{y15;R1}oMdJ{BWqb*j;IeT5uENj8ez*dYFa^KCuW${n z!wvY|$Qp-@&x~%P2YxYf#$MxdV;@Wy2aPY_2#jkNf|NaEEVVr;9mO_BO~RsyO%CFP z#SrQ+0u?uvO8Lxx8!a92gk<#(l+L2iyoG>w+|^c(UE{)cGt~01N4m>=W$rR}xvSh$ KxWIdpx&H!obd3N2 diff --git a/PythonHome/Lib/encodings/mac_iceland.py b/PythonHome/Lib/encodings/mac_iceland.py new file mode 100644 index 0000000000..c24add2ad0 --- /dev/null +++ b/PythonHome/Lib/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/PythonHome/Lib/encodings/mac_iceland.pyc b/PythonHome/Lib/encodings/mac_iceland.pyc deleted file mode 100644 index 05d04b752593b4d1abfcfe6a7d530d9e81345d28..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2793 zcmc&$X?qk!5biy*SrWpn!HA1j)`P_RL<}SWqhX1&NFYX+$;@mrxJR6sh*6Y2Es*MfT@$lbU~pjE9!zwEvHRe2~#JtwvaG@mO`u# z9SoDF@n{7FVB!>M>9xADnMi$?Y{-hG8Ih%OcekGDjMQgUO^KvsC7~-?O3tW}PA#Ju zvZbk!q>)WWs+TToX=#criPx@Zj5REi;F%uwhxKdt#H;|GF3u<->qW^Tax8+Ah7llw0^ELd9OK8em(kkCqJ>DIk=%oA$Yy^azrRtTp=A|t1@M8XP-O**Ug zq;M;dPNF#7)5K~5KuP!(E5%{bDM4?U&zgpdri@}}X)R;PsYZdKp`cVeMKaC6twScf zOe%8;L_GK>)U#3QvIgmc#PJbv@RC=?qhvOw{- z*b|AE(4rW}!z-21N#!^RtBd87sR>wJ(-TINQa5$Xe$aC>o(+ON{|}y&Xa`SX&`o$s zRJ+`GCjupLZWfMzhf#w&)G z%Rjcpwih6Ft3j&n*c&bEV<9RmeXJxNC2GVhx@J^kOv)^l)Opuilv`p1oprZ7I3?Y< zS?p9XL!=G+2&N4OA~sI2R^(9}>=apYK{T$WOfoA9lY6X0w@M;XNQ8$(nYs0ZS`=2N zhW=pZw2a=lxHXBT%v0(Kddlz<6rY~mL@STi=MMx+LZ#tJW#yAArc9kSea6gLcidSy z`>v|H=iC#Sd+&YsKk#66^r43zd30V)?PHHW@#IraKlAK!&%f~E{FfHIT(@vheM95o zC9gES`dahS*s_+_rTFqUR;%N>fUB|E$HHSeU-nQZsFhH3S@xAy(s z4?bM?(Z}ndA3lN2FaX=&YuE$(U<5|t0PKf@a2Srl5jY0N;X611C*c&Ffgj*|I1A_D z99)7Q;WGRLd+pQqsJ-7l%yXmmdHB{oX&>eNqxM<*2p<@MO|X;ahwU?b-~b;uXdkrC z@%%=f-^TM>|H$$Dar>Bk>Gz{>2rk-J?0xnLo*(*ckPqZ}ev^INzRYun>=DR8AAEIn z@alG+!|x8B+rx8vd2T1q?Sc#Zn=NqV>P5bxpKm+?U&3h^hF{=k`vT7m@!T-aoraCD z1vbE^kcZFV3)l*u!FJg3=l&}&2t%+NcKv#$u&J=eK2_LR*i{&^FBbL|b{95BDUnEE z>WOMr!5&Ec!{Lm}6e5X37ivBd)jW%8{Mf%E9X)zVby^Eb$MIWA1s{gt6gf2F_5R~0C&2wr3UzX9iqo2~!= diff --git a/PythonHome/Lib/encodings/mac_latin2.py b/PythonHome/Lib/encodings/mac_latin2.py new file mode 100644 index 0000000000..e322be236c --- /dev/null +++ b/PythonHome/Lib/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/PythonHome/Lib/encodings/mac_latin2.pyc b/PythonHome/Lib/encodings/mac_latin2.pyc deleted file mode 100644 index 53175dcb552dadf87fb01b3695b1658dfe5c600e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4772 zcmd^?d3+S*8ONX9Y&Hi8R}e@zI$(uGB~sds1(6cMVcHOJ5)H((VcBPr4D1nSC(tNT zHK=&s_ia6>x2SmE2a5N7;(hjR?S0wb?_HBkv7e9VANog=%^Tm=1#t7p;Je5ZwVbQgjq-v}h%)N^}fttmrt{c+qdbEYS(D ziK08gzA3sBY?A0?SWI*ZY-iD3V7rP=g;k602Ad}OE!cF?Z^OPL`dyeUx;yN9qBCGK zMfZTs65SIvTlD*|IifYNxuUhOd7|@S3q%*f_7bgw{Xq1GuzJx&um;h+VT(ogfjOd$ zuqM%cVf%?T!ST3lo$B7;fJ3;hB*fPHt zQ(>oxo(?-h^i0@UqG!X-5j_`np6L0o3q&u3T_k!j>}R5vz%CWN40gHb2H4L9m)d%T zAXjX?QuHd=)uPwHt`)rwcD?9E*bSmL!fq0zldYRXZ-(6>dMoTU!5Y|lyXYOTI|Zp` z>s_LE!|oBi7j~Z@)oi_A^a0p|q7T8=i*ANJEcys+iy-4{%tIfAJtq1%>7L)36Pq&%mA)eGc}#=nJroqA$W;5+t6jFAFlx)>j0nX6vhh#IyA^!AxyDxo(BM zF8T)SO+gyk`j+V1uy+LcXY0FyVO!r5eINFL=!atC1q`t`l<_6x+gQ%J(HQ%P#uUP+G^O_YOZmdnueyO)!SS(ecH5X z*1~R2GuEnj+Hx}4YyuA-=}Lx{qL!-fmQ zX^a)%q#(-E1K&#o3ATAeaMZH90uqR<2+11!g(V0}ZvmnlLVrX4aucU)Fc`fFggX`Q zYRd&LC_|S)1ilUZxodd;teb2%6Y$bq-GO-u*Y`7iHikhlk{t)CZmsv0xAxs5+nS0e z+LH0WOHaqbe30{ zO}XhHo}6zY=qJ!?e)_X$1e&=l!ndbNK697=pAB;rdh_Xmyg|kkFk_H_m5njpw!wpl znXU=B!+bMAbog{8Kl0Hv3DWMR4JDN>zbhE@4UV7 zWGqMa-98%HHk$KH;(R^PEa4=Xk`B{nn`k;i*oR|#UoVqyV{rce4y40(?n~z6FkH%X zF?U7`xjK!3@5WQCv~E6n%(S^Yk&BwkMN}@Zn0(4FYkp#ewj)jW7L3R7*=KOvxPCRy zz#1?i{|x=FAeYLN;5mTYJC)lSV^hp3jF$_qRiuw2+!G_QHOhjHZE#Q|TFi>lD@Bbl zrbR=*7mURv%iKU6otmqo`O;!C*~{03ToL!T?aoy%->ezFIk09p5U&9ptIZ;s&&^d< zK7skFs!O+LOhw9ntiu<|VMaI%hr@OG!mAmuHg>pp9DH#He$ON{vrJG4m4u?9GWqsw94yU|EIfC*Q^x?i5BEi(k9Afls72XP&QB|PJmoNs^kr>Bwa;WHW6|)X-5uJQ?6xmH`30O>)FIU zR=kZQmvjSZ7mnUYvPn0Q!Wneo+MRRkf%r^NKcc-lAa-rBRxwRO?r-0N%{+E%TACNNsD;Dmq<;dmr47Q zULh?Zy-J#4L1t36vbmH4uaov8HB;VXa~Y}1g1pVGz~RP%>{G4VaO+-*kA~%EO%_0NnnSD5pi(HfOPDo!cp4WI&bt{I5H+ qyPTEVPtGpJ#o3{l6}E$s%HqmMWn^r@*us+X9Z)Tc{%?N=75)br|E?(j diff --git a/PythonHome/Lib/encodings/mac_roman.py b/PythonHome/Lib/encodings/mac_roman.py new file mode 100644 index 0000000000..62605ec634 --- /dev/null +++ b/PythonHome/Lib/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/PythonHome/Lib/encodings/mac_roman.pyc b/PythonHome/Lib/encodings/mac_roman.pyc deleted file mode 100644 index 9673a31cf89ee47754dbce2d8e19f2be331c442e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2771 zcmc&$>30-G5br&+SrWpn!KjND>p|juB9aS?CYv}L3B>3!*_lli_lUC-F^W1QF>LVQ z5l|rn%)u2BIg}gU~^QSYNxvDSHG@`>(65U z*_MsrD7*f+@b79InR7TPjJ4wIV2YC^9IO==E~YxzCMS#G+RgeI>tk#~tCJ}np>PR> zH?MFpr9dd$LgC9R+)OECs#EAZEQSXBd7XzTb7pj2p)1Pkyi6&kO=|&D=CW3wFo2eP ztPdUZlc(We2?dbGDbUoTccxQ;>P}gcqq?dE8sx67c&Z~%omSLnASp*9S~@AG0v&2f z)nr{&0x=W>mN!&3HPwaIhAY<9hH4t6a0Tw`Yb&J2hRRTR^ZMrHfz5HflU|FGrSh(x za=$-*4WE$i!IOpkJgQEVRFP8woK*B4(G$S-qth5WuAPk5E+&P8lmp#MKi9Q*RFBf0 zh8ssUi5KFeGq%aWw&2&vbSLX`VcZUshwRsdXBmAiN}~usQtpaa?h27uA`}r_ZcnJz zTXaH3O~gb9@l;p0F8ok6Ev;pOsAOWwl;Ntptv=q~He)5zmd6sYu-+2T%psE$KXcqk zAQHWLQwWGQA}&N?d2$7E?5WDVkkRZ{0I7K2UIjKe>x?gOPX{9@X zTZwcMMQNWURiDN1d=AaRf~E}{%x?b2|N%!cAPF%hkRTq42=2qp4P(8I=7@FNya$q75? z+2bXoD8d_|m5S(`Vw{A{HF6@O3P^3k{}N3~+WZ;oUdOFi)(G1CKUh+dEi8#Uw_qtz zwX&m~9Y*5X5*+^wqcjgycg9CTZ}E&_M37Pw)-_d5wrFuIo_QV;%c|&ylu?U^ShjG@ z1effb+F^;+?6DC&N^ywTZgN3VW#vC{fr=~Dx9cwCgQhf9lYBK!)@`ynBlbipz<90j zLb+$w*x)?GX~j#m9J`>79m_|hq>mMZgG7mtPFIVnN`|&rKv#%nWS0~{;<#N9tn#hh zDz>VYCK84{0~3Y=(YisfS!7TgYn4O|8H z6}`b8scSvUaGN1+GDo4q>nOsHSA4q1h)xct%kA+N_zL}Vii+o!%$vVp;iAP$?z+2l z={;rl-gkds*#i$g^zb9ggO5J;_!BG2E1rDn>1UpO?)ev9eCg#^R=&FGwbhkX)it$i z*1lf%#+&sGp~j}Sq;T`w>sr=tXnm*c-S;9J<@Tte#yUFVo8C_(Q|Yb`w2a>U;pUHe zKK^9Or=NWe{qO~BgF)B{-@yos!6=NwL70F;a0DjdC>(<+_z|YzIGlh}@H6}br{OG| zfs1efF2OI{7&T9tKZf6b$HtZ?6np z*~Ja~?&ih_H}-R54>$J0IsW~2xP0Y2-`dZ6r@3)~8yBxmZ@oI*%Z)Mf95;r!aex~q zp%=EpR`?RK@HKn`JK!tW1-q|KT!tYShJCR2*HgKH+=zK1w{C>CX?MM1Zy31T;p28CEHRk>c32T-6 diff --git a/PythonHome/Lib/encodings/mac_romanian.py b/PythonHome/Lib/encodings/mac_romanian.py new file mode 100644 index 0000000000..5bd5ae8625 --- /dev/null +++ b/PythonHome/Lib/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/PythonHome/Lib/encodings/mac_romanian.pyc b/PythonHome/Lib/encodings/mac_romanian.pyc deleted file mode 100644 index f80ccd2fddf7cde3263951705d39950af9b30fc6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2811 zcmc&$>2nlS5Py4Svn1h0gHaYQ)`P_RL`(<)qhyJ*$PuHvXdO%3e0WSU+PMTHH+W34=!% z{6&L@DJ8<-6^203;AKiFQ{BSmV+q_KShV?=GOb|q3tL&y=4VPdEm}&LQo&jRVguYM z!1~d_AbA=MPp1I7aSAo}8XcK*sJ=ti<+!2hp(eSjOG~$h>NAQO52fUIOwXj`v?ixR z?P^-pWkXd$3DkuaHPtmYH%3-QYt}YImamqgHMm~YP$R8ws*5z%MXJ}VU$ZFGqZu9a zW}Nn`?&_@$2DRJxL<}FEFHR|9>qgBoaxH|DiZLLD0^R|19T7m;%}DkzDH^6s7=HS> zp=)s?PHP%o9QCB0jg!Gxr;BaEubUZe*6+dSU8s*ZuM5wzMg?l)2t!KlirMZ8l@Jk- zm?5_%Rr@VEA*&`6A_Ohn)olnrR9(;L*)STJn6e8{s%~ASwY3&@$+nJ16ydO66zEK& zT?qo_no2AZy?R#^2snZ+R6@Kv3W@NS2tTO=rzyB??@zehaXU=F7y+DOv9z30V=*Hr z7O9NVoy4U?Hi-gtjuX;kppx)4R*EA_$N1f49%B{?jp?|qrqr|{CmRHgdK|UlDe`F! zE^R*HjZ&DyA)>-R!Jdy=hd9U}+j@yc0Ze5Eev9 zXlXg=#678y2`>tAJit;J9aWB#*mi}S%&G!dXYa{lO4*xPIKc0ki0E=bq5lU_O0|tB zk!S*<5|uC~;7Nf=yqkyP-@%k-plQn7Bn;;k_C_2jM^Qsp<U>JD`s!uK20UW1BRvr3I+I^s|y^nCKBP=(16%$r9jLTNf9)l~Za2r!}Wa z*u`C+sJ5$_E;5H51v7^OF&n4o5vdd>+trqQ5G|}Royds#Icye)d%~MZ5^XzlazwqKqFTe8YlGm2LUR$@U zetE-+m2Wh@`PQnY$m-^|rRbV>)~;K>q2=Ay_uh|fl-uHpnrQFPIzLFJ(wVLg^{mnT zQP0P{pM1LMv(LYP0r(QO!XWH`?_nPtf)N;nBXAgw!ZA1j$KfQLf}h|toPo1&9)5wJ z;R0NOi*OCD!gctSnyP4GXG&4+_-gxZyw-%r@48Ro7cvM$M$mbkad}x z!`wW;&2!KP+h8+%1v&TzzJ=}ZHSB`je;&R8J7F01!qCn0`7QZ<*4g}?{7`<_x{}|Y z-<#hWreq?GsX;24I5tG;B{p#!x)4)r&QK$gsQMXH?hF5&v~_Dq#cngG9Y?Ck)Ckd@ hm)H$?sRv)rQgg&^>a7e^dMmwEo+@AIbpLJU{TqDlr6m9W diff --git a/PythonHome/Lib/encodings/mac_turkish.py b/PythonHome/Lib/encodings/mac_turkish.py new file mode 100644 index 0000000000..0787f4990b --- /dev/null +++ b/PythonHome/Lib/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/PythonHome/Lib/encodings/mac_turkish.pyc b/PythonHome/Lib/encodings/mac_turkish.pyc deleted file mode 100644 index 7c1fe88895f071cd3a4f6869b56e1b9a71214b5c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2794 zcmc&$S$7mw5Wcf!G9>Jv!H9z!<3i%TA_5^m1culXwiq2c(>+PUEU~*IMp0W5VS)>X zMTHPT2>T+7vI(BUIbDe_bB_Lp`v-XN2Vm80W;&n`fd}oGdvkBqbls}2zFQUFUzOp@ zYu3k;?Dpfszw>bzS8!4oYsT5b6faAASTinsO!cr0UY5eOpY<@-&DgqTFH-_S;S-8r zN#SEknNawJB2-fNnNrSFuh0cp3Jruyx&Twg6?H+Ot0?J$OsS+za~V^{v*wU6fR;k6 z8yyUjr}5|n3c$cA(%5CT=dzKyc3GE`rm9C)$Q>P8wk=YZQ`BT6BPSDPr@m1$+9Pdh zR@G%wRU#=pmx;_?v7oWBA+{u5yShHMXr&ad#r^X7+NM>~vWEE5nx?f)vm=`{Q@ofY zYc(BRHQ}&!3!j)7z|+MUC1kxQSxAmWa8fY>L{Na+gN|eTxb`wy`LU&WNd?nZN{&cnO@fI!`MA2kGZc4&kS=sN|OjeM(#+cSrQ77SRxz= zQ*KSG&RcYXp{7$J1TEXqX$n77UC-%86qQU&#!Ot*v@F+JTZ&eUmQi>j8qRy-v~gsV z5MZAB2}Pn;?+60%E(Rf%cLpI5{1U+@mEm;nUOVOqwcB1t2^KSiQzDU-GioAXhQ%h6 zQ##YQl}IO1obG92H3pz0e2bOiFzA$^x58&m#zjLmsjC?^Ys%?*fuf#7sd!3cnu=S8 zOn8|T<`Rf_@K2~`pwwjz(g%s-BjVsCuZl;>Y)r$6iFgI<646e;D3N!9Brd*!B`GZ{ zr`@o}5;37gF^+~;s-Tl9aS~P+%V|Ruu)3zlj3}jUQqg|Ub2pxg1bzM=JSou*p2VQL z@RX=_x$%w#O5)sf9RCibG!a$z%S%FVTG2G3NC}FYx+-VZ=o*&O5+8|e3+acHSBH;S z#Bj|7r`*iCp^4R4;v$H}=_PQS!XNhKMt z7+x-aagA*+K!Io?4U9)g&5KEb-+!ORv;3p_Po&7{BkJsl91j|C@;c*p}<0njXn9gK#9Utn3+4<3? zkGnqkbn|DQe*r!46>NiE*a<&CKOBNV7=j~k7>>emI0+}<6r6^i;0&CFb8rEEfuG?b zT!u?<4St2|@Ef-V?eq4Keb_$Ets(m|9JJ5cCwb41ebGL_dk0}F?B)3Z`vUJh!h4U} zN9{{IzlG;_^8AiJEuKGZpR%w0aT1QfRr`j0$UejKeZTMGy?LJBYM-{RbL*Hr2o`k1 z_anPTc5@5Ad$`rltpnWJ%dLHIh5xu6Zj4+V9vD72e17=C$iT=!ZXL3(aI2471Kc_f zTVOkU3134VzJ>2#2Yds&Vb9IOH((d^!G73xb7-)zwa{;$E9@=oEA-h{3kM4O3)`ZU zNn|iJMJ1QSCP)p$A&pBFVu`~S>OK+`J(G%j@&A$5PA#oCy#=MC2sMV{AUg6~rw7mT c;oAl^MC_pcs!)}`%3tlP4wO#_-eUg00R*g{k^lez diff --git a/PythonHome/Lib/encodings/mbcs.py b/PythonHome/Lib/encodings/mbcs.py new file mode 100644 index 0000000000..baf46cbd48 --- /dev/null +++ b/PythonHome/Lib/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/PythonHome/Lib/encodings/mbcs.pyc b/PythonHome/Lib/encodings/mbcs.pyc deleted file mode 100644 index 35153404c0bdb0843a3423d2e10d8370e4becde8..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2003 zcmbtU+m0JW5Uufe?e**?T!erH2{kWdRtkPVNJt2w-53xnfkEv^t5_=ybcSe( zJ|NSfBA~KE(+-s(O+yOU8nSg7kcFd52EQYE0m~7Y9@&7N_Gpe}eR@Ikoao84N9I@@ zeQ^wSj$<;BI0oW4**OMePQ?+4Oncnng?oB z8=I+l?bLN%nfkVgqG(jql{IR%Q9q~dnffs;%epcuE|=}-qIs6DR(WOpFssX9x;|HP zSC=YnvOFKIHV>oQWu7h7ZQ7_?mwRuk?P1yHmz8l={bbA8+AVNoT3i(EgwHx3Mp2xd z1J!Ed^2O4t(O6$SRF_4eG|wBQZDZZ<)(qA77j=E9_2u~S6Ku=>#V76{LVtpeqf2a+ zA-w$@p<+JvJto7uJo6cE;MPSOvH5Lup6Cz!0`dVpXZ8XZ$8xylq36|)-P*SI9buMN ztF@Pdt#h?&V%SK!=2MJDU*EL6fAQ5#kJ*;mS69xWV^jB5p zY-uZ>7T-%iZYM`x^$4xuJr=JmVlyN%3rV-gGgj@(CPDIY4l>|4pCZT(%lK>}@r-kL zsg0ILn&XRkzr@|xVy>A0&-Qs0Z6u^?H`94!yb-P#1ts0!?mqZ1^OQM0XI|i~#2zqzEF=GcWoTjGEl0QTk7rx&)?e;pS;aT@A#P{ew DJJgn$ diff --git a/PythonHome/Lib/encodings/palmos.py b/PythonHome/Lib/encodings/palmos.py new file mode 100644 index 0000000000..4b77e2ba91 --- /dev/null +++ b/PythonHome/Lib/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/PythonHome/Lib/encodings/palmos.pyc b/PythonHome/Lib/encodings/palmos.pyc deleted file mode 100644 index 07203bf5fe2a555fa4e311b0ab3b0827e51407d1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2931 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 diff --git a/PythonHome/Lib/encodings/punycode.py b/PythonHome/Lib/encodings/punycode.py new file mode 100644 index 0000000000..d97200fd35 --- /dev/null +++ b/PythonHome/Lib/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. Lwis. +""" + +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/PythonHome/Lib/encodings/punycode.pyc b/PythonHome/Lib/encodings/punycode.pyc deleted file mode 100644 index e60aa60f58e32cee0e45f9b30970e3a890838b26..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 7685 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 KmY0f4BmV-ts=9#y diff --git a/PythonHome/Lib/encodings/quopri_codec.py b/PythonHome/Lib/encodings/quopri_codec.py new file mode 100644 index 0000000000..d8683fd56d --- /dev/null +++ b/PythonHome/Lib/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/PythonHome/Lib/encodings/quopri_codec.pyc b/PythonHome/Lib/encodings/quopri_codec.pyc deleted file mode 100644 index 86db8adcc6c2508348e43a3bf9253a92dad61a1e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3430 zcmd^B-)|d55S~3dw&OTWng(c4B(_gIL>dIGii7|Gp-7Rc6s=XIwIZ3z-P*b2d}r>~ zRFTpb(!Ys6idWu&Z{}=YNGp-%p)Xu~lewM!G4sv0vs?Rfx&8b8&)txw&jS8`i?{d- zA|mQRDvCTx6!oB#x<@^aPS@qLMoEoEb?Vhg?WcFBZWrjJP5Dz&N^yU5sLwj2ik?Mv ziWcY<=4%k^4bhtvHOVSEZqWdPTJ(zOoalM4MbV-d7RAt>8x|>A5<^=Iow=b+(K6YV z*p_JEQFLQ&TcT)XX6uM;b#CiWbdx`N%N%gmUt=7G5Ib39Lp{iH{mUeCHo7;?C_!%sV*EQ7#3SP z&76Lk#+buyx8uL@?D+~Sx)wxNdhI@O4R!<{p$k2zoTED49d15=IFrPjcvP&BBl=B| z!_T8LK&bfl(&HAu`Laf?M#ptJgSEzCp4Ui0J6;eo40XbKBs$P;G6o!eHgPcN?C{uz=#kiT=#F%lrNv}qqmKcT#$)q5%L^UZL7dt` zrj#aq1mF^$&}BLpkCW4Fz3aGNFi9LbW-|P43C7*3`-`JEJkkJ~z01<%RELv1x2c0x zOvd9ZN7|~TtAU(U$q>gDPTez{f|!Nhgm5gjHKj6@&jgo6`~3! ztfX*g-LFA1vC{KSq!kMNVE@a zhK*8L9K%uAWKaeEc99z1O!s&a_MFsPI;)uBk?b=Roh4>Wj)Cpgb%&F}6(_m!# zeaG4C_eWVYN$@FN8y;0fE810dxmm@yPw*DJOvCGVj*qI{G|cS?H7`iYQk}n^)OGYL zlWHZGoK#69SD)9Rj;=EFboYnhy zF9K>fN^=WBru{KU3M)WXb6*`p4(;>V0u6N;!Lm}lLj;+KZ$i+#2SXL$mB3?OeKCuT zl(4Y^&%Dn|U6*?wVDQ7)+`x@%6D}$?813WuvlU{@C@CZ@C?)4mFrZHK7fM#gPntIgSv^kFs@}0u2{HxEf9(y zZoeQiuD&=DaOrhTT*I1OpAUdNsf}Dd&h23D;v#?`bK@Twz=>RhYz)* diff --git a/PythonHome/Lib/encodings/raw_unicode_escape.py b/PythonHome/Lib/encodings/raw_unicode_escape.py new file mode 100644 index 0000000000..2b919b40d3 --- /dev/null +++ b/PythonHome/Lib/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/PythonHome/Lib/encodings/raw_unicode_escape.pyc b/PythonHome/Lib/encodings/raw_unicode_escape.pyc deleted file mode 100644 index 7cfb6c6ef5b1ef1b9285f36b8e90df89c2f740b0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2093 zcmc&#!EVz)5FN*klejG)1cIPS_yDRa(R=_xs3Cw5X zL1w`a6&s`lr!^R%?!X1WIl$qt21%U_HXGd1U_;VigTsbqX>cHEfvmBu4kL8nm9{!0 zYfGEUw)N8HLb5@VVS|Di1h**GuPFQv3v)8f{Vf%p?acEuo+fff>NuLoEx(78*z>#t zl^P>+|9IiQi&VVR%@Za4eK|RvtFa$UqHH%SCY^XX+3t8=5O3q#vxQ2>C&usf#ojZ& zn`OSBx%P$BQhk<5$M3)Q54u8h`yUVSwe%-GeN)H4`0Ns23s+uI%#Tn=%)_EgPi+`F ztkhxXf*1s7g`k1LG*N_M9!+Ez8jmNFX)@1f>f)3VjkRf`im8W}sfR`Cq0Gt78!y$r zY(yu^jfGl-fL?(${S>v%(SCY-#E#N@tdFi9*qJQ^y|aNsJ1AVIWtqFE?B%hN6PcSR zd&5Dg5|kR68I*gdl%QbuU0~DM1P8$uQ*SOu4|V+jg#kFV;0yktQiF5sBn#SufPD5- z6cErmf&~RsV4>7hX|@{1)JjyB%R>+^KexICD3}6LxfS?QnEwJ;q zQKqG!jnxUO!ra8S2{1m!y#n%UF6e&%nVM3xC^g2MT2`!)Sf@1{D>oF~18Upr0TtA1 zg7#F-SH+TO4Ut85m^T2 z#N?%wlVubNVso;dmnOZ87h_yesAu%zI+0Fq32tzzg;O zykHN&3-$oKU=P3x_5i$K55Nod0K8xizzg;OykHN&3-$oKU=Pe`F=t@j7xMwkSury( zvtmAknG^F7%)FR$FdvHvU_KG^Da>bL&cl2z<^s$YVlKjbDP{rYl9;ZVe9)K6@0eHb4fEVlmc)=ck7wiFe!5)AY>;YV#qb$bhe#T)!%%VnV zk66UvifrU1N%GrDnv~^9v1po<^?iy{vXz%y46Ws*R=rC7{SK(y-t=poxU#qwB~ioM zq;fOrc3r$$S?n0ws5CoCCA@WKZhmHTw1Q8~+RB>u-Se}vy++zwnQ3%dog^}y8Ebm8 zzio8dF18!9NypF4&uVXDedJo{cK^GH^WMgll}!wkG|pa%O=2rIYS}664t5({K=R3cb~Y1 zZ}6Q@5ziv4_XE7hdQKkUmlvOxtpZ$?L;cdAdxLIC{T|dd;Inqrt=pKDejHU=g!k&G z&-#!*wXLQuz{TC3*IC#k=_F|tjiQiFqcn5>hFiJ6!;#*H7whnRcQfmv!%UKoOPAd1 ztRZCAf6N}s*_pi-ch5eg*F$h(Bk+j`xP>Px$0dM&($ zYzxN#gMqa4eCLGdAdE-K0m}LDf}cX+dfZ5C+r~a>T~*H|4b>6sqC)w9yg0%IQi35R^Mn_}y{yCY zGFwUYbrk=7wgW@%uh-DvK6Ilzloh^XL~1^t1&d1UKdcv_6{}+&LCWKm|?MruziXs~khr|psYi!9-tx6dzd2S>okd%oDIr8k>{2+CxYTaP(XUREvvO3F7iN*;h z0^;;g@D<^E!q970aj`O>ghdY)tfd#MdKgR>vZMVX%jshPPUqtE@N{vy Zc&u=&G%|4z;vV`>zGJ1m#gPKH(cg(WVyOTC diff --git a/PythonHome/Lib/encodings/shift_jis.py b/PythonHome/Lib/encodings/shift_jis.py new file mode 100644 index 0000000000..8338117276 --- /dev/null +++ b/PythonHome/Lib/encodings/shift_jis.py @@ -0,0 +1,39 @@ +# +# shift_jis.py: Python Unicode Codec for SHIFT_JIS +# +# Written by Hye-Shik Chang +# + +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/PythonHome/Lib/encodings/shift_jis.pyc b/PythonHome/Lib/encodings/shift_jis.pyc deleted file mode 100644 index 65d6022bf944b5b187989d0bcf67e445f25887c9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1705 zcmcgs&2G~`5FY=;`Kgm21gQLo1E-w&1PE0G4wayX&7s1IWD@Tt*ovLX-U{^`o{5*? zF?ay@X52VY3x{0d^{!`UX4l`$&bQw0e(&ei*GWQmkB{#;di4u~#_Q0EC~9PfB4?|2 zDe}k=Wj<+_HZZkFL*q~u&;o8g{UF*9eTf3nEixWuZ83Lf;gSv-bB8nxFn7h=6LY6A z_ejGKh{uU|gtYKT_Zp9oGz_&zUpxll5jGwJ(tVypLyl=O8X&&(51vcg<#@lP3ma!? zWm}ky*V-gaP8?|7v(F0*h!+_!E@hsC55cF%Cp8(tN+VuwI~d})nB^vpZBHioTHmaA z$_@$dZv#lCU|B?{AlAFULLybKAe~J=rSqw{rp2!09^nF@%dE zDNSw)J6nB}Uz88S;S@CCL~av;2fcE65Q+Ca7*!jK9-&vfPvG9i^g&`hGA2HiCwrJU zYZF_VS+2}Xn> ztCG{h3F7qj6yGI*@;70Y(5(`lkC}NF#bPbI+5KE`!78p0#UK^uFpav^cv~qT_VO`OV6v^IIz%Ni35vpC@vuV0T%eIENB~ z +# + +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/PythonHome/Lib/encodings/shift_jis_2004.pyc b/PythonHome/Lib/encodings/shift_jis_2004.pyc deleted file mode 100644 index 51385fe31f235c27f2146fd05be693d1e83e4252..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1745 zcmc&!&2G~`5FY=;`Kgm21gL<71gD&;s^W-HMc_~gde|H)tVkyDI>A=#RQ6UV=kQFt z43EJBz&GQ@2`yZ5iS1p_&dl!4-#5;$Zs*6{4vYoPJ63##2~Hynu}!HXF#zFG;F1~*Af*9sH!VzIm`}1e3{6KC z*;3yuc*zP8pKm-+an7`mV1cYofrNxAUxGRre@v!hQBCrBIsV(?lk1gY6Mc-5ljvD( z%RB^ekw-YnXO4zMPd$O5?Al@tx0tO^}!o5{~VJ+CjjX2 z0ox84v;=SfQ+Gq7Pc#U%59FiR0eRCT-D0GysW}?3 zW{SJ)3O|Jet&}_>m&oG|eihe>Vl~C_*b4~e z2s`I744VUy#p(r?B?E&1SI_eCdh!mKS#^!dzA(L3!sD2S+0DWv)0Gk2M269sO(SVJ zI9+xq4y5>DICY;kJMQ-b@$SD$x7ZZ#&EwsZc5xzc`Ioq=S&5k9cC=sEIP`C-?)jE; VQ8H$aE#L0jPu;fl#NqJ@?;mAYPrLvC diff --git a/PythonHome/Lib/encodings/shift_jisx0213.py b/PythonHome/Lib/encodings/shift_jisx0213.py new file mode 100644 index 0000000000..cb653f5305 --- /dev/null +++ b/PythonHome/Lib/encodings/shift_jisx0213.py @@ -0,0 +1,39 @@ +# +# shift_jisx0213.py: Python Unicode Codec for SHIFT_JISX0213 +# +# Written by Hye-Shik Chang +# + +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/PythonHome/Lib/encodings/shift_jisx0213.pyc b/PythonHome/Lib/encodings/shift_jisx0213.pyc deleted file mode 100644 index 9740271c58dcd709669cbea84a8dbec4750b249d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1745 zcmc&!OK;Oa5FS6`JnAF}0V*IN!6~PT#}%Q9z@ZZKusKv%kxb%sg00x8?5!Z@@SFHE z{0x2od^2vG(848`*xvQ*%MWl%Ac4tK8qGaK}}l}SR1}g zfkQD->XNo;4N-$MI2NTI&7kJeccL}Xr@$lKpxB|bDdHB*Y|>sWZjpun;~uibhW~{92<&y3328&pwR?J@}XW#&d3%EWac(6Q)V| z?fJ_WuS^51;Zny@9T*Fox2*UG6P!jEVw+M&VgSOWz$G;rKuQDNZd#baFrQ>`7@CeO zvZcOS@RAiGKHqqt;+$zA!2(&G0tpFKJ_U6${*X+^qMGFMa{RZ&CzmV5Ci)m9C(*Oo zmbnY!ERTvfi*qwsyq9~5+dgpwYM%nT_QL^R**pow=k8}(6FcuVr3A{wXGdP5{v3 z1GXJ9XbIo|rtXGDpJ)(jAIL|s1M;Rxy2VIYQ*$(6$IlHH8G}aQPl|z}7$Z_L$+ng& z%oI1-6@Cf{S}A!%E|JF_##f1=+$N9{9F~S}A2KA*^4U_bw7pz${VJ{%#cGPO9lo3uAb%N_2eBev+5d^ePMd3gvT)tv#W(krYj@3i43DNn?}-d zaJuYJ97yrQaOys8cHHg<;@y9huCXcJoBO*b?czk@@-J~!vl21I?P$NSap+%H-SZ9S VqGZe-TfW`5AG&Spfy3h&-ah~^P=o*g diff --git a/PythonHome/Lib/encodings/string_escape.py b/PythonHome/Lib/encodings/string_escape.py new file mode 100644 index 0000000000..e329a2607d --- /dev/null +++ b/PythonHome/Lib/encodings/string_escape.py @@ -0,0 +1,38 @@ +# -*- coding: iso-8859-1 -*- +""" Python 'escape' Codec + + +Written by Martin v. Lwis (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/PythonHome/Lib/encodings/string_escape.pyc b/PythonHome/Lib/encodings/string_escape.pyc deleted file mode 100644 index 4ff4ad65b30c927d121164211849bbe678213af8..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1952 zcmc&#&2G~`5FY=;N!%6?Afccl`Brlv4}cJ=C?Hjo3T+M*Q6=Nro8l^QD(|*cByR1K z@DRKh5?7dS+}IWLKzjfuJDJ^C&wlf>U%c;Y;kUg{ql_*ekAF9Ln6E5yqA^Q{a+jtK zjal(XJ9OmIgms@Th|Y;Vj$O(-V(`QeGzO3It{8kV^csUtd7rc^whm3$LD<+jl&>sp zf!J0XTR{05CgUzZjp94N`i@2PVPQYd%VCiYJHHz6vahHYdu}G3Ko#`a8p-g7;{A7x0z|#yMja_54#+~RAYht`quNZmr(panY zQT#TEW+K*x`#Z(KzPwzNhi2c{ihq;Z|L}OBupL;8&mwU9j=j&yc9~Urrc0Yn-w1}P ziQ8qf#Ql(!CT{MI3vLPz5hF7hdS^MdST~PYSfV3`zVMe7m(ID;4h=>zeC`%3D8@TV z1OU~cSJk{SVzF2>dODGU6y@=W6>U9mdi??OjS@4+9ACntt)1@H-+}E?eU9udB_RDAE|vU75opWMYpLwqLNIb{%Qqc6>B_h(n08L^uqONROncRJ+0px zWDr;S!O}Tr5CBKE(&-FWS+}`st|M|@x8?Hkp_*-7Zv_KIL<27i*}_md&Hot;bSvoQ z5=O?VJb<^w!#rnEU$UC0nWC+bQtpewOxr)C_yd34TlaneYCvun diff --git a/PythonHome/Lib/encodings/tis_620.py b/PythonHome/Lib/encodings/tis_620.py new file mode 100644 index 0000000000..b2cd22b23d --- /dev/null +++ b/PythonHome/Lib/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 -> + u'\x81' # 0x81 -> + u'\x82' # 0x82 -> + u'\x83' # 0x83 -> + u'\x84' # 0x84 -> + u'\x85' # 0x85 -> + u'\x86' # 0x86 -> + u'\x87' # 0x87 -> + u'\x88' # 0x88 -> + u'\x89' # 0x89 -> + u'\x8a' # 0x8A -> + u'\x8b' # 0x8B -> + u'\x8c' # 0x8C -> + u'\x8d' # 0x8D -> + u'\x8e' # 0x8E -> + u'\x8f' # 0x8F -> + u'\x90' # 0x90 -> + u'\x91' # 0x91 -> + u'\x92' # 0x92 -> + u'\x93' # 0x93 -> + u'\x94' # 0x94 -> + u'\x95' # 0x95 -> + u'\x96' # 0x96 -> + u'\x97' # 0x97 -> + u'\x98' # 0x98 -> + u'\x99' # 0x99 -> + u'\x9a' # 0x9A -> + u'\x9b' # 0x9B -> + u'\x9c' # 0x9C -> + u'\x9d' # 0x9D -> + u'\x9e' # 0x9E -> + u'\x9f' # 0x9F -> + 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/PythonHome/Lib/encodings/tis_620.pyc b/PythonHome/Lib/encodings/tis_620.pyc deleted file mode 100644 index d83d896c75d0000bac322ccc06bb11b574165e3c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2803 zcmc&$X?qk!5biy*SrTs0VAREn^&lWBUWiBljY7oPXdp(H&CYBxagR7N5u+%_2Eu*c zr}upyQ0)hKp8h5E5B%T{z^Wdy6Qa)(;e+mOcWSz(tE=96yDE`C8L)^f zm(g%9(PRqIMRQ1)VNnc;E)pWb3W@%(D3BZ#!$MSrSl<;EW=tz0S`n`)BEqcGil|m3 zYKo{Z>xC88x|k@Cfn-e=6Xv8*U0mxLYPz^E8~LHDPMDKLS3(;gO9@dW2b1h+COw4% z=%XpMcF60ilvAyJIVYF*EGM-lH!xtAdsD3y)5@nj+s!Usv@q3cl`SXdS!Sx>R7$CN z1A5#1lK-;1prb7_pWbWfSl2NxwbAzact@U1v;Cpd?-E-``m*;05Q5vnhJcA}ri2jh+M8B}`!lD|X zfJ3z29&Fd1x!z=2%~RwQM%H&%FKLl5$a=Y+qUG=66I`oU&>`66fk99EVL494anqy} zdUEHG)Y84$?&%)2;&xvJk&y8BXkaF>L5^O8ZX^tYw_XzfVNH1JB`sbXfWgok44qL& z)Af1mn`X4GdYooByaY|zY&lo5vRN;wA4(N-ut<*v>kN)DI7v$r0A$b(QBT9=6XM~9 zh&P>twsPLFN>Cq<;-5OH_q~YBE9b!&Yz!ahkktM=pq1)V) zNwe8@ne3H4UG^-f3b4xN2q;>~gLcggjBSj1tE;7FMHyPidq{TU?bZx|W7B zF#E5NqHPT$7a*`X9$g{q`DCvGIFy< z%@TT?l#J(Cxl*TNQ=P2wkJ+`HU*uf+{G&oevd|m~vKfS=rHSHVS~Stnab4qpVdc#K zzyU6$&4B~8fH^&_yuOSk{|5ODkXj#?Te?bgiK3%2^|2T;*^G1Lre^0+V@h!GsEWEw znyJw4@pa-l;&N@Ga>>0UC?T49?5p`wdVaIC>M$Y3HEjD^7&xxOTNOwL}5e4%dWIYV>l(Pc)8P<<#KYM^gie+Q9i z6beV8v3OmgJ~^qOaq^U@)27duIcxS!H#g0>rTNy|Zcoj<_>_ga(Z~);T!Xbpi2uBc(A{;|Fj&K6uB*H0#(+Fn}&LW&c zIFE1v;RA#Z5k5lr7~vCyPZ2&t_#EL2gf9`kLiift8-#BWzC-vP;Rl2t5q?7W8Q~X% zUlA@MTtWZ@iSQdaT>BwhM!5y$R+QUNR#6V4+>UYw$`O=1QSL&y8|5C9dr|H~xgX^L zlm}5BLU|bF5tK(!9z%H?I7_gLcvM`wy*-A>;%FMR)5Zet%vXp`9)_OzN=FrbJV;DcT%qj@3_z IUlGy206g@&O8@`> diff --git a/PythonHome/Lib/encodings/undefined.py b/PythonHome/Lib/encodings/undefined.py new file mode 100644 index 0000000000..4690288355 --- /dev/null +++ b/PythonHome/Lib/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/PythonHome/Lib/encodings/undefined.pyc b/PythonHome/Lib/encodings/undefined.pyc deleted file mode 100644 index 334120a285fd1f846927ab9fe8793977e5b39358..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2454 zcmd5-QE%f!5MIZLo90?T2oRNuv=R^JleoO`hERLqkSZMkZ4RodDiznePPTIFYIj4( zE4^RBkKm8-1K^u+W21u9D*}X5Pj`2`Gv9nOI~)JHKlI zkcZKP(ZXgO6 z7`3{A(2usdgmrtZE)ja4CTBYYYL>o5SU-(~kl$>=qORoQRi#Z~E2AIFNv%yj8c94a z7uL(1=5lSzQfB2k+j!|R>y6ChcUieI&z-BCG(YC%I#`%mFH9vbjjiTvV&#n<%ab5s z$yUL@kCp{?Kp`(TGAxYrHkk4CMi#a-GSt$qZO9k0E($i0twO!bg3YB54tD92Z!1f< z0M57^ZpWk1sj~t0$>>*^%by-s+8O!6EH77XF4JXJ9+k~xoY%`I*pcQ>5bgEG+4&;K z$yA+uB99TKqPdsKc;kK`_|vcD>9JDB)0eNX&HjdG8U`SdxoXRxhm~hUt%NY38|mgs zc#SeZvM}xm8plG-QYxB|(C3IM4>`^0B`XtJeg`7({+mer#I|NBX{Y{O$TnrtRNw-{ zq{yfUdl0wuaBdn$eXM#@77W`~*Q>z34Q0=#Pzo0Q5To(=3wwFKwd&7XPe@X;iyRsP z;R%n3{weT^%rRg^R478Ni0FqRM9Bi-``CGlFeOuA2yt;yWlM8$5k@>&)_PT9swfp| z2cq-!W|S!G5tJ-XK9b&E9Eh5eDtBgSs*sh>nJ<@Pl^=@o8D9S$L{lg@)mn7LL7DtF zN#!!YfzQe=+Iw@)6de%mChN?pB2LvV1l#;FE4|?lJHu~CBjw}6t@R|jOX3%t(*F~Q z>JiX(VcyRlRo6$`2t{;fGRnN0sD5Z;FSk2?r$(6m0G^&<#$)GPE-{NcpKBJ}7o zzQUE;-;Qz14yc%QLj4(6alo}Xq~>uWc4jG+`ZUl{r#=#B+BV3piE#DWt_5&6HSX?m z)2AFK4EF#Mw&sNWVF8PvkKJ zfN72%<~FpSuOt!eMoF}XU&6n12n{Hr&Z_Gio%92Y8$^GBL(vg`Fc|XjS<|XNCt#l9 R0*d~@@SuOtKa39tzXMGr>45+M diff --git a/PythonHome/Lib/encodings/unicode_escape.py b/PythonHome/Lib/encodings/unicode_escape.py new file mode 100644 index 0000000000..817f93265a --- /dev/null +++ b/PythonHome/Lib/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/PythonHome/Lib/encodings/unicode_escape.pyc b/PythonHome/Lib/encodings/unicode_escape.pyc deleted file mode 100644 index e3985181014b6a436cac8898db67a01b55f97f99..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2041 zcmc&#;c62>5T46jF3Gi35k(^fPY`+qn+Fh)#;8!JQ8q$pD4f^3O?u&S3A-C5;J@~l zkKsf3Vm^S*%r$pb`@{B!Uc1xTo!yz)Z)U&R-#5H(2OkD8oPRd{-Nm85qDTOSC@n~8 zkXbN9#Rh4?qy{6@9XJCx1vnhmAgQy#W`kQAY)BexaM;i+4GttNkTtf|VT2C6(pHCL zZDn)WwqDv?NH%CPY*12z;0ERT1%>}^X-;OjzqQEIc$UZ=spDuaxBMPXV$bsqRBDXO z{o|$oCQ|WEH&2xG_vQ3>p~ikNjk4XWm~`UVbi3nuLA;Hp=S!82PmJH|i@hg)H_LoM zbL|VMrTQq7j^BUlA9RK2_TL}kvGfOieN)GzIChDxg)1*8-v=lp-oc_f)3x8f$YG)$?nI#kE73lZ`i>tCwuT!>dh& zT7*V#z?y!9TIXm#Jw9S5X+G9R7Xx+XOF{cLaA*gG>$EI$8cOD^Jn0GAq2wCGxlHMOT$Be70vIIh%0)bDK^mjfxNzXa{69A5=P zqKW$}?}#C#I50{^Q=$b~p;x|9LcM6s)r+KpR;9gO9yig)CXQ7tt2~5^l7E-SEzIFz zl}C&!f0SPjhklBpcxnaxBk>#Ns>ERh`MXZ-ow)SCkmL;#a+4VA6dHqo+M>@djmS$A z{18kXvQ>Eg%wm_ zL5T^vv>-&TRZ~MfKbDx%7|Bj8ALCS$H?Ufki-RQn1QZcrB1%tYaTpdHMLRD`MiARw cFCz-{toTRqoOH(Dwbq?>qwTbvO?$Kc6Fkj})&Kwi diff --git a/PythonHome/Lib/encodings/unicode_internal.py b/PythonHome/Lib/encodings/unicode_internal.py new file mode 100644 index 0000000000..df3e7752d2 --- /dev/null +++ b/PythonHome/Lib/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/PythonHome/Lib/encodings/unicode_internal.pyc b/PythonHome/Lib/encodings/unicode_internal.pyc deleted file mode 100644 index 68daa8c5969b6b683ca724e11059566b0e055b6f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2067 zcmc&#?`qUQ5T9Ifxx2Jg5k*f51{6%e-UEn8&#F+Ur|b!(M5Z{aZCP)L9gN(W>E zatB7JxS$+3Zon9I56%Ei0rp1?kWDtYZ15|C3$n!qj}7h0;DPLbYOt*dV{{NywkF7x zrOjvCYGw05uF+)FB2dHV24Ve*B7DEFN3$Y)GB2`pCe>zESfz_3e-duvG!24aPiNMu zB0OA#Zxfwv_6w<1xT~gzb3F;8X_9Z{<)oL+rW?H=h|&#w`(&ZB$&n4W2V&=G*w6D& z(AZ*TI#Sg!lmpg;6*Z=dlYTkCi5j zd=SG3tq`?P*fxqdE|RH=V;k^fI+OF9ran$7)YRB}sGbKNF9VNNK~~;&u3owg9W1w% zYI!_*1lG(W)OrWI+2H}Z$%=_NxOiCaWFhE{H5|r6;d>p&-bQ7oNVS@(!Y27^2BfQW zG|cqPbC98ch~5z_ z2vC^^t!LV>#nPft`IzgJ6(@7c+Bn0esZ;RR(NneWl1oAWPDJhn;TN>PuHPiNQGzzs z{;!teHoi;A;zRsD68wrw`5zKYttdJa80VWBRjiO$r8OK^Y$fXbE{@BSDX7Z??WtW~ zEssPS_m}=Lj|6jQwMwQ$5~|K%bz>>>Ws5HFCzZ7>@O6>gL@(<&mKCj$2$jfxiR2cd zcvvGzQRRmaZsRb|P?XoM{3PJVz%qMDj}_$fCN;YB>9Qg5TO{c=ao8!eh7q;LfNveq znW5t@ay8!#E-X_=R#QhwVEW>6Nm!ceXSjZ!xqiPbU{NuRd^(eXB^*r4JH>d$q*Wg) zsLX=8Lr~a)Kwh)5mim995Yz<8PcI(hl!FGR6@Pb-i_Wz4;5GsF&;j diff --git a/PythonHome/Lib/encodings/utf_16.py b/PythonHome/Lib/encodings/utf_16.py new file mode 100644 index 0000000000..f3fadff615 --- /dev/null +++ b/PythonHome/Lib/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/PythonHome/Lib/encodings/utf_16.pyc b/PythonHome/Lib/encodings/utf_16.pyc deleted file mode 100644 index 14579d22916f0837440ca267a680899f82d32fb1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4908 zcmb_gZF3V<6h6Dzv`t9m)k=L`L?JlP5nuSAj#5w@Mhwgrtag}*Y4)Z~NjA*xjhGqu zAmy9C!Wn;qf6O1C&vWi}H?19L9m?FxecyA>dCqgrP37#J$sT9bt9lkoda+P$=##Hk5ync@04-3Xh*&fx06b(XrL;f1Aoz1h8h z-47>ee`C{z*IUuei{bKM5Jv20VPrCs{$k>#uys3JU5=vV*4>}5t^W`HT6TsK*|gua zT^~)B0OdM|PolCSTb?`?dF+YxWxIk~co=UrseRqvrRbTRM<2IoU%t{tA7hpW-A%`) z$y03=RX=$+wz|or=_t*b7!$3sMYNXg-|Da5Hwkw4la1`YJ8tRWM7Ow8k78ZM1I4o^ zP~S|tsTrEYb_U;Yqe;7*r!HN3dx7)K*lX~odhhZdhyXuK_`#Fq!Yq&IZktX@zgX=ryY?>+`V+^KtySy9Ba`uMEF%>YOrm}U+A zsLo1TRM0e*oHF$Gma=D)%yQxS#F|kGbK7I+<-i-5wp%|vxV|&kyd^(F_EH+mJ@&Y`yvQy@oTU9%l)0$-R-ac<11dI4s~uh*h5v@JneABf zKIP)sQY}2J(ArfD154=%`Vz!zdy;&RLlxo?ksk^iXsfz23q+zjlXtOeMa6AJ4II^^ zhn1R)Xt;=^;#`wpijJdlHzZgTCo1Pbm93Y9!F1C_9Ffsz;>~yspYUkXJ#zv`Izs~j z;DUC0IEu%>a9jOXzk8!I$V_w!vueR;fvwZ1N?Ek^eEw9%AzP{-5F=>RYe8*xFN1!q z#JvxLp2J@A9|k3TVh}u9(MCYBq-(uIvb3+`yldlL&!i@vBKura)s&i3snf*>N1e{o z4^5j_s3u-QX_E~ihR3KA|AEFXC;5GfHkB|zf!l%HugH@?o>b)tfLL(nce*%GXo5Sh z=u|~P+|wxsVobduk2M-Ss7m@92@?Scgz*&UhX6RCDm|nWySNsdjBhhUGh#Wa)i~cL z52^QN^tF3;Zy@Oi5%*1J7{()$g~`aG-$`xwsBbsJYq!5wkVbD~`4llvajp4vC(cg| z0=&)ydk8omqyyed`V7V z!a<+*)TO0D4nhcTV%w)E8IeLlsLfkiXGJl=EOfs_>H=1n=g=)pp7 zQZG7-#&jrTvY^@J3o5XOdcaf9%|5P+B11XJOW?jy`nVXh?eZB{4^t+1%Cv_U~=ZdT* z$0dNt9@HhhB%bFbp8TjrAd$D+t=WutF-J9&TFGwN;yt%MwvJ-|C+0dhEzeqxc@?kj z&3i7W^EUicaghnX>t2cK#K0IIiY@}~1VP3!_j>q37vq%yRt_ZjSi_u)fU7#?A|R$t zGt9+M0wUljkAP2o4S(1kX!v_6fllL(YV#f3C3=HZ$cp!j&aiqHm3s#6j#Dl~t#6sG zjo#xzW|AfBUI1*KzloC3S!7ozYIrV@D%oC9%^l_O+Iqn^xTcMw+&1IaW=R+NM^P1u zpP=C^2;0F-;BZ(Fn#Y3+SqE^4Uq_IQ;%5=&A#;LMYg=Yl^y${ZG&lrVton`nJ;Noe z6jn3Le)&ev-?n>)^Sn*{%`rGq6F%-3lia`~jY%#mp|SK8c%8pJ+)R3-@{5}5MvQOH zInJSVD3w{77*CVbY~W{wbTUTQS;(s)g)jd#DV(OA?RGrsB5hX?>5D?y@D%19h!kR) q7N}s9$w_w^t;0z-haF$Ihr*X^t7tRc>7eE}DvM_q7Zy(~F8m9z2swQK diff --git a/PythonHome/Lib/encodings/utf_16_be.py b/PythonHome/Lib/encodings/utf_16_be.py new file mode 100644 index 0000000000..86b458eb9b --- /dev/null +++ b/PythonHome/Lib/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/PythonHome/Lib/encodings/utf_16_be.pyc b/PythonHome/Lib/encodings/utf_16_be.pyc deleted file mode 100644 index 0f60b753fe561e13563dc67faf9a14465cb1fb8f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1894 zcmbVM-AWrl6h52(tlEECEWOxXxk3#H#j8?`X$yi)%R~@^uuXO+ab>fS*-1;lJMBC4 zN%~@afc86QV+^(zjT`4Ub7s!WcfRve{I%x(Jo?fJY4#QIe-|VB0TB^(AsvbelsMFN zNIP^^pl*>O{FUem$`VCo(U)m}lNGumx+FU8mMN;rMnyJi^NlJ+b=j!NhCAP=QM4i( zb=g>*Z`3JT<3-nHC>{SEBm55GeV*FWaq4YM>|kqqXREI_yw*6n4#y7ddY5*FB;)^wApZ7Kiq`%`P9V2Q|q=fGLj>MvK*tAuQ3ELl;CB4%q@-7U75k zecNZ!#XMx_nSFpY916B~g1!!*g4*(3hi0OEzSx!_;`DrC#ZDVDHkl6{iO61H);Kwc z`zJbub({{fllhH}^QlO0dm|kL)|JI*98D5lGKLSmB-3gIvzrJ1k9Adr z5pyi>RsQ1pokaSEZ{|Yyeu&AO@3SHo9ms}~d`6^JS*)>O6UA||Tq8k$G8kwxOQEIV za%w!qxQ5Hmbga?65!cp2V%!yI4Hw>xNoHjIpU{-fSvnMS9@3imG zC+Umz0ore7V-jpH8aJNtoS8FoX1@6;{#tc^9)0PAH2sSBzk`+i0EvjYpbkX^N*wAs zq#ZghP`5}C{z`NWW{IM*@XOT4%?e!;T@f93%M?{bP!U0GCa6+W7eP$~?o3dlXhj5d z5j19kIz_8|=(_Am$G^uOeh2YBPwd$!_14F>zqz%&ndo(|HHviTy6%yQt<|Y_I`KaC zOt`t5Mn-!FdU!fE1J57!lARTVbcHi9;I}u;o?4YBBpUh$T9A=#uEtAzPrUA_8&1 zZ~F|osE6!&W*^{;fP$^U|Y6zXvW%S!?p|(rx#-@dfJ$g$$aogNcIA|=E*^P zdZJTk$LSzDnOSUJOhhX;d>>acwn>hC1iGJwMh|srd&zs&)h1*ie|&2XD|-T>kq#6@ zfvbe;phzl@C**K$R*SDc1DQrI0HB1fpy$w9N1|!RxIhAfVnl8MAR%bQA?Hvr6q!!? ziZ=p9KTdnevhnA3IW^PxeX&;qBM8#oPzQl^Z%GQ z##r8~{Dt>B$@Cm=#zOFZh|LV|^CCALzy_0iMnyH4tTJI0#d)&aBf;so-`8eZLQA{L zrSTN&#$A4L>5D}Oz3n>QIs0SC;Bw1k*#8)Ry%$jiftJLT%8#oXLC^X@m6lZvs0q+$WN1;#hYvM*U;94)`t;u*D{_DAy= 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/PythonHome/Lib/encodings/utf_32.pyc b/PythonHome/Lib/encodings/utf_32.pyc deleted file mode 100644 index b99fb81dcd2d6154e9933ed576f8ff644f42a6b9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5446 zcmcIoe~%ki6}>Ya+iS<$q)7<7G=M{a7*I<|03i`Uo3xQCTDO`_NxO>V?AqgGcD>_j z=B>g?SqZxN4*`#tyFd+xdSP3_<7?SDOdyfw7) zSHu6e@f80=F*4gm8Q3VaNnqQk_?7^bdD)8efjl@#N#N=H1rbks$~>u4`5)pQbC zfcHRW18i)S!l;0lx{I4!w1#3ZNVC)p22xdjnk9}yQb3Y>wMFPClF2yc@>TT}b8{hp z%PqJP3@I@imE;F#K*l}cd4J9FKhnT}E-cOd$Z!w>+&{RLQFr!YdvlzsdJO0*Frm{Rb$ntphYZsW$5&dvKL2%mt@r7A!X=zANHBgF%0Twg1bYq)(6~c(kSp=+4up0v?AN z{|EYX-+?f9569yqPeu#$UkWeX$-p90A2mFgdfz`ck^X{;i%^J2Ss{kFjokVlsGM?} zzb+7|C={f464|4g9Y=Otw_`xFV$(lpawM>VO@FPSnqWQFkcTyfUbE+lPy2Pt|3V5y zhysOt0e^r1*r9G?M1C(y$-ZD|yqiIrG0c;%B7aJ>r#wsXBNU%JxR2bRi%cNdIp~h2 zNzu)w4(*-Xb)Ti~Y4`3&9}2ed_b`2dsu$Qd`O_@&FLVOV-ULgOTz1kWKgm)C?)R7y z_%J6Qt%zEEF=vwSf{E55|(iNzLpK7$2ju6k`;_eN2a^nlaY@oRkXp zC1Aia(Cc24UJN!Reh~3du5s!<@DtcE`mu#ypg3A$i8QUayqiAppNRN;h5l7jw@%A$gBEGBGJ z2Xh@9Qi@?%`Isj|9_00szoT_^%NnZq_|mlOj+XdHbaHx$D`%EVyene~vUnfMpmc^O zny>F&5;co|jAB`vB>g4b#a;GQ8lH!&n5taW9~4d=U_n6_v+xRZ*9kZ111v)yF`1vo zWM0p&B#o~Xk*;HdxA0UEskM%X^opYew?sn^^VFS{&Hn^562z9%+59{fA)!S$LW&dDL?m zrmS+s(KdM9EYh^T5#Eu2O#SAPe?{JTIu{MRGt(pgOP51b$Q;#e;-gbR5H7}RgtD|U zY5Tn1zb;o!}|if_zgZatr|T6x640%yAZ+gmK7ca}jGx5ry~Lm7U}& zCQtBGnf~QjrXThMjU@+>(z$5<2Gw33n_?P_x-1y4nW(j*1(%4Eoii`Eq}$3RUcfh$ zcF-l@1~s|?4OQJpD6gz`3zbDO@)BIb^;TbVjv3TmLG^kXNg~9(PhDN#y42}0EPb+aT>@zE85*lhA#dgC-OQohuxPTj{E-^PeEs~Q`t`^ z@bo!{wouI#^X*qbH39MrkFw}S*lH5u`cYIt@t3H03&M6V6F3|egys>0k>~=4_-=+& z1s}|C-qD&NyFan!mcnEo!{88HrQ|pMOP9YjQCMAb()ov?@&n6qcX?Hizj+2nHq0*! zj7h%ZnPQSpglQ~&inzxQVDD$+>HLklaK+a#BbIZ}t83LnjHW}}9R(s?YsH3FG44Smh$%CZV2TZrj=DdebZb~~$KO_eM{1F1 UjbI~cg`L{w>zlVXuWnxZFI!-4^Z)<= diff --git a/PythonHome/Lib/encodings/utf_32_be.py b/PythonHome/Lib/encodings/utf_32_be.py new file mode 100644 index 0000000000..fe272b5faf --- /dev/null +++ b/PythonHome/Lib/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/PythonHome/Lib/encodings/utf_32_be.pyc b/PythonHome/Lib/encodings/utf_32_be.pyc deleted file mode 100644 index 863ab3810efd123b1b615ab4a88ee0786bc40e0e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1787 zcmbVM%WB&|6uq+ij?*_3moBo4HpwFCvXm0Hg+MVyE`*wZYHP-+f-MJWObKL{d_=#b zKh_Uu&$)7BlWgipp7H43nLFp6`|$s4w|}2}AH=eJeEh%1$bVrnB16ocn2Jn28G2$p zIj_jj7lU6_ZXm3Rsj0js6YQ+ZjmWjgw_#08Llt#ZG)qN8OiL9_RkTY*Q_PksTB_)j zik6sdehk}$G6)_K;VVq-FPHAeJl)w{xXIq(!QR;J?)2uy#_i-Up1!Mdr^}Mq#T6_$ zsu(?rpJQ?&=bl`NTzTRua_z&q2YEjr6M8(Rz1%&)H*Sdz52CS+AcEM@*4J!d0~&TU zOi6mNaC**W**wbw$V8|7HCFqlpOf*aO>sI&&+^mK;{L^@o+=Etu{Ebn@!T`a$7!6| znN8hj`jKaC7E{TGyN)pO7nm$KLX;{D9fRXbSojmuo!iml_LrEJ-YWr!>ov}K(jBNb z{RA6CX$Z;49Rkz^8`9;1DpHZ#=_KSrshA|`Xu7HYg1bx7$dR2W zn$68(%1>hWG@9l%+`?*g;s3E7HgISgL;0@Xx0VhAn9jy(ihMtBx zHBE61w7JG0XyIUA8v(O3=V#fBltu-tRh+Dx!m|GM4)F=lU zC9O-|*kg}6PABu#jhfdX{R`=Q$lz>Bn`1$pSpYdh@5wIN!E!c2@mgMe?G3mQjIb`v zJdUCw=gU-54iu4N+dk3?ux72TEz7I`Osoa!E>;_(=CyB&_VA89Pa)U6PPJ9(_}yyP H$6NaceP>81 diff --git a/PythonHome/Lib/encodings/utf_32_le.py b/PythonHome/Lib/encodings/utf_32_le.py new file mode 100644 index 0000000000..9e48210928 --- /dev/null +++ b/PythonHome/Lib/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/PythonHome/Lib/encodings/utf_32_le.pyc b/PythonHome/Lib/encodings/utf_32_le.pyc deleted file mode 100644 index bc56ccc15052d9e71846eacd307f3e823615c4bf..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1787 zcmbVM%WB(D5FJ^5$LSl2OBdNin`Du6SxSl9LZFx;7eY-yb)>6QMwWwgO$lU|d_=#b zKh_Uu&lx$gNj7yP-|^MVow+k-9`2v*?(dWDqfnNQi~sjn#V?RZWDM#^RFl+^u_MNj zX-&qiMEKR^2F$ud4dpi^#>uAKh+K<&8#g3ssi3KXb|q*@)KNiO1>H)}mS{@_9ToH{ zK}Vu(evG?xW#m1ghp#}oUoP#BdA75=u<_pE!Cq>1cLwvwgx%yXo}q2>q|KAihBa)t z>R1D^pMzMDsUue+SB}`4T)VLDfIswzgsO+MSJ)@`#x23&L6DjNEU+zYea#ofqhZ?s zNwSNDRXvmE^StoD6D7rK?DkJTCugT7gLaag7pIlQ{fkT0Dh+pWw4hCK>@(2gEX>W! zWOkB%q^`+B3i~C}39^h{0YF}_q31|{q|po$ z91w-UCn9$M&=8EzkV~itMPbs|=SHE3lWdZ18h>e56I{mcsl7Ig20=ENnIN!4CkSTq zXn{-wde^5(S{Q!|g4Kophq~W_(l(aj-MokQ2hH>fZ(^Z%KgFiPd+M?i05+K75f#5j zLc;3eFaBZ1QCZZS3x2nBdj7?(&+E&CO(Xk|%bpFdph?8wMYSB;8^a-gnJ6 zll7W?sB6T~XG?F48k>j}zjUqY9-^u3@CKW*9m;u!0f%`I)x~1cH3XfG(S}mPOhcbW zZLuwkxz@<*Kyj#pfYn*>vl>PUqdKfzoUFRIEc5&>yX^klGN~9_NGcYPTVwpxEPI+I z?MvP`;EX!X;`!=Et!tn0`3&A?ayEs{vZ2lm9687A$uBv<3JyYXI!<%#^>`47urH%| z7zAa_SEZyFs7ID#`$#*$L~CPh*=D7~^tJT5kKM*z^V+xNczDN|r!F_0UcFQ6x&3OCzL?%+K2E- zd@&zDzi&1sK?O;ZoXI&eXXea&^W*;5ZGJ!bGKggPaq)kEm45??MTVe`#3dO!GIYc^ za#50@D=~g$xdF2*aYgwR8R2GCZbYs{J`XDr*HlndL475tN!(CDT?NgRpf2%_3K}YC ztpp8;cX=2#>B_*nLl2KYIv*DH>oo1`&F$#r{$8gyjZM^So@9x&CheRpI)_;jrk#)T zBpu`5JLB;nzcj{%vspKqPF{4I$xnRxwo0ouOClSUu;nUa^~in*Vnr?-xe~c@#FpgR zg(nX9eUGTAdc^m0+rk+h1^WSxU|HJvl+BGtqqYK)q_eqI9g}6#Ecd_@CHYhAx~K1x zvs05oJ4w&;Q?=HeEmWg0x`S&u?TKR_fF7q&W+o=J;rJc(Ocqhd4{se}<&QuNa6~3c zOfM7YieJPLF^u1<$Lmi(mQicq$o)0+9BB_Ul74~-a;CtT~t{*Sa@gMtUwF@mtO88e_(<7~jWch4F>U4gtVmibrpJ7Kgt}LKUCZE#C>w=A)6xmL;>5tAvCl zps>JIJ~6PF2`B7?jY7DslXV!}9zi1U_@8e1Cfuyg+qy;Ue75aYXb~y)*b=Q(mk>oQ z`&ZZ$Wnaub3_J9DTo#L|R}pkG#vDou^9}tN*TvQ_@@fOG0mZ&HJF78gx^*xqbn2*f zYO?OsqNKAw*+qwEnn;W!BoYgVZ7?o1vz}&#_*p*Qa@y@Qp;_Z+b+J9UymzEd;kCd diff --git a/PythonHome/Lib/encodings/utf_8.py b/PythonHome/Lib/encodings/utf_8.py new file mode 100644 index 0000000000..1bf6336571 --- /dev/null +++ b/PythonHome/Lib/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/PythonHome/Lib/encodings/utf_8.pyc b/PythonHome/Lib/encodings/utf_8.pyc index 25fd323f06f04de54a1aa50205cd86c14afb470b..c0be188f0184cebb5edd85b74429d7387840038c 100644 GIT binary patch delta 468 zcmZqUpC-8B0;8b|0|P^On82Uo>#EHUr>N^jDKlKL1{^hOKMVSdQ3oN zNk)F2M}BVV 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/PythonHome/Lib/encodings/utf_8_sig.pyc b/PythonHome/Lib/encodings/utf_8_sig.pyc deleted file mode 100644 index dd0160d89b9bb8a9b17fad17387549848e41ba4d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4725 zcmd5=TW=Fb6h31+acmqKpaKGvY#&S_jdhNXGGwlTDm;x;s`H zi9CfD-umADj{dR!fcE>&*lRb02Ir|kGtAD;GMWg27g8T{|#F9 zJGw~Z8G0j8LApksVNjH)Brh>8=y*!Un4A`CWV0k4tSQS&kpq#RpOqw<(HB$tqLROu zmZ+*P%KG9|{-P{VO<&CDi`o3ej6|pT@T@{<8ufQ5p^>?m8{$B z^J?|u;87CTq}_`!e``059pASGTlIyFg1e7?#4+7&ux5ju)b7|MvXQQKHVIl8kFN$n zCr&emacXU_w&!eib8rD9^cSSI#fyTt<0U%0A!w!csN1h|dB!{R++3J!E8f|$(amc7 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 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, IOError): + 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/PythonHome/Lib/filecmp.pyc b/PythonHome/Lib/filecmp.pyc deleted file mode 100644 index e1584518cb8ea9edc1af96e750c099e9b641344b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 9322 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 diff --git a/PythonHome/Lib/fileinput.py b/PythonHome/Lib/fileinput.py new file mode 100644 index 0000000000..21c2d1f9bb --- /dev/null +++ b/PythonHome/Lib/fileinput.py @@ -0,0 +1,413 @@ +"""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="." 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): + """Return an instance of the FileInput class, which can be iterated. + + The parameters are passed to the constructor of the FileInput class. + The returned instance, in addition to being an iterator, + keeps global state for the functions of this module,. + """ + 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: + """FileInput([files[, inplace[, backup[, bufsize[, 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 = '' + 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 OSError: + 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 io + def openhook(filename, mode): + mode = mode.replace('U', '').replace('b', '') or 'r' + return io.open(filename, mode, encoding=encoding, newline='') + 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/PythonHome/Lib/fileinput.pyc b/PythonHome/Lib/fileinput.pyc deleted file mode 100644 index 7e70114d95fcc598334c3c97dd2da2f833bfb17b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 14415 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 rcI5-~vsckf)Sj= _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/PythonHome/Lib/fnmatch.pyc b/PythonHome/Lib/fnmatch.pyc deleted file mode 100644 index e6db6c7f467a1e65900b313b7ee6da57e2a8ef9e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3504 zcma)8TW=dh6h6C7oY=WGy(B?JomQ%FqSg<6pimV`D5R3ociKy)+7B*}^XS16Gtjnmhqch)X^`xh4<|iiht?UhsEd$yG(H*PlK=t-lnw%+OGDmvY4SD%BR;f=`+_^(tH zvGD_RiU=S&cIn7vd-u>FdhXCM4UOO&7;(s!c=iZg#yG1pzv0ju+F13hrQzpH^#MG9 zZQljes>0`C0eR(TT0Kgl!y*)n?Zx_5F0;&n_((*+WBRGia9E&ERNTpD2h)DiQwEbU zP}cG@KY$BGaLed}?IArZIFMlIV?GzWoJ;mM>dKqpx)+>!PM$Bo9K4JJT~(w-G)E z-3S-NVeJ0=8BF+NHN3XB892<`n*%67TCH!k6s;NTV7tJ2Y^NI@*yL*#7!AuJXcVjDiq3NAri7KiZN?yHz=R6j?j$*EG%Uy8F zfYBtrbIz1=0cFOWLT?`Rf^#kh7@v=e04zj<0Yd_q2V|W-U|c>a#u+g1H~@1~_#6-d zpEEQ@X-_c05~4)_Bdx_fAVSsxvHO)i_kWMwPDPa0z$ro8l?=v#hn&cSw}Gfu`1uNK z$T^l>-+whMfqtW)B?*ps;8jM+3B_V)_-VC>9xnlPq z9EjG^L<6NyZW4Nr{A#CNRy z7!-nEzQ@mO1-grP1hP)_@gOW==_mmbCxU+r1gj#5{;=TT@{sJ`!?GpH&>zSi{E6_- zw+8|j96rKCZs`xjc`Q(WQCFC2tP|rp3&j z12tG9lc3%iz8dtKE?p?Dt;BJ`d@Ed9T;^l8YnJBMYm5@pM72@87d6nDzjTX70KZ%Z z@5P~q+W_MluL4PMf}+OT8^ZjV;3~8hNK7GhZ6!rmJS_s@XP-#l~jsPTMR=dX(@G?#py1_5&>eB5bBj z;CFP5S4d2VvPkO0{do9=PMT~)Bgg?(+$f2 diff --git a/PythonHome/Lib/formatter.py b/PythonHome/Lib/formatter.py new file mode 100644 index 0000000000..e0a8fe10b2 --- /dev/null +++ b/PythonHome/Lib/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/PythonHome/Lib/formatter.pyc b/PythonHome/Lib/formatter.pyc deleted file mode 100644 index 29813be42d8c1b177aa5fa7064616cc025e36a1e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 18023 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 diff --git a/PythonHome/Lib/fpformat.py b/PythonHome/Lib/fpformat.py new file mode 100644 index 0000000000..71cbb25f3c --- /dev/null +++ b/PythonHome/Lib/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/PythonHome/Lib/fpformat.pyc b/PythonHome/Lib/fpformat.pyc deleted file mode 100644 index 046091a736044e7bc089bdab2df89ec8c05dd066..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4551 zcmb7HUvC@75uZI$lt}%xteBD!)C;MHC_2)_v4)=<-alf-^F9Ugb0cDAQgokbrf|y+Ve;mkHP|lMGD90g;HuC?@%dG zr$Boc7^iT8!ZID%xFrtpe1W+4Wr*@T(^0p#+-^3;j zI=a8)VYa>c`D2N@82DRPGPko0V2Hs14S17#&5KZ5*28C=ORD zwi&&ox3U#9k98Kbjn#pU``ts6>Lf+mW+^Wk#NoMtR&G@XP*0EgT@z=#`oka%x+XKJ z-K-2Y_4!|JGfVWL8E)Q$?_5|UHP&j>^O<_ zoAr&X!uOE{&34B;Go8r8>vmRvgq!6bjuoZtB>UmEIMA+R_~*6#_0`9BRyJVh~ex;Lso4x z+%XyrrzNT^>=lUm!H=WEgW-wmy%WEP-f!?Qn=2{Ha2t)E9ihn^8OOuXbq|mIBSc2@ zMA36ZfTB}05D*j8o}hG@;0pBr!lRhD{|RDEg3!g?iy|Eq>C~gs0-d5UM$Zv~W7PI2 z{g`o&A)Z*I)Uw3f8_?sfF-m_&873ek(aS5BC@yi(q5(6{v2u}~m#9@l_>_6Ce}nK% z)=y(yv(Zt!hC9uAL7J`URvJjmtZ6goB`XZWG>EJL(9zR0Jr1bN3L}_j>d5Nl)n!&& zUSF2(+!T*&aDO*R0YM2i;OHodW5)3(QFhFMlf<8zG?9tJrC&Bv6nIBGh^=4|b7azp zuR$;uG2|k?y^Q--aTR!Hv0W=cW_(!)gd{X6yhQ|(XdY)gVLOS9+`IH2rAfahz{MIh zo+SpYbRiIB3Ljl8=7$yB4fiht*eg3!w0YlW=zBTv@<|!H{|zi^7a^!LtEOm5-GnTw z5>4Z|s!FQKhvh@?_V3}bUqCQq6t#hopE44GG6sX-4sDF;s{6m;os!^Fz`+wfXK*4V zIJhh>RH5+nbBcF|Mu~OUsKYk!B5$w}aEae;LZ6l_-P;JxJm zk$e{W7KAVSB8=`axKn=md)npQjkzU2HQd4_ z4RK%UKRw_QY=8Z67>0E`F5fKky)6%uQP4s`CYW)B5$7~1=Q7-`5*!XVW<`*?zBw6k$zR7nnJ~3G_HA2_EWsK9W>*(ldgm)bvvSHK<4) z@~?C24G5RIc<#Wz!JTs~F0$HX`0^PXDEi5AT|>o1npFk$I=E{L@L5z#1ZW|>OwpVY zAaQ_<)Wde`?4J4+7m!SxkWK>H6v zZMN&tYDbX?g_cNHJxX9GJOg6M$q;5&py>K)475P#*7MoR5Vp zIu0{J#7vx=WEE=6yf?-NReAWr)+?}%2|Kk(zW+Z#d_6okIJWjzB~bpKATa|JDxH%{ zVgxba!sINJ(A7p2DUrr}?Y`PB4<7k!@o(Y?QtC-8t^1?;%t)!`e-q>WEfx|@BR=m2 z0|_X2k|;Q|j?|Y~@l|o<&+zC9#HA6&MxWrZ--U1ywg`G&651}Q*VMFE_7?Cyi+G#& zuBjUsnW8Ido(UXfT}3r{=8(qkp=}>QoV-JW?=X=&{${Fml^Z^P9gRB#zwcr%e|hk< z. + +"""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[-+]?) # an optional sign, then + (?=\d|\.\d) # lookahead for digit or .digit + (?P\d*) # numerator (possibly empty) + (?: # followed by + (?:/(?P\d+))? # an optional denominator + | # or + (?:\.(?P\d*))? # an optional fractional part + (?:E(?P[-+]?\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/PythonHome/Lib/fractions.pyc b/PythonHome/Lib/fractions.pyc deleted file mode 100644 index 0b31d4bd129f3917718195db445ea34d9847ed28..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 19148 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 diff --git a/PythonHome/Lib/ftplib.py b/PythonHome/Lib/ftplib.py new file mode 100644 index 0000000000..c98290ce85 --- /dev/null +++ b/PythonHome/Lib/ftplib.py @@ -0,0 +1,1061 @@ +"""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 +MSG_OOB = 0x1 # Process data out of band + + +# The standard FTP server control port +FTP_PORT = 21 +# The sizehint parameter passed to readline() calls +MAXLINE = 8192 + + +# 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 + maxline = MAXLINE + 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(self.maxline + 1) + if len(line) > self.maxline: + raise Error("got more than %d bytes" % self.maxline) + 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(self.maxline + 1) + if len(line) > self.maxline: + raise Error("got more than %d bytes" % self.maxline) + 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 + 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 + 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(self.maxline + 1) + if len(buf) > self.maxline: + raise Error("got more than %d bytes" % self.maxline) + 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 +except ImportError: + 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(self.maxline + 1) + if len(line) > self.maxline: + raise Error("got more than %d bytes" % self.maxline) + 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(self.maxline + 1) + if len(buf) > self.maxline: + raise Error("got more than %d bytes" % self.maxline) + 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(self.maxline + 1) + if len(line) > self.maxline: + raise Error("got more than %d bytes" % self.maxline) + 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/PythonHome/Lib/ftplib.pyc b/PythonHome/Lib/ftplib.pyc deleted file mode 100644 index b68200ee3cf1a7213a7765eaf16c5552b8f382ee..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 33147 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 UJ-d2#_jC +# 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/PythonHome/Lib/functools.pyc b/PythonHome/Lib/functools.pyc index 118bab5ab1239ae6a4b8feddc20ac287ff885d9e..6c64a1bc9b444ccca1c94fff76cb7adfa7e38422 100644 GIT binary patch delta 1532 zcmX@Ex7&1s1dE{^0|SGrRZMzjNk(Z>On82Uo>#EHUr>N^jDKlKL1{^hOKMVSdQ3oN zNk)F2M}BVVW_1>8CNi`YvfX85WS;EL5lFh`$?G|+fqGwaxRasRk+Xm-U1F23amoU1 z{le)%o_=9#VAvJ|F+(yFkN{!k$t7H5nl||%mp^&#m>kM21oTG+H@P-n1?zvoOL*T^lfah)w1ZtR_R} zG{F`!bZH8aqic^)7a4Yi3X@~k3$k?W5t5iZS)_&xSAt@|L^PKSof||G$j~J(_J9ms M>p8?HtBNZD0Nwot)Bpeg delta 652 zcmdmOdR%XV1Pi|m0|SGzRZKu-Nk)F2k@;p%7HcL9!L4j}87KeY zOlLO_Hk}$Eb2)`4>++gl)xUxlySa9J5OY1S>Usc`6`jn%Z;Vw%6F+uyB?NAwtKY07 zc$g7gaI%hs#AH3;N(}KE!YvqLy&{-mPNH2H>i&vis@o)nDV8oi1w*fnL^Foi1BnC- Nu|mlQ7-CIQmH?!hx6A+l diff --git a/PythonHome/Lib/genericpath.py b/PythonHome/Lib/genericpath.py new file mode 100644 index 0000000000..7ddb94c08b --- /dev/null +++ b/PythonHome/Lib/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 on 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/PythonHome/Lib/genericpath.pyc b/PythonHome/Lib/genericpath.pyc index 8cad3dcebc00365a6167d6ef57739af99219af82..311bf12b231f1115ae802391189b3914cd8df960 100644 GIT binary patch delta 577 zcmeB`d?>wPI+LLT0|SGrRZMzjNk(Z>On82Uo>#EHUr>N^jDKlKL1{^hOKMVSdQ3oN zNk)F2M}BVVWC0G5$-9`Ikg4+^^Jg-3UT4`rrp{HYo5|GKz_yl5odN6{N!PhqfWwxN YbZww0*<8RWMow%_. +# +# Gerrit Holl moved the string-based exceptions +# to class-based exceptions. +# +# Peter Astrand 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/PythonHome/Lib/getopt.pyc b/PythonHome/Lib/getopt.pyc deleted file mode 100644 index 24607cd840b00997e3b62e30ff00e570e98f4707..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6604 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 diff --git a/PythonHome/Lib/getpass.py b/PythonHome/Lib/getpass.py new file mode 100644 index 0000000000..2ac6fd7f38 --- /dev/null +++ b/PythonHome/Lib/getpass.py @@ -0,0 +1,179 @@ +"""Utilities to get a password and/or the current user name. + +getpass(prompt[, stream]) - Prompt for a password, with echo turned off. +getuser() - Get the user name from the environment or password database. + +GetPassWarning - This UserWarning is issued when getpass() cannot prevent + echoing of the password contents while reading. + +On Windows, the msvcrt module will be used. +On the Mac EasyDialogs.AskPassword is used, if available. + +""" + +# Authors: Piers Lauder (original) +# Guido van Rossum (Windows support and cleanup) +# Gregory P. Smith (tty support & GetPassWarning) + +import os, sys, warnings + +__all__ = ["getpass","getuser","GetPassWarning"] + + +class GetPassWarning(UserWarning): pass + + +def unix_getpass(prompt='Password: ', stream=None): + """Prompt for a password, with echo turned off. + + Args: + prompt: Written on stream to ask for the input. Default: 'Password: ' + stream: A writable file object to display the prompt. Defaults to + the tty. If no tty is available defaults to sys.stderr. + Returns: + The seKr3t input. + Raises: + EOFError: If our input tty or stdin was closed. + GetPassWarning: When we were unable to turn echo off on the input. + + Always restores terminal settings before returning. + """ + fd = None + tty = None + try: + # Always try reading and writing directly on the tty first. + fd = os.open('/dev/tty', os.O_RDWR|os.O_NOCTTY) + tty = os.fdopen(fd, 'w+', 1) + input = tty + if not stream: + stream = tty + except EnvironmentError, e: + # If that fails, see if stdin can be controlled. + try: + fd = sys.stdin.fileno() + except (AttributeError, ValueError): + passwd = fallback_getpass(prompt, stream) + input = sys.stdin + if not stream: + stream = sys.stderr + + if fd is not None: + passwd = None + try: + old = termios.tcgetattr(fd) # a copy to save + new = old[:] + new[3] &= ~termios.ECHO # 3 == 'lflags' + tcsetattr_flags = termios.TCSAFLUSH + if hasattr(termios, 'TCSASOFT'): + tcsetattr_flags |= termios.TCSASOFT + try: + termios.tcsetattr(fd, tcsetattr_flags, new) + passwd = _raw_input(prompt, stream, input=input) + finally: + termios.tcsetattr(fd, tcsetattr_flags, old) + stream.flush() # issue7208 + except termios.error, e: + if passwd is not None: + # _raw_input succeeded. The final tcsetattr failed. Reraise + # instead of leaving the terminal in an unknown state. + raise + # We can't control the tty or stdin. Give up and use normal IO. + # fallback_getpass() raises an appropriate warning. + del input, tty # clean up unused file objects before blocking + passwd = fallback_getpass(prompt, stream) + + 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 fallback_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 fallback_getpass(prompt='Password: ', stream=None): + warnings.warn("Can not control echo on the terminal.", GetPassWarning, + stacklevel=2) + if not stream: + stream = sys.stderr + print >>stream, "Warning: Password input may be echoed." + return _raw_input(prompt, stream) + + +def _raw_input(prompt="", stream=None, input=None): + # A raw_input() replacement that doesn't save the string in the + # GNU readline history. + if not stream: + stream = sys.stderr + if not input: + input = sys.stdin + prompt = str(prompt) + if prompt: + stream.write(prompt) + stream.flush() + # NOTE: The Python C API calls flockfile() (and unlock) during readline. + line = input.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. + + """ + + import os + + 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: + getpass = fallback_getpass + else: + getpass = AskPassword + else: + getpass = win_getpass +else: + getpass = unix_getpass diff --git a/PythonHome/Lib/getpass.pyc b/PythonHome/Lib/getpass.pyc deleted file mode 100644 index 6d70489b664f3fbfffb9315b08fb996eda30ece6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4708 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 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('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 applications + # 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/PythonHome/Lib/gettext.pyc b/PythonHome/Lib/gettext.pyc deleted file mode 100644 index 1dd946812634b40e93433084494070092adc8217..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 15309 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 OeVovZID>hdF!2A>welVS diff --git a/PythonHome/Lib/glob.py b/PythonHome/Lib/glob.py new file mode 100644 index 0000000000..f34534b53c --- /dev/null +++ b/PythonHome/Lib/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/PythonHome/Lib/glob.pyc b/PythonHome/Lib/glob.pyc deleted file mode 100644 index 6ca6f81690ec541c2cae9456f3c04a81aa6e2115..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2857 zcmd^BUvC>l5TCtsoSfq{B~|Gk3A#v>SfxaOkdRQ-q6QET5LM?wikotr?>6>1=R5ay zO=2k#59wFnBk&0jedbf}MR-Mm-^^W8c&YNv**l)wot>ROznQiF=UV6a?hpNhnr8{W zpJLeOASuxRR8i_tu4n+J<~2hDsVmG#W8oOl7&c`w#0l|thRk79SXgm+chL?B-(hHrGg^RO7+iW_^jkaTx=kHm! z0DqX}X%bhdxithnXAedVg9v z9alJJW|Azv$SLzgTEI9}vGZG-l z8png(f0?FNX2{3p4Gu16hyqDR8yqJn!LWaUARTos>@CjA#G{Gd%vA3%^Q|hRhWgEF zt6AOi=tR+pN5_h6K}R)obsCfFAc2RqM$U^0TPu0(IvOs|O zWmW??oV2J2m>&tx)Q`2OvP4Cj5e(+&4js2}$VY6((YtiK#M@pReVvbPEEat* z12(~uKWO*q@3l1&YZ-tNt2OnyO4wg6B`%w74Eq}hP;56C!V};WmcewX1Sc@7zL8fEGE{VpKrovELyTxT{@hO4aLO<~>G$QIh0@P7Y*Kl8OG5tblslMa^z*B0L_?EFp!!lgm9B`twD_OXv)FMzsj9LPWI_ijUQTKHy*M1oRmIzy1})nd zfcAV2hwR#Y40{!X0I#mP0kCZ-UtLlc)e^?#8eANF&dfH3eF#z~_rN27x`r6qGP1&b z@IliY`^DKB8lB*9A`q){{U1?AjP$x42qNl?TlXG6`48g6;Y(Pm?XNvdaX$pGml3ujxsXbi z-V-HblN?Citcj~+EG=ZGEKGe#@}BeNhjaTq%d@MbdhDmbAd1p5iK3AIfk~94<5ecq zJaLT)M%@*60Eo}euv88wCUK3DIM1Pk5i4y^@DOr@WIZXTGoUxT$?I&&%Mc6qsyNrR lRR3qYD=xnY1#Pbjh~eY;s-xEY>web@R)d?tg`m6c{R3?5P2>Oo diff --git a/PythonHome/Lib/gzip.py b/PythonHome/Lib/gzip.py new file mode 100644 index 0000000000..a613bae876 --- /dev/null +++ b/PythonHome/Lib/gzip.py @@ -0,0 +1,518 @@ +"""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("' + + 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 + + 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() + + 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 xrange(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 xrange(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/PythonHome/Lib/gzip.pyc b/PythonHome/Lib/gzip.pyc deleted file mode 100644 index 402a1fdb459955ec2acc05ee6dd11d4a0df977fd..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 14921 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
-jvplK0#q#Pdh8qrS?kH)lGM9x8rT| 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 o^*Zu7(L6gvFeSeYx82{5eQ+}PKSm~&@Bjb+ diff --git a/PythonHome/Lib/hashlib.py b/PythonHome/Lib/hashlib.py new file mode 100644 index 0000000000..6d69ad2c84 --- /dev/null +++ b/PythonHome/Lib/hashlib.py @@ -0,0 +1,213 @@ +# $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', 'pbkdf2_hmac') + + +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) + + +try: + # OpenSSL's PKCS5_PBKDF2_HMAC requires OpenSSL 1.0+ with HMAC and SHA + from _hashlib import pbkdf2_hmac +except ImportError: + import binascii + import struct + + _trans_5C = b"".join(chr(x ^ 0x5C) for x in range(256)) + _trans_36 = b"".join(chr(x ^ 0x36) for x in range(256)) + + def pbkdf2_hmac(hash_name, password, salt, iterations, dklen=None): + """Password based key derivation function 2 (PKCS #5 v2.0) + + This Python implementations based on the hmac module about as fast + as OpenSSL's PKCS5_PBKDF2_HMAC for short passwords and much faster + for long passwords. + """ + if not isinstance(hash_name, str): + raise TypeError(hash_name) + + if not isinstance(password, (bytes, bytearray)): + password = bytes(buffer(password)) + if not isinstance(salt, (bytes, bytearray)): + salt = bytes(buffer(salt)) + + # Fast inline HMAC implementation + inner = new(hash_name) + outer = new(hash_name) + blocksize = getattr(inner, 'block_size', 64) + if len(password) > blocksize: + password = new(hash_name, password).digest() + password = password + b'\x00' * (blocksize - len(password)) + inner.update(password.translate(_trans_36)) + outer.update(password.translate(_trans_5C)) + + def prf(msg, inner=inner, outer=outer): + # PBKDF2_HMAC uses the password as key. We can re-use the same + # digest objects and and just update copies to skip initialization. + icpy = inner.copy() + ocpy = outer.copy() + icpy.update(msg) + ocpy.update(icpy.digest()) + return ocpy.digest() + + if iterations < 1: + raise ValueError(iterations) + if dklen is None: + dklen = outer.digest_size + if dklen < 1: + raise ValueError(dklen) + + hex_format_string = "%%0%ix" % (new(hash_name).digest_size * 2) + + dkey = b'' + loop = 1 + while len(dkey) < dklen: + prev = prf(salt + struct.pack(b'>I', loop)) + rkey = int(binascii.hexlify(prev), 16) + for i in xrange(iterations - 1): + prev = prf(prev) + rkey ^= int(binascii.hexlify(prev), 16) + loop += 1 + dkey += binascii.unhexlify(hex_format_string % rkey) + + return dkey[:dklen] + +# Cleanup locals() +del __always_supported, __func_name, __get_hash +del __py_new, __hash_new, __get_openssl_constructor diff --git a/PythonHome/Lib/hashlib.pyc b/PythonHome/Lib/hashlib.pyc index c81eee727cfeb1891d9b634703cc158b42213ce6..bc842302f90d46c28cb486fcd73555df72bd00f7 100644 GIT binary patch delta 503 zcmexmyvA&UDUYEI0|P^On82Uo>#EHUr>N^jDKlKL1{^hOKMVSdQ3oN zNk)F2M}BVV292SOkg7Ex;Cc?MzD~f W?X2i8GJLlAn)ntnv`wBVnFs(CY_WL& delta 201 zcmZ2u_RDyKDG$FC0|SGzRZKu-Nk)F2k@@B{9vwyu!Na_=n1X`*1{i{qiv-T1>z-U7 mI1!7O>}G! 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 + _len = len + + 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 _len(h) > 1: + try: + while 1: + v, itnum, next = s = h[0] + yield v + s[0] = next() # raises StopIteration when exhausted + _heapreplace(h, s) # restore heap condition + except _StopIteration: + _heappop(h) # remove empty iterator + if h: + # fast case when only a single iterator remains + v, itnum, next = h[0] + yield v + for v in next.__self__: + yield v + +# 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/PythonHome/Lib/heapq.pyc b/PythonHome/Lib/heapq.pyc index ff1774440caa8ab47fdd231c2e17dbe45831085e..b1c1f0ab064bfe1d1a1eb311f7ba27f2e8229c22 100644 GIT binary patch delta 1025 zcmeAwd{??*s+6G>0|P^On82Uo>#EHUr>N^jDKlKL1{^hOKMVSdQ3oN zNk)F2M}BVVlP^~0K+X^)?GPF%Tt8M`doAp{rlQT3< zlMyyfniAw#o2li>$hvvGmKhnEH-FJqXCcF>S_a(Aq-$I3VoZjv&B12d$?)1_NsB@N DAY5Yh delta 409 zcmaD?+Eut=suaHj0|SGzRZKu-Nk)F2k@@6fQeV-e)>;(;02u;uuK)l5 diff --git a/PythonHome/Lib/hmac.py b/PythonHome/Lib/hmac.py new file mode 100644 index 0000000000..9cd1a9fd91 --- /dev/null +++ b/PythonHome/Lib/hmac.py @@ -0,0 +1,136 @@ +"""HMAC (Keyed-Hashing for Message Authentication) Python module. + +Implements the HMAC algorithm as described by RFC 2104. +""" + +import warnings as _warnings + +from operator import _compare_digest as compare_digest + + +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/PythonHome/Lib/hmac.pyc b/PythonHome/Lib/hmac.pyc deleted file mode 100644 index 1d6315aae08568033421895e6492e88bdf46eb5d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4392 zcma)9Yi}FJ6`kcvA}vLZUvZE&9kg*n1q#t9b{@77L{%EZNFoa>H)#mBi{b8&9BLoT z&eAdqyI&Oa@jLpVf1$srUkmhWd+wcGlCo7hqINhtd*|-Vx#ylctp9tnGuW|5p(y`a z`2G}^{U@48h(20RL^Tn6qF>{FUBq>fG(^8Cyr>~2Ein>8uZgHBPCfD2@2`pey3lQ* z*G1G4dl>seO?-cg9`-xpWi!?mGe$h)0=>MyN$=>tA|m+2NL&0M#HkS9^|$CT{ddF< zu)9e8qwWUn;4zvnzTVrH-7ocANAG^2?AW9uIm~kTwYFA`wA`B&W1SWzRE5dXZFx8^ z##t(pESkl-*Xi6#rm;?7VI>SDyHoKf%S|y(q_Q&7Hq6aHM{+Qi{^$F0_q|`;>~+k4 z@psVmu!Ld@O%P_uROLE|%t+g!z>qKkkIh5seSoHDprIEmVo}GyuW{K!G#dLyAkcCY z`gO(vaMXC?O%c@zlzxj4rVa;$IvfV-v_-VWk2=CX>bA-ApU_mRcDoB>Wo=K&z1U`w zRvjB{>b`?bocZ5w8%!envP8<33vJVEDZ@_ zE4zokIh4CMKiuxI7xO8W5H`>d^_sY7+x8#8=7}c&)bYB=5mrwe{gt^$_cuA@o``GW zX+t~#3G3o-LZpl$nbpN0f3m%j)x1c*)XXRjQ`(+PO%%vv7~CArFo~cJIxI@U5NVF}{5E~#4_#&pB^LTfp)oO~n&OP4OzfzdaW6H6QL!}XbXF|p(ySe6 zhH{!`k4&T^M=YA}vJKgMTke%fT``uFpkyN0{?2{>9j0UT*7AFg*A$xpQX#cPJ_`$| zN3M%mo{|T*)pOUq;^{LzRI`|pB&+=OlIYfQod>KJ#X6WD1fh!KAn-{$LTc!$;kt~= zZlVFHCrns`?T9s|RGK;-0(vJqG%a#nO7#U4UEDZ7y@y|!!NYN)!rpYwFTWeBWDu!O zcFBb7KujS9aTXp2*8EYMi}c|3nK79S<&8*MtrOZ{CT)TZ+>tX&0A;fr8p+#thCM@j zv3JoNWOC_Rs-l39&cGiC@W?#UX&Jtf5qIRCwX=kr-iUez^F{Y6n&JwY!0HfD2?i=W zj8Z0PAh+{z*0sCr<-dbG1n8OD;jWCl6WmrkhJ(H&Bt=JF}KE87k;_b@sNGf?s=njXMciIv0^B2o+_BMn0xR??_TE_@=X|2i6X`%}988QtP? z&GXx4`y)KJ1n>k?767hj@uEV6vph$(fipmM1-%ClAPu2H>B-V~ zj=F-J2TJJjfybq0cU!6y#YsP|?w5?~l2kAzKJAfN)-=OAf2>iD&_M!-|eF7s(r%|y6 z?W#)ekH-B=O#I3m>#}rpw|68;T6thtffG>xpH!qngKA0E2FC+~+N0IV`Na{4Hp3~p zq#$pSh3%!g`Xy#lhPYkTH@t%`RRhPjAXSMD0xt7G;C}YtmP8>4qAY|OkX-w84Dcm2 zq^pkW3yghw#S&TWouja{W(tWVL1{HwUaPistKDpGwA<}YSjQk;g#A7)wknwA$aFe! z)+=&Hb66I0&|;Xw_@nq_&rp*XCkla&37f!)9geJHRh@uX_TvcUZxm@|BSct z1VzMf8sFV!uZhNQ)M$rAiE>BTe3LMQ65E2POYfHIhv=id~lb7!Z6=dggaBd7Wec zhQ#nOPCp}!>Wi*_9j*TcH9w(-3CgeI>c#m%lb37$KeXhP-F3|Wgl0H;);4Mv>$~1= Lqt$HHE)V|)+M&W& diff --git a/PythonHome/Lib/hotshot/__init__.py b/PythonHome/Lib/hotshot/__init__.py new file mode 100644 index 0000000000..1556ab3f2b --- /dev/null +++ b/PythonHome/Lib/hotshot/__init__.py @@ -0,0 +1,78 @@ +"""High-perfomance logging profiler, mostly written in C.""" + +import _hotshot +from _hotshot import ProfilerError + +from warnings import warnpy3k as _warnpy3k +_warnpy3k("The 'hotshot' module is not supported in 3.x, " + "use the 'profile' module instead.", stacklevel=2) + +class Profile: + def __init__(self, logfn, lineevents=0, linetimings=1): + self.lineevents = lineevents and 1 or 0 + self.linetimings = (linetimings and lineevents) and 1 or 0 + self._prof = p = _hotshot.profiler( + logfn, self.lineevents, self.linetimings) + + # Attempt to avoid confusing results caused by the presence of + # Python wrappers around these functions, but only if we can + # be sure the methods have not been overridden or extended. + if self.__class__ is Profile: + self.close = p.close + self.start = p.start + self.stop = p.stop + self.addinfo = p.addinfo + + def close(self): + """Close the logfile and terminate the profiler.""" + self._prof.close() + + def fileno(self): + """Return the file descriptor of the profiler's log file.""" + return self._prof.fileno() + + def start(self): + """Start the profiler.""" + self._prof.start() + + def stop(self): + """Stop the profiler.""" + self._prof.stop() + + def addinfo(self, key, value): + """Add an arbitrary labelled value to the profile log.""" + self._prof.addinfo(key, value) + + # These methods offer the same interface as the profile.Profile class, + # but delegate most of the work to the C implementation underneath. + + def run(self, cmd): + """Profile an exec-compatible string in the script + environment. + + The globals from the __main__ module are used as both the + globals and locals for the script. + """ + import __main__ + dict = __main__.__dict__ + return self.runctx(cmd, dict, dict) + + def runctx(self, cmd, globals, locals): + """Evaluate an exec-compatible string in a specific + environment. + + The string is compiled before profiling begins. + """ + code = compile(cmd, "", "exec") + self._prof.runcode(code, globals, locals) + return self + + def runcall(self, func, *args, **kw): + """Profile a single call of a callable. + + Additional positional and keyword arguments may be passed + along; the result of the call is returned, and exceptions are + allowed to propogate cleanly, while ensuring that profiling is + disabled on the way out. + """ + return self._prof.runcall(func, args, kw) diff --git a/PythonHome/Lib/hotshot/__init__.pyc b/PythonHome/Lib/hotshot/__init__.pyc deleted file mode 100644 index 4214cf3264d7379676c1801991f2342f7aeeb183..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3319 zcmbVOU2hvj6rHu554$NTMJ=DI1|CRMrIt`7UZ^UdD&hf^YJ-G`DlO~Xv9ry3XEif! z5-EL3CH?>p{1RUHS^NMv=kBiKQnd=TJ>xsycg{Wc-s%5+b@b=YzwT$M{S5H`HH!ZQ zRj$+l>PY21RYvLn0)BnU^PW2Bsfg`?D*I|aPzP%&GHWWwZ(ZdZ>O6{~d{gBkl@HYm zrOuW5ct_Z&gc07jCqtZMxWzj=3Y@lj&St8m; z-?yBbpfW%dkaeKG5EOwZ;5q0MN(uvFNI{UKAb3*PP(YLda1~Gwh6I>BBNaEe7C1*0 z#3mb{T0`Og0~G%UsSy1b-qYHr` z`Cx0YVw&egHMP6kr5Q2hR3?L=(<@2uU)o zPaA#Pwm89cu8eL(A4luaCu`f$mV7hr+7+?fyXa^PK=d&P1McsVb^Z>j2fU0hmiobS zbXw&)7zdcr(2R7@j33FmnApXnv3N}U4keV!+(VXqgt?v?sNSpk(k)l@-Iqhe=VKEV zt`cQM)7<#X6?L#q+o^PSn(lZ81kG9F3!OnUrPx>5x6qt`-$Hq<=5IjyJ*?X&Szgle zB|K@=x6q2qK6^{8c%yv~_w`C`y`55A_W6oZbe*mUDc?uO(#VVuJ$2q>g_fFkG2xp$ z2N`whCPi?mJJn@6F=dHh`z$RNpr&0_oCbdhP!dT(gAg?E{3CNJt|;p-O<8Vq8>KTm znM*fb21oA1gob3N)N@2e1inZ;N9;q$LlgId+-K}-f|dUZD;_twhgUQwCcBf_d7Xx0 z0vGhbF_$5yFqJeUAL;gEs%M3>)f{1MJX-cLOU+6Q2v!>THF~U!-CuVA4izZyr)Dwf(i@!kFZ$g)Q z&C2_N6FDMumNe7uB%xS32(-tDaqeLy=1-ixHq^CqLmEasYog4zrt#SfFcyON=sc^--%=> zT>02KFxkx(bOo>H=_z2;HL|tImu5*zTg|=_7CYk?W$03coQr3ilcZwuJxP4#Br`Qn z^w{~rH=v_EhTRZyV6)oJ$dIfwX;q%?>ElD@O;h=WxNSI0!-{DOzf>kKJTI7Q+j#ad zRJIGaap&7Bxr&yfQE~K&`_N;i^eGCsyT>C7aqalB9u$9y>EEF=!ECd6E0JtTQl)bP zw`F2S;E;DNo;}QJlC@)|i%=z4D} My4JgfIJ43F7m*gsMgRZ+ diff --git a/PythonHome/Lib/hotshot/log.py b/PythonHome/Lib/hotshot/log.py new file mode 100644 index 0000000000..17e8b50515 --- /dev/null +++ b/PythonHome/Lib/hotshot/log.py @@ -0,0 +1,194 @@ +import _hotshot +import os.path +import parser +import symbol + +from _hotshot import \ + WHAT_ENTER, \ + WHAT_EXIT, \ + WHAT_LINENO, \ + WHAT_DEFINE_FILE, \ + WHAT_DEFINE_FUNC, \ + WHAT_ADD_INFO + + +__all__ = ["LogReader", "ENTER", "EXIT", "LINE"] + + +ENTER = WHAT_ENTER +EXIT = WHAT_EXIT +LINE = WHAT_LINENO + + +class LogReader: + def __init__(self, logfn): + # fileno -> filename + self._filemap = {} + # (fileno, lineno) -> filename, funcname + self._funcmap = {} + + self._reader = _hotshot.logreader(logfn) + self._nextitem = self._reader.next + self._info = self._reader.info + if 'current-directory' in self._info: + self.cwd = self._info['current-directory'] + else: + self.cwd = None + + # This mirrors the call stack of the profiled code as the log + # is read back in. It contains tuples of the form: + # + # (file name, line number of function def, function name) + # + self._stack = [] + self._append = self._stack.append + self._pop = self._stack.pop + + def close(self): + self._reader.close() + + def fileno(self): + """Return the file descriptor of the log reader's log file.""" + return self._reader.fileno() + + def addinfo(self, key, value): + """This method is called for each additional ADD_INFO record. + + This can be overridden by applications that want to receive + these events. The default implementation does not need to be + called by alternate implementations. + + The initial set of ADD_INFO records do not pass through this + mechanism; this is only needed to receive notification when + new values are added. Subclasses can inspect self._info after + calling LogReader.__init__(). + """ + pass + + def get_filename(self, fileno): + try: + return self._filemap[fileno] + except KeyError: + raise ValueError, "unknown fileno" + + def get_filenames(self): + return self._filemap.values() + + def get_fileno(self, filename): + filename = os.path.normcase(os.path.normpath(filename)) + for fileno, name in self._filemap.items(): + if name == filename: + return fileno + raise ValueError, "unknown filename" + + def get_funcname(self, fileno, lineno): + try: + return self._funcmap[(fileno, lineno)] + except KeyError: + raise ValueError, "unknown function location" + + # Iteration support: + # This adds an optional (& ignored) parameter to next() so that the + # same bound method can be used as the __getitem__() method -- this + # avoids using an additional method call which kills the performance. + + def next(self, index=0): + while 1: + # This call may raise StopIteration: + what, tdelta, fileno, lineno = self._nextitem() + + # handle the most common cases first + + if what == WHAT_ENTER: + filename, funcname = self._decode_location(fileno, lineno) + t = (filename, lineno, funcname) + self._append(t) + return what, t, tdelta + + if what == WHAT_EXIT: + try: + return what, self._pop(), tdelta + except IndexError: + raise StopIteration + + if what == WHAT_LINENO: + filename, firstlineno, funcname = self._stack[-1] + return what, (filename, lineno, funcname), tdelta + + if what == WHAT_DEFINE_FILE: + filename = os.path.normcase(os.path.normpath(tdelta)) + self._filemap[fileno] = filename + elif what == WHAT_DEFINE_FUNC: + filename = self._filemap[fileno] + self._funcmap[(fileno, lineno)] = (filename, tdelta) + elif what == WHAT_ADD_INFO: + # value already loaded into self.info; call the + # overridable addinfo() handler so higher-level code + # can pick up the new value + if tdelta == 'current-directory': + self.cwd = lineno + self.addinfo(tdelta, lineno) + else: + raise ValueError, "unknown event type" + + def __iter__(self): + return self + + # + # helpers + # + + def _decode_location(self, fileno, lineno): + try: + return self._funcmap[(fileno, lineno)] + except KeyError: + # + # This should only be needed when the log file does not + # contain all the DEFINE_FUNC records needed to allow the + # function name to be retrieved from the log file. + # + if self._loadfile(fileno): + filename = funcname = None + try: + filename, funcname = self._funcmap[(fileno, lineno)] + except KeyError: + filename = self._filemap.get(fileno) + funcname = None + self._funcmap[(fileno, lineno)] = (filename, funcname) + return filename, funcname + + def _loadfile(self, fileno): + try: + filename = self._filemap[fileno] + except KeyError: + print "Could not identify fileId", fileno + return 1 + if filename is None: + return 1 + absname = os.path.normcase(os.path.join(self.cwd, filename)) + + try: + fp = open(absname) + except IOError: + return + st = parser.suite(fp.read()) + fp.close() + + # Scan the tree looking for def and lambda nodes, filling in + # self._funcmap with all the available information. + funcdef = symbol.funcdef + lambdef = symbol.lambdef + + stack = [st.totuple(1)] + + while stack: + tree = stack.pop() + try: + sym = tree[0] + except (IndexError, TypeError): + continue + if sym == funcdef: + self._funcmap[(fileno, tree[2][2])] = filename, tree[2][1] + elif sym == lambdef: + self._funcmap[(fileno, tree[1][2])] = filename, "" + stack.extend(list(tree[1:])) diff --git a/PythonHome/Lib/hotshot/log.pyc b/PythonHome/Lib/hotshot/log.pyc deleted file mode 100644 index 3e161f12f04514ab739bb2e640361c6f5632762d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5332 zcmb7IUvnEt5uaJf`e)fm?EG^`!iGx`9o&gKiUNvD9T#Hf&JdKUmBGfC5^L?qURl~z zc1LkkmAqW8j;E`u;(>y(_{p%i= z{<+ln%l0q3eU<-}@%tX0^mk|ie6<=WwOi0y?K<=KCAC|c(`B_=7TO{IctPzhsBuN@ zR@AtvcB^V!Q@b@auB+X;8aLE#L+JpMF=s&q6?K65i^^bHQyENKQU=qO6?tkZsH%^Y zdZyIRcF$0wZmSOM!hhkf)2e{94K&*y+}Y}Fbhb7;%i*lMv$%Ol(G;N8i>qQnu)~R955tJQ&%71Od2X^$mpU9 z7KLc4pee+X^13Z{;>FV`ryt|I7}tx;D88L=o#i)z>u5li##vUG983P(&$JLx&J{b`bz z$i5kbiRs%onYDO=wuYuR2uEh@Px8(*>KC2E*rs^o#76N!lATzUlXAKYIx>$lmL93l znz5W<7!6`M-JVb-aQ2S_8S2E5v2?m#YW@C^kp5(1qQHvqoaU5CJdr6q5V9ZXrDik` z+0bebwZNyONza37@7)jg_j29$z|o$}vdux0(Dr(l!IWO)B&UwgiasNsRi|F9gX(LH z%pW;qT95~bFOC$0VqLOyL?>?N&87S!2!GRKwe|}Zgy6;QkNa_wNGfxW8k|e{$grh$GmUi z$<%iGJS;xkyBLkGAwa`@rT@VDt-~;N$HpGUfeWhdk47eN2T<1d{X^Feg3yL>hJCnx>z;~^?9bHjntJP6MC0|!sYXCER@U+%r=rFP9#nKl=hQu7DxV64Dyge@Ja|B;pUFn3fO&{~UxB5F9#lVxH!Z>7Hu!_)RgtWV&Zc zt^eYx+H=%Xe8DHIM~+I`>WQPe58G-R(4U>hiL+p4df_Z!q!#l64o|5#l?*WP?V%h@ z6er`pkC37X+2M#MMxkRc9i`rDpjzBY=7nSx%!6b(HxbFhIL!f4c44#l$LOVerSx@u zRX24_7g$($Cf#;+;kjpG`vd1C|9ty@`R5u06gEMMCdvWMGq}rKl_i?@6*jWl5~;#5 zCB-6O3G*2Ef7!C|Q7lEXY+*{_qZi<#D0%W~h+8lA`5U18<4<*#t#JN(<^1fQfO0i6`Az0hHzB5R5{f&5(=nQ#jRlD=Ow3#@|ybf6`+==~k3_g`HQrYm5W zyO`ug*Ul!U#X8AjNP2jvKNby;l>^h8`=57-!&3CnPX!`3qrg1Q5R>&w*T$1gikCFSu-)&$< z)|UYHSYdf@kXeF1_iK0~-pK7{5GJWTb%c0lFcB5MO235$$n9J%H}z$~? zBh!FInEn}^SHsb#MY{YW1BQ+TuM~$)?$D9S0CEH~oNjha{0=(f@{-}%p5Q!&w;%qg z5cK=GpzQjS1&25#7~#7Ylba!w zVL;i|8gk%v^rgZoZCV9@^FFNi{s)Na?hcFy10U5?@_mMR7sXO`Wz2~TO@NRN0h16@ zQnRyk=nQmd_haxnLBlil=QM*)m2b$;JK+=EY@?dqprQ4WSm}a90$`8y53bVh#52N zzrpTJHeY4aX2ZLJfVlTPQjBts+CATeQ2+HG3Lejpc~5YmqU)FHrFyx(T(97_T3>A5 zLc5wtlkCZoN{%m1+ft&6+q{Rj9sxtLYnDSLJC^v4CiZA?nb_;$&V}9an7kUBIvXl- dTCK%uw=+AvOFx&a&xC}J)2^?SD!{W!>E9#$^UDAL diff --git a/PythonHome/Lib/hotshot/stats.py b/PythonHome/Lib/hotshot/stats.py new file mode 100644 index 0000000000..7ff2277a18 --- /dev/null +++ b/PythonHome/Lib/hotshot/stats.py @@ -0,0 +1,93 @@ +"""Statistics analyzer for HotShot.""" + +import profile +import pstats + +import hotshot.log + +from hotshot.log import ENTER, EXIT + + +def load(filename): + return StatsLoader(filename).load() + + +class StatsLoader: + def __init__(self, logfn): + self._logfn = logfn + self._code = {} + self._stack = [] + self.pop_frame = self._stack.pop + + def load(self): + # The timer selected by the profiler should never be used, so make + # sure it doesn't work: + p = Profile() + p.get_time = _brokentimer + log = hotshot.log.LogReader(self._logfn) + taccum = 0 + for event in log: + what, (filename, lineno, funcname), tdelta = event + if tdelta > 0: + taccum += tdelta + + # We multiply taccum to convert from the microseconds we + # have to the seconds that the profile/pstats module work + # with; this allows the numbers to have some basis in + # reality (ignoring calibration issues for now). + + if what == ENTER: + frame = self.new_frame(filename, lineno, funcname) + p.trace_dispatch_call(frame, taccum * .000001) + taccum = 0 + + elif what == EXIT: + frame = self.pop_frame() + p.trace_dispatch_return(frame, taccum * .000001) + taccum = 0 + + # no further work for line events + + assert not self._stack + return pstats.Stats(p) + + def new_frame(self, *args): + # args must be filename, firstlineno, funcname + # our code objects are cached since we don't need to create + # new ones every time + try: + code = self._code[args] + except KeyError: + code = FakeCode(*args) + self._code[args] = code + # frame objects are create fresh, since the back pointer will + # vary considerably + if self._stack: + back = self._stack[-1] + else: + back = None + frame = FakeFrame(code, back) + self._stack.append(frame) + return frame + + +class Profile(profile.Profile): + def simulate_cmd_complete(self): + pass + + +class FakeCode: + def __init__(self, filename, firstlineno, funcname): + self.co_filename = filename + self.co_firstlineno = firstlineno + self.co_name = self.__name__ = funcname + + +class FakeFrame: + def __init__(self, code, back): + self.f_back = back + self.f_code = code + + +def _brokentimer(): + raise RuntimeError, "this timer should not be called" diff --git a/PythonHome/Lib/hotshot/stats.pyc b/PythonHome/Lib/hotshot/stats.pyc deleted file mode 100644 index 828813fd2852a77cefb84ffe460692f5286844f2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3083 zcmbtW&u<$=6n^7fujABi5+yD40v1$Yij)(A1Em5=%a2x}T31c6f);0YovdT;n%xN{ z$d*vU5&j2`zzHG2pTK{^1r8j`_q}y&T104tlQ;WjcIM5z?|tvhI)5~mf7$+|6Uyx8 z;Q1z`_zq1Z(nV_|s>skt7fPvDq+2=B9qGENJ2G@+RF!U3MxJy%F_9}@!9-1>szhfc z^4L8V`KY@jQB7hagSzx#a%ujeE)o7$BwC&iElYGpqE(3+^C9$`>~tGETBp6n6SvTG zY|kczO~RtpOMAnkFXFt_&+^uLneFUnb~AZ^-&VVVskVyd+ScuBzICbHegAf7piub! zDx_FNV?`!7HV$ie_)eQMW;V`1<(|dOtQW<(S{g#tId%ze`^hj)d!x7wU9>6AL)+ZB zne6W1NCjl4poz`#kx%$(v)~ED_y8da*2pLbO{yl(#m>r8u zjaWEpB&Y}uHgIK7RsTGObE>FK9r^qxnN;MRkAIM5@$AG65}( z9JrDn$OPcj$W+$DUITHv1jEz99@yYD))kCW#qRITamqQe*5{`KY#u4 ziY5t8Dsn5&$V%IQ9_;4XL7duT1ojfwz1Rlq>C72FHK+)f2K8pP=f@XSp(L ztZAa`(VS~D?EW%W(Dc}68PJ(vVt6>xnek`vPN{cqzh`~-WXdo}<1{N%^e_#XqUF*k z9wHm*TS;9gkC(Sh>*6A(JEZ10(;~PA`cI=MI)7e?yEh7Wrx9Yfu|XnX5Yaa%$u*Dd9-Itv0|lBNs?fk2wql zK5>a7ARvjZvj^a+OU@WPI+~|jS|r%D{cD)PRJ79rir(pXu* zSJ#>H3TAISj?<{EMA0~LZZF>}G$2|!II@ev;kTeXRz2{^uU8>jNX2!`8h~z?HNd`F z@yv=@HM-@ja4@t%V7Y$~jI!u(h^|laYq?c(i;Yz~twghwt#Ef@f6oi_<{7+a2!yVcyVVNT`_mXLcn;wPkKJIdI zgs--WXF0x~6fM2hTKL2|97Ziv`_^vU;#CySKG3uX9O~_-)otPDf5wb=)DA=sC+3lr zZ9N(}7z9xkqWn-Fmlv=96m;eA?0((E-RkqpMsL&do@6-n^G}mbGfjEnbK^&LJ0&Pu g1230V?+U9;v4O_pO;l-A&O3E?{q+mg_1e1k7l*1R6#xJL diff --git a/PythonHome/Lib/hotshot/stones.py b/PythonHome/Lib/hotshot/stones.py new file mode 100644 index 0000000000..fb88d581d3 --- /dev/null +++ b/PythonHome/Lib/hotshot/stones.py @@ -0,0 +1,30 @@ +import errno +import hotshot +import hotshot.stats +import sys +import test.pystone + +def main(logfile): + p = hotshot.Profile(logfile) + benchtime, stones = p.runcall(test.pystone.pystones) + p.close() + + print "Pystone(%s) time for %d passes = %g" % \ + (test.pystone.__version__, test.pystone.LOOPS, benchtime) + print "This machine benchmarks at %g pystones/second" % stones + + stats = hotshot.stats.load(logfile) + stats.strip_dirs() + stats.sort_stats('time', 'calls') + try: + stats.print_stats(20) + except IOError, e: + if e.errno != errno.EPIPE: + raise + +if __name__ == '__main__': + if sys.argv[1:]: + main(sys.argv[1]) + else: + import tempfile + main(tempfile.NamedTemporaryFile().name) diff --git a/PythonHome/Lib/hotshot/stones.pyc b/PythonHome/Lib/hotshot/stones.pyc deleted file mode 100644 index 5d73a6914f9d369891ae2e9856dabbc1e81bd32c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1126 zcmah{U2fAr5T3P@rb!dpMioB-2}`I_5F%Uv5E3d-scNI7Qc)Dixbdd3V|(45ZKX)* z3*`uX;3V9DK5!il05fYFc*F5dW@o?o`M$OLv(x%^@@X`M@^R_^4K4giCZtzD0xAsFm|hW4aRi{9r!|tYakmCy0CCS-+*)>UWc#-kF^F#XVw0}wE%H`Q&nif zxM|Ou5VznOAl?8*WOkrYuTH~7zvwxf3Ub$Iap)~A{6WT0hJY1t(iJ%ZVh0R0t3h1n z;KYF|dR=?8#vKGPEfI~%S%;MaGZ*f@|3GwB*5T52s7B}KI!^<=Krb+a@baPx zzCbxuS!il37gaMX;50}QjCRQDZF9UqX08mx+!xMFEKgpsa4zDY5EQ zR8AC1vq53szmysymHECsIXF5RjI4(yFlg%~DhN%Bz-V-o`(dQ9*eY%O0>-6s9c9&? zN8LZ#)0!YmMQWWX>+KEp2YXgWJ9nbaEC>E@a?>PhHL@D8*j8j5a(%-X*&_qi;63vC zlY{7VQmQg3(EWUA=T3tt<3aEd=ZH=5P_!JEY}4tAme>-m*rsS#Sb=<>@xC8%n_ipD zkX0W#WK4%l*`!}Eb}52%dki!rI5oB1hfH^PpQ9|h?`J_ONnF0!K%ZUOsF7)IX?H1l wNPzH|B1#8(`HpXt!JPM(?Ee{ax0k63FB18hDIkA1ZBhQ5X16UmV#jHV-#_Z^>i_@% diff --git a/PythonHome/Lib/htmlentitydefs.py b/PythonHome/Lib/htmlentitydefs.py new file mode 100644 index 0000000000..3dd14a79fa --- /dev/null +++ b/PythonHome/Lib/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/PythonHome/Lib/htmlentitydefs.pyc b/PythonHome/Lib/htmlentitydefs.pyc index 5805462935e68aa30526bd214e04b8ff2e329a35..cc773558ff9f95275403d099b5154a19afe136d7 100644 GIT binary patch delta 62 zcmca*_{VU=R53$m1_p*ytC;l6l8n-%nDG1xJ+EMYzn}o;82{3eg3^*0m(--v^q7Fk Rl8pR3kNn)!%}d10m;lF*7O4OL delta 28 jcmexkc*}6ZR55-<1_lOatC)bwl8pR3BlFG2#LSogkOm1) diff --git a/PythonHome/Lib/htmllib.py b/PythonHome/Lib/htmllib.py new file mode 100644 index 0000000000..44647dbf02 --- /dev/null +++ b/PythonHome/Lib/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 tag with + the same names. The default implementation maintains a list of + hyperlinks (defined by the HREF attribute for 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/PythonHome/Lib/htmllib.pyc b/PythonHome/Lib/htmllib.pyc deleted file mode 100644 index 882aff5c1d0ffb2b0f1482745662dbe1075c21a3..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 18944 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 A + + +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 +Req-started-unread-response _CS_REQ_STARTED +Req-sent-unread-response _CS_REQ_SENT +""" + +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 and amt: + # 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 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 = {} + if strict is not None: + self.strict = strict + + (self.host, self.port) = self._get_hostport(host, port) + + # This is stored as an instance variable to allow unittests + # to replace with a suitable mock + self._create_connection = socket.create_connection + + def set_tunnel(self, host, port=None, headers=None): + """ Set up host and port for HTTP CONNECT tunnelling. + + In a connection that uses HTTP Connect tunneling, the host passed to the + constructor is used as proxy server that relays all communication to the + endpoint passed to set_tunnel. This is done by sending a HTTP CONNECT + request to the proxy server when the connection is established. + + This method must be called before the HTML connection has been + established. + + The headers argument should be a mapping of extra HTTP headers + to send with the CONNECT request. + """ + # Verify if this is required. + if self.sock: + raise RuntimeError("Can't setup tunnel for established connection.") + + self._tunnel_host = host + self._tunnel_port = port + if headers: + self._tunnel_headers = headers + else: + self._tunnel_headers.clear() + + def _get_hostport(self, host, port): + if port is None: + i = host.rfind(':') + j = host.rfind(']') # ipv6 addresses have [...] + if i > j: + try: + port = int(host[i+1:]) + except ValueError: + if host[i+1:] == "": # http://foo.com:/ == http://foo.com/ + port = self.default_port + else: + raise InvalidURL("nonnumeric port: '%s'" % host[i+1:]) + host = host[:i] + else: + port = self.default_port + if host and host[0] == '[' and host[-1] == ']': + host = host[1:-1] + return (host, port) + + def set_debuglevel(self, level): + self.debuglevel = level + + def _tunnel(self): + (host, port) = self._get_hostport(self._tunnel_host, self._tunnel_port) + self.send("CONNECT %s:%d HTTP/1.0\r\n" % (host, 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 = self._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: + if self._tunnel_host: + host = self._tunnel_host + port = self._tunnel_port + else: + host = self.host + port = self.port + + try: + host_enc = host.encode("ascii") + except UnicodeEncodeError: + host_enc = host.encode("idna") + # Wrap the IPv6 Host Header with [] (RFC 2732) + if host_enc.find(':') >= 0: + host_enc = "[" + host_enc + "]" + if port == self.default_port: + self.putheader('Host', host_enc) + else: + self.putheader('Host', "%s:%s" % (host_enc, port)) + + # note: we are assuming that clients will not attempt to set these + # headers since *this* library must deal with the + # consequences. this also means that when the supporting + # libraries are updated to recognize other forms, then this + # code should be changed (removed or updated). + + # we only want a Content-Encoding of "identity" since we don't + # support encodings such as x-gzip or x-deflate. + if not skip_accept_encoding: + self.putheader('Accept-Encoding', 'identity') + + # we can accept "chunked" Transfer-Encodings, but no others + # NOTE: no TE header implies *only* "chunked" + #self.putheader('TE', 'chunked') + + # if TE is supplied in the header, then it must appear in a + # Connection header. + #self.putheader('Connection', 'TE') + + else: + # For HTTP/1.0, the server will assume "not chunked" + pass + + def putheader(self, header, *values): + """Send a request header line to the server. + + For example: h.putheader('Accept', 'text/html') + """ + if self.__state != _CS_REQ_STARTED: + raise CannotSendHeader() + + 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 = self._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/PythonHome/Lib/httplib.pyc b/PythonHome/Lib/httplib.pyc index dbe7afb6a2e95bdce5d35265f8e7e73b94df7f0a..ef4df152481940fb5895b00a3a93f145185c79ca 100644 GIT binary patch delta 4210 zcmbW4-%C?*7{+&|%dm(>$F_?uW>mY$Ic-KcOG+nAX&Xf|>}a?;9k*&f&&mA|*Gke| zbkjG9f(oGIj?2o~AS<|TfTYRxG#KX%70Qfkj{fMjWBOlYK)7AzEP2@3#R zbv*&7Qfrc*T5vmoZ0KP7Tphm{ed|~OFt&X7I=>h@+xZlrc6i?d)UhFvt$U07B$c}q zAQIZ>)&Pv@KIvXh6=_P_OqXgSm?Y@%xDhy|$EXaraIIiO2xgMGlt&|7Z>@TtEj9XfX(@X1!C zpuU3L!;1*~XXL03x1axlzz(}eZKFs(P$1F>giFfBI>0F9!^H#I4(4&gGC~vY~`v3ZfpUm4iXH1zMuu&zN(fX)@QGR_Od${tdTW^Cw!O zk0J$;Lr(?@;uE;DDCq}06N3nq@+1iJz@qTX&(rtz^m^|1zVCuxmXnrp zNuf}bU2nDy^>=i4T{Dp*Z4X$~t*62CEJ@8T(_dXUckIuKi=5rrJxYL@oJ5rfDbsGC zy1aThAeOh60OO5<*OHPO3LO%R_KTK*@fEMg*nTw^yQ~yPp$m_ib^ubSBq&;v@x}@; zo%sVWjfF(UTNV$5u&dOEFsb|ix6Y`DfaSM}W7u%kX5iE+9T?2o^wd%POZ1>njZso@ zyyh#M;CI%G0M~6tz~sBUCEw#cyIC#T^LFDV==tNFa_CLwyF21(xidRjUw{E!cGgM> z>~+4uQN7C|?=$Dxg%L;H*$Dr(YoQAlb*fP5x}OY?79YSDan^d~p$}Zi)EyN!q$KZi zk@08mFa&X5?@fSmx}N^`dB9=1UxV?V9<_n6X~2lCZwGrsAvuSf!2X=W!oxApwT|2d z_GJY9Jbq*+{_k*BJ9-2xKhP^O`6bYg07f?i-J+C!2QfPE7@2Mi+0xi1_$`Dgf$5$c z0xJwdKVA+`N+4{Rm;iS6kItW51+JMYmY-wE)HvE4Km94nS^La@LTkha!hexcHNZ}) Gl}-UbXV=#N diff --git a/PythonHome/Lib/idlelib/AutoComplete.py b/PythonHome/Lib/idlelib/AutoComplete.py new file mode 100644 index 0000000000..1248f000ea --- /dev/null +++ b/PythonHome/Lib/idlelib/AutoComplete.py @@ -0,0 +1,229 @@ +"""AutoComplete.py - An IDLE extension for automatically completing names. + +This extension can complete either attribute names of file names. It can pop +a window with all available names, for the user to select from. +""" +import os +import sys +import string + +from idlelib.configHandler import idleConf + +# This string includes all chars that may be in a file name (without a path +# separator) +FILENAME_CHARS = string.ascii_letters + string.digits + os.curdir + "._~#$:-" +# This string includes all chars that may be in an identifier +ID_CHARS = string.ascii_letters + string.digits + "_" + +# These constants represent the two different types of completions +COMPLETE_ATTRIBUTES, COMPLETE_FILES = range(1, 2+1) + +from idlelib import AutoCompleteWindow +from idlelib.HyperParser import HyperParser + +import __main__ + +SEPS = os.sep +if os.altsep: # e.g. '/' on Windows... + SEPS += os.altsep + +class AutoComplete: + + menudefs = [ + ('edit', [ + ("Show Completions", "<>"), + ]) + ] + + popupwait = idleConf.GetOption("extensions", "AutoComplete", + "popupwait", type="int", default=0) + + def __init__(self, editwin=None): + self.editwin = editwin + if editwin is None: # subprocess and test + return + self.text = editwin.text + self.autocompletewindow = None + + # id of delayed call, and the index of the text insert when the delayed + # call was issued. If _delayed_completion_id is None, there is no + # delayed call. + self._delayed_completion_id = None + self._delayed_completion_index = None + + def _make_autocomplete_window(self): + return AutoCompleteWindow.AutoCompleteWindow(self.text) + + def _remove_autocomplete_window(self, event=None): + if self.autocompletewindow: + self.autocompletewindow.hide_window() + self.autocompletewindow = None + + def force_open_completions_event(self, event): + """Happens when the user really wants to open a completion list, even + if a function call is needed. + """ + self.open_completions(True, False, True) + + def try_open_completions_event(self, event): + """Happens when it would be nice to open a completion list, but not + really necessary, for example after an dot, so function + calls won't be made. + """ + lastchar = self.text.get("insert-1c") + if lastchar == ".": + self._open_completions_later(False, False, False, + COMPLETE_ATTRIBUTES) + elif lastchar in SEPS: + self._open_completions_later(False, False, False, + COMPLETE_FILES) + + def autocomplete_event(self, event): + """Happens when the user wants to complete his word, and if necessary, + open a completion list after that (if there is more than one + completion) + """ + if hasattr(event, "mc_state") and event.mc_state: + # A modifier was pressed along with the tab, continue as usual. + return + if self.autocompletewindow and self.autocompletewindow.is_active(): + self.autocompletewindow.complete() + return "break" + else: + opened = self.open_completions(False, True, True) + if opened: + return "break" + + def _open_completions_later(self, *args): + self._delayed_completion_index = self.text.index("insert") + if self._delayed_completion_id is not None: + self.text.after_cancel(self._delayed_completion_id) + self._delayed_completion_id = \ + self.text.after(self.popupwait, self._delayed_open_completions, + *args) + + def _delayed_open_completions(self, *args): + self._delayed_completion_id = None + if self.text.index("insert") != self._delayed_completion_index: + return + self.open_completions(*args) + + def open_completions(self, evalfuncs, complete, userWantsWin, mode=None): + """Find the completions and create the AutoCompleteWindow. + Return True if successful (no syntax error or so found). + if complete is True, then if there's nothing to complete and no + start of completion, won't open completions and return False. + If mode is given, will open a completion list only in this mode. + """ + # Cancel another delayed call, if it exists. + if self._delayed_completion_id is not None: + self.text.after_cancel(self._delayed_completion_id) + self._delayed_completion_id = None + + hp = HyperParser(self.editwin, "insert") + curline = self.text.get("insert linestart", "insert") + i = j = len(curline) + if hp.is_in_string() and (not mode or mode==COMPLETE_FILES): + self._remove_autocomplete_window() + mode = COMPLETE_FILES + while i and curline[i-1] in FILENAME_CHARS: + i -= 1 + comp_start = curline[i:j] + j = i + while i and curline[i-1] in FILENAME_CHARS + SEPS: + i -= 1 + comp_what = curline[i:j] + elif hp.is_in_code() and (not mode or mode==COMPLETE_ATTRIBUTES): + self._remove_autocomplete_window() + mode = COMPLETE_ATTRIBUTES + while i and curline[i-1] in ID_CHARS: + i -= 1 + comp_start = curline[i:j] + if i and curline[i-1] == '.': + hp.set_index("insert-%dc" % (len(curline)-(i-1))) + comp_what = hp.get_expression() + if not comp_what or \ + (not evalfuncs and comp_what.find('(') != -1): + return + else: + comp_what = "" + else: + return + + if complete and not comp_what and not comp_start: + return + comp_lists = self.fetch_completions(comp_what, mode) + if not comp_lists[0]: + return + self.autocompletewindow = self._make_autocomplete_window() + return not self.autocompletewindow.show_window( + comp_lists, "insert-%dc" % len(comp_start), + complete, mode, userWantsWin) + + def fetch_completions(self, what, mode): + """Return a pair of lists of completions for something. The first list + is a sublist of the second. Both are sorted. + + If there is a Python subprocess, get the comp. list there. Otherwise, + either fetch_completions() is running in the subprocess itself or it + was called in an IDLE EditorWindow before any script had been run. + + The subprocess environment is that of the most recently run script. If + two unrelated modules are being edited some calltips in the current + module may be inoperative if the module was not the last to run. + """ + try: + rpcclt = self.editwin.flist.pyshell.interp.rpcclt + except: + rpcclt = None + if rpcclt: + return rpcclt.remotecall("exec", "get_the_completion_list", + (what, mode), {}) + else: + if mode == COMPLETE_ATTRIBUTES: + if what == "": + namespace = __main__.__dict__.copy() + namespace.update(__main__.__builtins__.__dict__) + bigl = eval("dir()", namespace) + bigl.sort() + if "__all__" in bigl: + smalll = sorted(eval("__all__", namespace)) + else: + smalll = [s for s in bigl if s[:1] != '_'] + else: + try: + entity = self.get_entity(what) + bigl = dir(entity) + bigl.sort() + if "__all__" in bigl: + smalll = sorted(entity.__all__) + else: + smalll = [s for s in bigl if s[:1] != '_'] + except: + return [], [] + + elif mode == COMPLETE_FILES: + if what == "": + what = "." + try: + expandedpath = os.path.expanduser(what) + bigl = os.listdir(expandedpath) + bigl.sort() + smalll = [s for s in bigl if s[:1] != '.'] + except OSError: + return [], [] + + if not smalll: + smalll = bigl + return smalll, bigl + + def get_entity(self, name): + """Lookup name in a namespace spanning sys.modules and __main.dict__""" + namespace = sys.modules.copy() + namespace.update(__main__.__dict__) + return eval(name, namespace) + + +if __name__ == '__main__': + from unittest import main + main('idlelib.idle_test.test_autocomplete', verbosity=2) diff --git a/PythonHome/Lib/idlelib/AutoComplete.pyc b/PythonHome/Lib/idlelib/AutoComplete.pyc deleted file mode 100644 index 036fd01f1f8cd902557b575440404c444e6b7b70..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 7818 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", "") +KEYPRESS_VIRTUAL_EVENT_NAME = "<>" +# We need to bind event beyond so that the function will be called +# before the default specific IDLE function +KEYPRESS_SEQUENCES = ("", "", "", "", + "", "", "", "", + "", "") +KEYRELEASE_VIRTUAL_EVENT_NAME = "<>" +KEYRELEASE_SEQUENCE = "" +LISTUPDATE_SEQUENCE = "" +WINCONFIG_SEQUENCE = "" +DOUBLECLICK_SEQUENCE = "" + +class AutoCompleteWindow: + + def __init__(self, widget): + # The widget (Text) on which we place the AutoCompleteWindow + self.widget = widget + # The widgets we create + self.autocompletewindow = self.listbox = self.scrollbar = None + # The default foreground and background of a selection. Saved because + # they are changed to the regular colors of list items when the + # completion start is not a prefix of the selected completion + self.origselforeground = self.origselbackground = None + # The list of completions + self.completions = None + # A list with more completions, or None + self.morecompletions = None + # The completion mode. Either AutoComplete.COMPLETE_ATTRIBUTES or + # AutoComplete.COMPLETE_FILES + self.mode = None + # The current completion start, on the text box (a string) + self.start = None + # The index of the start of the completion + self.startindex = None + # The last typed start, used so that when the selection changes, + # the new start will be as close as possible to the last typed one. + self.lasttypedstart = None + # Do we have an indication that the user wants the completion window + # (for example, he clicked the list) + self.userwantswindow = None + # event ids + self.hideid = self.keypressid = self.listupdateid = self.winconfigid \ + = self.keyreleaseid = self.doubleclickid = None + # Flag set if last keypress was a tab + self.lastkey_was_tab = False + + def _change_start(self, newstart): + min_len = min(len(self.start), len(newstart)) + i = 0 + while i < min_len and self.start[i] == newstart[i]: + i += 1 + if i < len(self.start): + self.widget.delete("%s+%dc" % (self.startindex, i), + "%s+%dc" % (self.startindex, len(self.start))) + if i < len(newstart): + self.widget.insert("%s+%dc" % (self.startindex, i), + newstart[i:]) + self.start = newstart + + def _binary_search(self, s): + """Find the first index in self.completions where completions[i] is + greater or equal to s, or the last index if there is no such + one.""" + i = 0; j = len(self.completions) + while j > i: + m = (i + j) // 2 + if self.completions[m] >= s: + j = m + else: + i = m + 1 + return min(i, len(self.completions)-1) + + def _complete_string(self, s): + """Assuming that s is the prefix of a string in self.completions, + return the longest string which is a prefix of all the strings which + s is a prefix of them. If s is not a prefix of a string, return s.""" + first = self._binary_search(s) + if self.completions[first][:len(s)] != s: + # There is not even one completion which s is a prefix of. + return s + # Find the end of the range of completions where s is a prefix of. + i = first + 1 + j = len(self.completions) + while j > i: + m = (i + j) // 2 + if self.completions[m][:len(s)] != s: + j = m + else: + i = m + 1 + last = i-1 + + if first == last: # only one possible completion + return self.completions[first] + + # We should return the maximum prefix of first and last + first_comp = self.completions[first] + last_comp = self.completions[last] + min_len = min(len(first_comp), len(last_comp)) + i = len(s) + while i < min_len and first_comp[i] == last_comp[i]: + i += 1 + return first_comp[:i] + + def _selection_changed(self): + """Should be called when the selection of the Listbox has changed. + Updates the Listbox display and calls _change_start.""" + cursel = int(self.listbox.curselection()[0]) + + self.listbox.see(cursel) + + lts = self.lasttypedstart + selstart = self.completions[cursel] + if self._binary_search(lts) == cursel: + newstart = lts + else: + min_len = min(len(lts), len(selstart)) + i = 0 + while i < min_len and lts[i] == selstart[i]: + i += 1 + newstart = selstart[:i] + self._change_start(newstart) + + if self.completions[cursel][:len(self.start)] == self.start: + # start is a prefix of the selected completion + self.listbox.configure(selectbackground=self.origselbackground, + selectforeground=self.origselforeground) + else: + self.listbox.configure(selectbackground=self.listbox.cget("bg"), + selectforeground=self.listbox.cget("fg")) + # If there are more completions, show them, and call me again. + if self.morecompletions: + self.completions = self.morecompletions + self.morecompletions = None + self.listbox.delete(0, END) + for item in self.completions: + self.listbox.insert(END, item) + self.listbox.select_set(self._binary_search(self.start)) + self._selection_changed() + + def show_window(self, comp_lists, index, complete, mode, userWantsWin): + """Show the autocomplete list, bind events. + If complete is True, complete the text, and if there is exactly one + matching completion, don't open a list.""" + # Handle the start we already have + self.completions, self.morecompletions = comp_lists + self.mode = mode + self.startindex = self.widget.index(index) + self.start = self.widget.get(self.startindex, "insert") + if complete: + completed = self._complete_string(self.start) + start = self.start + self._change_start(completed) + i = self._binary_search(completed) + if self.completions[i] == completed and \ + (i == len(self.completions)-1 or + self.completions[i+1][:len(completed)] != completed): + # There is exactly one matching completion + return completed == start + self.userwantswindow = userWantsWin + self.lasttypedstart = self.start + + # Put widgets in place + self.autocompletewindow = acw = Toplevel(self.widget) + # Put it in a position so that it is not seen. + acw.wm_geometry("+10000+10000") + # Make it float + acw.wm_overrideredirect(1) + try: + # This command is only needed and available on Tk >= 8.4.0 for OSX + # Without it, call tips intrude on the typing process by grabbing + # the focus. + acw.tk.call("::tk::unsupported::MacWindowStyle", "style", acw._w, + "help", "noActivates") + except TclError: + pass + self.scrollbar = scrollbar = Scrollbar(acw, orient=VERTICAL) + self.listbox = listbox = Listbox(acw, yscrollcommand=scrollbar.set, + exportselection=False, bg="white") + for item in self.completions: + listbox.insert(END, item) + self.origselforeground = listbox.cget("selectforeground") + self.origselbackground = listbox.cget("selectbackground") + scrollbar.config(command=listbox.yview) + scrollbar.pack(side=RIGHT, fill=Y) + listbox.pack(side=LEFT, fill=BOTH, expand=True) + + # Initialize the listbox selection + self.listbox.select_set(self._binary_search(self.start)) + self._selection_changed() + + # bind events + self.hideid = self.widget.bind(HIDE_VIRTUAL_EVENT_NAME, + self.hide_event) + for seq in HIDE_SEQUENCES: + self.widget.event_add(HIDE_VIRTUAL_EVENT_NAME, seq) + self.keypressid = self.widget.bind(KEYPRESS_VIRTUAL_EVENT_NAME, + self.keypress_event) + for seq in KEYPRESS_SEQUENCES: + self.widget.event_add(KEYPRESS_VIRTUAL_EVENT_NAME, seq) + self.keyreleaseid = self.widget.bind(KEYRELEASE_VIRTUAL_EVENT_NAME, + self.keyrelease_event) + self.widget.event_add(KEYRELEASE_VIRTUAL_EVENT_NAME,KEYRELEASE_SEQUENCE) + self.listupdateid = listbox.bind(LISTUPDATE_SEQUENCE, + self.listselect_event) + self.winconfigid = acw.bind(WINCONFIG_SEQUENCE, self.winconfig_event) + self.doubleclickid = listbox.bind(DOUBLECLICK_SEQUENCE, + self.doubleclick_event) + + def winconfig_event(self, event): + if not self.is_active(): + return + # Position the completion list window + text = self.widget + text.see(self.startindex) + x, y, cx, cy = text.bbox(self.startindex) + acw = self.autocompletewindow + acw_width, acw_height = acw.winfo_width(), acw.winfo_height() + text_width, text_height = text.winfo_width(), text.winfo_height() + new_x = text.winfo_rootx() + min(x, max(0, text_width - acw_width)) + new_y = text.winfo_rooty() + y + if (text_height - (y + cy) >= acw_height # enough height below + or y < acw_height): # not enough height above + # place acw below current line + new_y += cy + else: + # place acw above current line + new_y -= acw_height + acw.wm_geometry("+%d+%d" % (new_x, new_y)) + + def hide_event(self, event): + if not self.is_active(): + return + self.hide_window() + + def listselect_event(self, event): + if not self.is_active(): + return + self.userwantswindow = True + cursel = int(self.listbox.curselection()[0]) + self._change_start(self.completions[cursel]) + + def doubleclick_event(self, event): + # Put the selected completion in the text, and close the list + cursel = int(self.listbox.curselection()[0]) + self._change_start(self.completions[cursel]) + self.hide_window() + + def keypress_event(self, event): + if not self.is_active(): + return + keysym = event.keysym + if hasattr(event, "mc_state"): + state = event.mc_state + else: + state = 0 + if keysym != "Tab": + self.lastkey_was_tab = False + if (len(keysym) == 1 or keysym in ("underscore", "BackSpace") + or (self.mode == COMPLETE_FILES and keysym in + ("period", "minus"))) \ + and not (state & ~MC_SHIFT): + # Normal editing of text + if len(keysym) == 1: + self._change_start(self.start + keysym) + elif keysym == "underscore": + self._change_start(self.start + '_') + elif keysym == "period": + self._change_start(self.start + '.') + elif keysym == "minus": + self._change_start(self.start + '-') + else: + # keysym == "BackSpace" + if len(self.start) == 0: + self.hide_window() + return + self._change_start(self.start[:-1]) + self.lasttypedstart = self.start + self.listbox.select_clear(0, int(self.listbox.curselection()[0])) + self.listbox.select_set(self._binary_search(self.start)) + self._selection_changed() + return "break" + + elif keysym == "Return": + self.hide_window() + return + + elif (self.mode == COMPLETE_ATTRIBUTES and keysym in + ("period", "space", "parenleft", "parenright", "bracketleft", + "bracketright")) or \ + (self.mode == COMPLETE_FILES and keysym in + ("slash", "backslash", "quotedbl", "apostrophe")) \ + and not (state & ~MC_SHIFT): + # If start is a prefix of the selection, but is not '' when + # completing file names, put the whole + # selected completion. Anyway, close the list. + cursel = int(self.listbox.curselection()[0]) + if self.completions[cursel][:len(self.start)] == self.start \ + and (self.mode == COMPLETE_ATTRIBUTES or self.start): + self._change_start(self.completions[cursel]) + self.hide_window() + return + + elif keysym in ("Home", "End", "Prior", "Next", "Up", "Down") and \ + not state: + # Move the selection in the listbox + self.userwantswindow = True + cursel = int(self.listbox.curselection()[0]) + if keysym == "Home": + newsel = 0 + elif keysym == "End": + newsel = len(self.completions)-1 + elif keysym in ("Prior", "Next"): + jump = self.listbox.nearest(self.listbox.winfo_height()) - \ + self.listbox.nearest(0) + if keysym == "Prior": + newsel = max(0, cursel-jump) + else: + assert keysym == "Next" + newsel = min(len(self.completions)-1, cursel+jump) + elif keysym == "Up": + newsel = max(0, cursel-1) + else: + assert keysym == "Down" + newsel = min(len(self.completions)-1, cursel+1) + self.listbox.select_clear(cursel) + self.listbox.select_set(newsel) + self._selection_changed() + self._change_start(self.completions[newsel]) + return "break" + + elif (keysym == "Tab" and not state): + if self.lastkey_was_tab: + # two tabs in a row; insert current selection and close acw + cursel = int(self.listbox.curselection()[0]) + self._change_start(self.completions[cursel]) + self.hide_window() + return "break" + else: + # first tab; let AutoComplete handle the completion + self.userwantswindow = True + self.lastkey_was_tab = True + return + + elif any(s in keysym for s in ("Shift", "Control", "Alt", + "Meta", "Command", "Option")): + # A modifier key, so ignore + return + + else: + # Unknown event, close the window and let it through. + self.hide_window() + return + + def keyrelease_event(self, event): + if not self.is_active(): + return + if self.widget.index("insert") != \ + self.widget.index("%s+%dc" % (self.startindex, len(self.start))): + # If we didn't catch an event which moved the insert, close window + self.hide_window() + + def is_active(self): + return self.autocompletewindow is not None + + def complete(self): + self._change_start(self._complete_string(self.start)) + # The selection doesn't change. + + def hide_window(self): + if not self.is_active(): + return + + # unbind events + for seq in HIDE_SEQUENCES: + self.widget.event_delete(HIDE_VIRTUAL_EVENT_NAME, seq) + self.widget.unbind(HIDE_VIRTUAL_EVENT_NAME, self.hideid) + self.hideid = None + for seq in KEYPRESS_SEQUENCES: + self.widget.event_delete(KEYPRESS_VIRTUAL_EVENT_NAME, seq) + self.widget.unbind(KEYPRESS_VIRTUAL_EVENT_NAME, self.keypressid) + self.keypressid = None + self.widget.event_delete(KEYRELEASE_VIRTUAL_EVENT_NAME, + KEYRELEASE_SEQUENCE) + self.widget.unbind(KEYRELEASE_VIRTUAL_EVENT_NAME, self.keyreleaseid) + self.keyreleaseid = None + self.listbox.unbind(LISTUPDATE_SEQUENCE, self.listupdateid) + self.listupdateid = None + self.autocompletewindow.unbind(WINCONFIG_SEQUENCE, self.winconfigid) + self.winconfigid = None + + # destroy widgets + self.scrollbar.destroy() + self.scrollbar = None + self.listbox.destroy() + self.listbox = None + self.autocompletewindow.destroy() + self.autocompletewindow = None diff --git a/PythonHome/Lib/idlelib/AutoCompleteWindow.pyc b/PythonHome/Lib/idlelib/AutoCompleteWindow.pyc deleted file mode 100644 index 2ecee947cbe69cacd6ea2e5d0aba0719b8dc1515..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 12198 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 diff --git a/PythonHome/Lib/idlelib/AutoExpand.py b/PythonHome/Lib/idlelib/AutoExpand.py new file mode 100644 index 0000000000..7059054281 --- /dev/null +++ b/PythonHome/Lib/idlelib/AutoExpand.py @@ -0,0 +1,104 @@ +'''Complete the current word before the cursor with words in the editor. + +Each menu selection or shortcut key selection replaces the word with a +different word with the same prefix. The search for matches begins +before the target and moves toward the top of the editor. It then starts +after the cursor and moves down. It then returns to the original word and +the cycle starts again. + +Changing the current text line or leaving the cursor in a different +place before requesting the next selection causes AutoExpand to reset +its state. + +This is an extension file and there is only one instance of AutoExpand. +''' +import string +import re + +###$ event <> +###$ win +###$ unix + +class AutoExpand: + + menudefs = [ + ('edit', [ + ('E_xpand Word', '<>'), + ]), + ] + + wordchars = string.ascii_letters + string.digits + "_" + + def __init__(self, editwin): + self.text = editwin.text + self.state = None + + def expand_word_event(self, event): + "Replace the current word with the next expansion." + curinsert = self.text.index("insert") + curline = self.text.get("insert linestart", "insert lineend") + if not self.state: + words = self.getwords() + index = 0 + else: + words, index, insert, line = self.state + if insert != curinsert or line != curline: + words = self.getwords() + index = 0 + if not words: + self.text.bell() + return "break" + word = self.getprevword() + self.text.delete("insert - %d chars" % len(word), "insert") + newword = words[index] + index = (index + 1) % len(words) + if index == 0: + self.text.bell() # Warn we cycled around + self.text.insert("insert", newword) + curinsert = self.text.index("insert") + curline = self.text.get("insert linestart", "insert lineend") + self.state = words, index, curinsert, curline + return "break" + + def getwords(self): + "Return a list of words that match the prefix before the cursor." + word = self.getprevword() + if not word: + return [] + before = self.text.get("1.0", "insert wordstart") + wbefore = re.findall(r"\b" + word + r"\w+\b", before) + del before + after = self.text.get("insert wordend", "end") + wafter = re.findall(r"\b" + word + r"\w+\b", after) + del after + if not wbefore and not wafter: + return [] + words = [] + dict = {} + # search backwards through words before + wbefore.reverse() + for w in wbefore: + if dict.get(w): + continue + words.append(w) + dict[w] = w + # search onwards through words after + for w in wafter: + if dict.get(w): + continue + words.append(w) + dict[w] = w + words.append(word) + return words + + def getprevword(self): + "Return the word prefix before the cursor." + line = self.text.get("insert linestart", "insert") + i = len(line) + while i > 0 and line[i-1] in self.wordchars: + i = i-1 + return line[i:] + +if __name__ == '__main__': + import unittest + unittest.main('idlelib.idle_test.test_autoexpand', verbosity=2) diff --git a/PythonHome/Lib/idlelib/AutoExpand.pyc b/PythonHome/Lib/idlelib/AutoExpand.pyc deleted file mode 100644 index 071649913d76f85678ba0a506eec84bbc4025e54..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3412 zcmb7G&2Ah;5U!s6v3GHPAaR@!p$t+23n(jsI3X)Qf)7Y2LgPpg#$hy`>Gh7ip0THU zy|!fMVk9nHcmeJ_1s9$rFTex9_tmVuj$}b%d3&m>yQ-_JzpuI*e_!hM{`_q>j<)MO%SXpLlnjEt;7sO3P`0?8VZbtG%b&mt!xKdd#xHYIDxb|6)JI<+NhEwL@x zYDO&V( z*GV_a2Ln3`LA4CbB|A3Ut?VE_=!Z|Kut|j#5n;HK_;d(g8+J1=vPeop;@2;BBQ7kQQ!#<|ivBMgMGmW&OA+=v`-* zRgOTCQJqB?b-7-8n2r#(x(<`gBrlM)$HSz++|AQfbm!h4_;8dLmI)l$WdGa*hJn;4 z;aQ@(n#t3{s_fp_I)7?W(ADff(q!zAg|ElHTshd~b`Wx9o%P+^I|k=1qIx>aalj7y z4PkE!$HN@t2wzQxI3Ny}#pn%gsV(l;>b z79gy|^`@Tz-R=q$%ga_Z_X)v=550jdPC*Je{XK^4ZlO6cvV|7oh_MzxMFEp&^rXk# z=xRJY6`mk9zD0YcwMUPt$8ik&9D0mvk{3OQqK&%^slWbRzOkNXBRj%(mbd=yp`XWi z9Op&u<2Z!uxIHloMq_54snD38A}mCUn76cioESL{PBn;J>&QtU#|>3B#I2~%WKB6n zJ!#5uONvL+(RFlHbKI8WIXP;}Q6Sr}s^kdW2IcCPi##BVrnujA2*I@I-{9m{8C_df zn?D`Ik+uc9JYubq8>o7S(7^tvCAW?{{NRL_I0JEF212B+skP6T>4xhyQ0b<9;KImJ zr*`(5Ingz-M{I2X8F@$9Mbtf>fqQ@^s%zLQ)SZLls?ru&4vi>?HY%HJySHaE?uYlXFdZh9%ZWfO=#iq3n9GX{IAj+EFrr4mgAPM< z3d9XN8u_>CDJZS`9MKpvRB&(AdSr`;M5^6$0~(Fp$1UMGfYMlRNg<6M3zyE(g(CV_ z54xld5~I2nNl@4c9bJKsG2Opd{Y zIYw1;rus|v{t!aHO?K5vgAZ9cFUuHwM&s6n#>VWu{4e8|@@(oC%rszT8-(B~x-Zd0 zdJTpN5bZqg0!0A$k@)(KR;tvO`00J6H>2LJeMhuD=zn^i8|p!?OqS2}4M!xePd zR}|HkgEI*_MKiO=-(&pTb2QT;sJ8&hKCxz)4x*HLGR!R8prN^Oq#wn`uxTo@5eryIKexyuC$taFlD23 zxj)QFraB;UNO=**S((Oh^f43>-!U3N^dZN&oiQFQbgJ~=(r>sSb+TON_93~iht$Tg LEwrzFkJkJP5J?5o diff --git a/PythonHome/Lib/idlelib/Bindings.py b/PythonHome/Lib/idlelib/Bindings.py new file mode 100644 index 0000000000..df2b251426 --- /dev/null +++ b/PythonHome/Lib/idlelib/Bindings.py @@ -0,0 +1,89 @@ +"""Define the menu contents, hotkeys, and event bindings. + +There is additional configuration information in the EditorWindow class (and +subclasses): the menus are created there based on the menu_specs (class) +variable, and menus not created are silently skipped in the code here. This +makes it possible, for example, to define a Debug menu which is only present in +the PythonShell window, and a Format menu which is only present in the Editor +windows. + +""" +from idlelib.configHandler import idleConf + +# Warning: menudefs is altered in macosxSupport.overrideRootMenu() +# after it is determined that an OS X Aqua Tk is in use, +# which cannot be done until after Tk() is first called. +# Do not alter the 'file', 'options', or 'help' cascades here +# without altering overrideRootMenu() as well. +# TODO: Make this more robust + +menudefs = [ + # underscore prefixes character to underscore + ('file', [ + ('_New File', '<>'), + ('_Open...', '<>'), + ('Open _Module...', '<>'), + ('Class _Browser', '<>'), + ('_Path Browser', '<>'), + None, + ('_Save', '<>'), + ('Save _As...', '<>'), + ('Save Cop_y As...', '<>'), + None, + ('Prin_t Window', '<>'), + None, + ('_Close', '<>'), + ('E_xit', '<>'), + ]), + ('edit', [ + ('_Undo', '<>'), + ('_Redo', '<>'), + None, + ('Cu_t', '<>'), + ('_Copy', '<>'), + ('_Paste', '<>'), + ('Select _All', '<>'), + None, + ('_Find...', '<>'), + ('Find A_gain', '<>'), + ('Find _Selection', '<>'), + ('Find in Files...', '<>'), + ('R_eplace...', '<>'), + ('Go to _Line', '<>'), + ]), +('format', [ + ('_Indent Region', '<>'), + ('_Dedent Region', '<>'), + ('Comment _Out Region', '<>'), + ('U_ncomment Region', '<>'), + ('Tabify Region', '<>'), + ('Untabify Region', '<>'), + ('Toggle Tabs', '<>'), + ('New Indent Width', '<>'), + ]), + ('run', [ + ('Python Shell', '<>'), + ]), + ('shell', [ + ('_View Last Restart', '<>'), + ('_Restart Shell', '<>'), + ]), + ('debug', [ + ('_Go to File/Line', '<>'), + ('!_Debugger', '<>'), + ('_Stack Viewer', '<>'), + ('!_Auto-open Stack Viewer', '<>'), + ]), + ('options', [ + ('_Configure IDLE...', '<>'), + None, + ]), + ('help', [ + ('_About IDLE', '<>'), + None, + ('_IDLE Help', '<>'), + ('Python _Docs', '<>'), + ]), +] + +default_keydefs = idleConf.GetCurrentKeySet() diff --git a/PythonHome/Lib/idlelib/Bindings.pyc b/PythonHome/Lib/idlelib/Bindings.pyc deleted file mode 100644 index e72606cf5106375709099ddc8edfdb4c9ad7c1a2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4565 zcmbtXS##Sq5Qc2$QktXp^-%Q9nJL|ezI8a7I(Dw9n|N%e?qo8!>P#!LXCxbBGg2vFNFG1sIP?jTBvVCex7`83iYkX zJG8zf)OSLCFY+aN+!E>sp`Hr$qfkGIe1(Mfh58wH44BV^`h^1cRjA(r20TAl5qe2H zJ|mvO;m;yqclCEn$e)mqO+7HBmVT(^NSBSwZ0U9B-FtFq{ehmqA}y8Fhai-FQz}#D zZmrwh8|qq1<7BFo@y3>EfwlvaH+727(v$;RkEUzd;RZl$y$@dOSY}1)oLmL(UDx#K zNxN$w9)$v~VTY{Nsn-gn@YGKotiky--o#Zp121HLt$Uc(ChZrRgT@0nSz3SO1wA@b zz*&lkbO)xYz@1@tnN?ciE^AWm4UOxL(gW?J@v^ec8S)AzlKM$Hs&ET$rQ+lNbf5Xoz z)Kd8K@L^P;H=q)J1s(=)Sa$&y$z45`H}UCZc#30N=`t$yIATA&o(3x|H$Bv0UkA(fC>KGCN|~%XjO}&uGlPjzH$BVMDR#qF$wacj zJFP)xt4U-B!TF3KhPz#xGVyYsD(TQw99JOoN3r;`AWSw2>vYg(xNh}$k{ihr;~k%t z)oD=#i0k#Jk{a#~ANxLBAF5UyH?RafWn)JliECH}vyCS4?i>Y{HGYbPvrd8wJRgWD z%f}zT@E-5z93$ji;T#}~YLbCh?Du3- z{~M@C)&lVkZrBkFD9Gx)=EyA{JY!7@$KCEHWspx}c!kc?OvNo6J997Xo55rX<#0X8 zS{$bSe#z1)lBYuxq%9T`xM%ac&=Op`aP2%vB5;98$NJ!y38~sQ$`8YZ&xUE4Yp4+B zW{e6*@iO4+rgSgBe;$mICS$k>G@>dRn32PY8M>F&)Fa8K2DaORPKEHDPir6U*dfRv zb`nkN5)fev&Pae9bFXlelb?h;1Y7NW>JlywbqP+w&?>GA@xKdo2fG|b9H%g(hP;6k zqM-S<>(lH&V%&h7nQstkb`W9Qgnfftt~bz+m}^oSaoFIo@zHT(kJsH+NWzZO zgmi$!tmU1}ts8i2X2&ooBW2RU=8$5f4ajyycPLr!TWC)-3zs)VL4+g&N5YdQsFb(S zg6}>WgKnm($)?SwEfWf=K+@~oU0nhX^AQw7=VvL#&q-AbUWl*QWC7A5gB?0BljRH{ z^?K}X0p?kYqxWFmtgO`!$G}xmb*)o~169 z;+L5KX6j-wb|UrB5p$7z4*Fso^%auKvmDmCA?i7i$QU<2n=yWVN^9ddh1XipspQ5m zVyiH#PouRN^c>vA=*0+*Z5CrWwwaUa7`y=AvB4aq$G`=dkBw#q", "") +CHECKHIDE_VIRTUAL_EVENT_NAME = "<>" +CHECKHIDE_SEQUENCES = ("", "") +CHECKHIDE_TIME = 100 # miliseconds + +MARK_RIGHT = "calltipwindowregion_right" + +class CallTip: + + def __init__(self, widget): + self.widget = widget + self.tipwindow = self.label = None + self.parenline = self.parencol = None + self.lastline = None + self.hideid = self.checkhideid = None + self.checkhide_after_id = None + + def position_window(self): + """Check if needs to reposition the window, and if so - do it.""" + curline = int(self.widget.index("insert").split('.')[0]) + if curline == self.lastline: + return + self.lastline = curline + self.widget.see("insert") + if curline == self.parenline: + box = self.widget.bbox("%d.%d" % (self.parenline, + self.parencol)) + else: + box = self.widget.bbox("%d.0" % curline) + if not box: + box = list(self.widget.bbox("insert")) + # align to left of window + box[0] = 0 + box[2] = 0 + x = box[0] + self.widget.winfo_rootx() + 2 + y = box[1] + box[3] + self.widget.winfo_rooty() + self.tipwindow.wm_geometry("+%d+%d" % (x, y)) + + def showtip(self, text, parenleft, parenright): + """Show the calltip, bind events which will close it and reposition it. + """ + # Only called in CallTips, where lines are truncated + self.text = text + if self.tipwindow or not self.text: + return + + self.widget.mark_set(MARK_RIGHT, parenright) + self.parenline, self.parencol = map( + int, self.widget.index(parenleft).split(".")) + + self.tipwindow = tw = Toplevel(self.widget) + self.position_window() + # remove border on calltip window + tw.wm_overrideredirect(1) + try: + # This command is only needed and available on Tk >= 8.4.0 for OSX + # Without it, call tips intrude on the typing process by grabbing + # the focus. + tw.tk.call("::tk::unsupported::MacWindowStyle", "style", tw._w, + "help", "noActivates") + except TclError: + pass + self.label = Label(tw, text=self.text, justify=LEFT, + background="#ffffe0", relief=SOLID, borderwidth=1, + font = self.widget['font']) + self.label.pack() + + self.checkhideid = self.widget.bind(CHECKHIDE_VIRTUAL_EVENT_NAME, + self.checkhide_event) + for seq in CHECKHIDE_SEQUENCES: + self.widget.event_add(CHECKHIDE_VIRTUAL_EVENT_NAME, seq) + self.widget.after(CHECKHIDE_TIME, self.checkhide_event) + self.hideid = self.widget.bind(HIDE_VIRTUAL_EVENT_NAME, + self.hide_event) + for seq in HIDE_SEQUENCES: + self.widget.event_add(HIDE_VIRTUAL_EVENT_NAME, seq) + + def checkhide_event(self, event=None): + if not self.tipwindow: + # If the event was triggered by the same event that unbinded + # this function, the function will be called nevertheless, + # so do nothing in this case. + return + curline, curcol = map(int, self.widget.index("insert").split('.')) + if curline < self.parenline or \ + (curline == self.parenline and curcol <= self.parencol) or \ + self.widget.compare("insert", ">", MARK_RIGHT): + self.hidetip() + else: + self.position_window() + if self.checkhide_after_id is not None: + self.widget.after_cancel(self.checkhide_after_id) + self.checkhide_after_id = \ + self.widget.after(CHECKHIDE_TIME, self.checkhide_event) + + def hide_event(self, event): + if not self.tipwindow: + # See the explanation in checkhide_event. + return + self.hidetip() + + def hidetip(self): + if not self.tipwindow: + return + + for seq in CHECKHIDE_SEQUENCES: + self.widget.event_delete(CHECKHIDE_VIRTUAL_EVENT_NAME, seq) + self.widget.unbind(CHECKHIDE_VIRTUAL_EVENT_NAME, self.checkhideid) + self.checkhideid = None + for seq in HIDE_SEQUENCES: + self.widget.event_delete(HIDE_VIRTUAL_EVENT_NAME, seq) + self.widget.unbind(HIDE_VIRTUAL_EVENT_NAME, self.hideid) + self.hideid = None + + self.label.destroy() + self.label = None + self.tipwindow.destroy() + self.tipwindow = None + + self.widget.mark_unset(MARK_RIGHT) + self.parenline = self.parencol = self.lastline = None + + def is_active(self): + return bool(self.tipwindow) + + +def _calltip_window(parent): + root = Tk() + root.title("Test calltips") + width, height, x, y = list(map(int, re.split('[x+]', parent.geometry()))) + root.geometry("+%d+%d"%(x, y + 150)) + + class MyEditWin: # comparenceptually an editor_window + def __init__(self): + text = self.text = Text(root) + text.pack(side=LEFT, fill=BOTH, expand=1) + text.insert("insert", "string.split") + root.update() + self.calltip = CallTip(text) + + text.event_add("<>", "(") + text.event_add("<>", ")") + text.bind("<>", self.calltip_show) + text.bind("<>", self.calltip_hide) + + text.focus_set() + root.mainloop() + + def calltip_show(self, event): + self.calltip.showtip("Hello world", "insert", "end") + + def calltip_hide(self, event): + self.calltip.hidetip() + + editwin = MyEditWin() + +if __name__=='__main__': + from idlelib.idle_test.htest import run + run(_calltip_window) diff --git a/PythonHome/Lib/idlelib/CallTipWindow.pyc b/PythonHome/Lib/idlelib/CallTipWindow.pyc deleted file mode 100644 index 3ade0fe92d1dad21e73d6ce3727089a1f909d070..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6200 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 hMHbh6m|db`>;)8c++ON>"), + ]) + ] + + def __init__(self, editwin=None): + if editwin is None: # subprocess and test + self.editwin = None + return + self.editwin = editwin + self.text = editwin.text + self.calltip = None + self._make_calltip_window = self._make_tk_calltip_window + + def close(self): + self._make_calltip_window = None + + def _make_tk_calltip_window(self): + # See __init__ for usage + return CallTipWindow.CallTip(self.text) + + def _remove_calltip_window(self, event=None): + if self.calltip: + self.calltip.hidetip() + self.calltip = None + + def force_open_calltip_event(self, event): + """Happens when the user really wants to open a CallTip, even if a + function call is needed. + """ + self.open_calltip(True) + + def try_open_calltip_event(self, event): + """Happens when it would be nice to open a CallTip, but not really + necessary, for example after an opening bracket, so function calls + won't be made. + """ + self.open_calltip(False) + + def refresh_calltip_event(self, event): + """If there is already a calltip window, check if it is still needed, + and if so, reload it. + """ + if self.calltip and self.calltip.is_active(): + self.open_calltip(False) + + def open_calltip(self, evalfuncs): + self._remove_calltip_window() + + hp = HyperParser(self.editwin, "insert") + sur_paren = hp.get_surrounding_brackets('(') + if not sur_paren: + return + hp.set_index(sur_paren[0]) + expression = hp.get_expression() + if not expression or (not evalfuncs and expression.find('(') != -1): + return + arg_text = self.fetch_tip(expression) + if not arg_text: + return + self.calltip = self._make_calltip_window() + self.calltip.showtip(arg_text, sur_paren[0], sur_paren[1]) + + def fetch_tip(self, expression): + """Return the argument list and docstring of a function or class + + If there is a Python subprocess, get the calltip there. Otherwise, + either fetch_tip() is running in the subprocess itself or it was called + in an IDLE EditorWindow before any script had been run. + + The subprocess environment is that of the most recently run script. If + two unrelated modules are being edited some calltips in the current + module may be inoperative if the module was not the last to run. + + To find methods, fetch_tip must be fed a fully qualified name. + + """ + try: + rpcclt = self.editwin.flist.pyshell.interp.rpcclt + except AttributeError: + rpcclt = None + if rpcclt: + return rpcclt.remotecall("exec", "get_the_calltip", + (expression,), {}) + else: + entity = self.get_entity(expression) + return get_arg_text(entity) + + def get_entity(self, expression): + """Return the object corresponding to expression evaluated + in a namespace spanning sys.modules and __main.dict__. + """ + if expression: + namespace = sys.modules.copy() + namespace.update(__main__.__dict__) + try: + return eval(expression, namespace) + except BaseException: + # An uncaught exception closes idle, and eval can raise any + # exception, especially if user classes are involved. + return None + +def _find_constructor(class_ob): + # Given a class object, return a function object used for the + # constructor (ie, __init__() ) or None if we can't find one. + try: + return class_ob.__init__.im_func + except AttributeError: + for base in class_ob.__bases__: + rc = _find_constructor(base) + if rc is not None: return rc + return None + +# The following are used in get_arg_text +_MAX_COLS = 85 +_MAX_LINES = 5 # enough for bytes +_INDENT = ' '*4 # for wrapped signatures + +def get_arg_text(ob): + '''Return a string describing the signature of a callable object, or ''. + + For Python-coded functions and methods, the first line is introspected. + Delete 'self' parameter for classes (.__init__) and bound methods. + The next lines are the first lines of the doc string up to the first + empty line or _MAX_LINES. For builtins, this typically includes + the arguments in addition to the return value. + ''' + argspec = "" + try: + ob_call = ob.__call__ + except BaseException: + if type(ob) is types.ClassType: # old-style + ob_call = ob + else: + return argspec + + arg_offset = 0 + if type(ob) in (types.ClassType, types.TypeType): + # Look for the first __init__ in the class chain with .im_func. + # Slot wrappers (builtins, classes defined in funcs) do not. + fob = _find_constructor(ob) + if fob is None: + fob = lambda: None + else: + arg_offset = 1 + elif type(ob) == types.MethodType: + # bit of a hack for methods - turn it into a function + # and drop the "self" param for bound methods + fob = ob.im_func + if ob.im_self is not None: + arg_offset = 1 + elif type(ob_call) == types.MethodType: + # a callable class instance + fob = ob_call.im_func + arg_offset = 1 + else: + fob = ob + # Try to build one for Python defined functions + if type(fob) in [types.FunctionType, types.LambdaType]: + argcount = fob.func_code.co_argcount + real_args = fob.func_code.co_varnames[arg_offset:argcount] + defaults = fob.func_defaults or [] + defaults = list(map(lambda name: "=%s" % repr(name), defaults)) + defaults = [""] * (len(real_args) - len(defaults)) + defaults + items = map(lambda arg, dflt: arg + dflt, real_args, defaults) + for flag, pre, name in ((0x4, '*', 'args'), (0x8, '**', 'kwargs')): + if fob.func_code.co_flags & flag: + pre_name = pre + name + if name not in real_args: + items.append(pre_name) + else: + i = 1 + while ((name+'%s') % i) in real_args: + i += 1 + items.append((pre_name+'%s') % i) + argspec = ", ".join(items) + argspec = "(%s)" % re.sub("(?", argspec) + + lines = (textwrap.wrap(argspec, _MAX_COLS, subsequent_indent=_INDENT) + if len(argspec) > _MAX_COLS else [argspec] if argspec else []) + + if isinstance(ob_call, types.MethodType): + doc = ob_call.__doc__ + else: + doc = getattr(ob, "__doc__", "") + if doc: + for line in doc.split('\n', _MAX_LINES)[:_MAX_LINES]: + line = line.strip() + if not line: + break + if len(line) > _MAX_COLS: + line = line[: _MAX_COLS - 3] + '...' + lines.append(line) + argspec = '\n'.join(lines) + return argspec + +if __name__ == '__main__': + from unittest import main + main('idlelib.idle_test.test_calltips', verbosity=2) diff --git a/PythonHome/Lib/idlelib/CallTips.pyc b/PythonHome/Lib/idlelib/CallTips.pyc deleted file mode 100644 index fa5fc61fefd2fd438f19a8929d839aa9db07f683..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 7888 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 diff --git a/PythonHome/Lib/idlelib/ClassBrowser.py b/PythonHome/Lib/idlelib/ClassBrowser.py new file mode 100644 index 0000000000..6183be92ae --- /dev/null +++ b/PythonHome/Lib/idlelib/ClassBrowser.py @@ -0,0 +1,229 @@ +"""Class browser. + +XXX TO DO: + +- reparse when source changed (maybe just a button would be OK?) + (or recheck on window popup) +- add popup menu with more options (e.g. doc strings, base classes, imports) +- show function argument list? (have to do pattern matching on source) +- should the classes and methods lists also be in the module's menu bar? +- add base classes to class browser tree +""" + +import os +import sys +import pyclbr + +from idlelib import PyShell +from idlelib.WindowList import ListedToplevel +from idlelib.TreeWidget import TreeNode, TreeItem, ScrolledCanvas +from idlelib.configHandler import idleConf + +class ClassBrowser: + + def __init__(self, flist, name, path, _htest=False): + # XXX This API should change, if the file doesn't end in ".py" + # XXX the code here is bogus! + """ + _htest - bool, change box when location running htest. + """ + self.name = name + self.file = os.path.join(path[0], self.name + ".py") + self._htest = _htest + self.init(flist) + + def close(self, event=None): + self.top.destroy() + self.node.destroy() + + def init(self, flist): + self.flist = flist + # reset pyclbr + pyclbr._modules.clear() + # create top + self.top = top = ListedToplevel(flist.root) + top.protocol("WM_DELETE_WINDOW", self.close) + top.bind("", self.close) + if self._htest: # place dialog below parent if running htest + top.geometry("+%d+%d" % + (flist.root.winfo_rootx(), flist.root.winfo_rooty() + 200)) + self.settitle() + top.focus_set() + # create scrolled canvas + theme = idleConf.GetOption('main','Theme','name') + background = idleConf.GetHighlight(theme, 'normal')['background'] + sc = ScrolledCanvas(top, bg=background, highlightthickness=0, takefocus=1) + sc.frame.pack(expand=1, fill="both") + item = self.rootnode() + self.node = node = TreeNode(sc.canvas, None, item) + node.update() + node.expand() + + def settitle(self): + self.top.wm_title("Class Browser - " + self.name) + self.top.wm_iconname("Class Browser") + + def rootnode(self): + return ModuleBrowserTreeItem(self.file) + +class ModuleBrowserTreeItem(TreeItem): + + def __init__(self, file): + self.file = file + + def GetText(self): + return os.path.basename(self.file) + + def GetIconName(self): + return "python" + + def GetSubList(self): + sublist = [] + for name in self.listclasses(): + item = ClassBrowserTreeItem(name, self.classes, self.file) + sublist.append(item) + return sublist + + def OnDoubleClick(self): + if os.path.normcase(self.file[-3:]) != ".py": + return + if not os.path.exists(self.file): + return + PyShell.flist.open(self.file) + + def IsExpandable(self): + return os.path.normcase(self.file[-3:]) == ".py" + + def listclasses(self): + dir, file = os.path.split(self.file) + name, ext = os.path.splitext(file) + if os.path.normcase(ext) != ".py": + return [] + try: + dict = pyclbr.readmodule_ex(name, [dir] + sys.path) + except ImportError, msg: + return [] + items = [] + self.classes = {} + for key, cl in dict.items(): + if cl.module == name: + s = key + if hasattr(cl, 'super') and cl.super: + supers = [] + for sup in cl.super: + if type(sup) is type(''): + sname = sup + else: + sname = sup.name + if sup.module != cl.module: + sname = "%s.%s" % (sup.module, sname) + supers.append(sname) + s = s + "(%s)" % ", ".join(supers) + items.append((cl.lineno, s)) + self.classes[s] = cl + items.sort() + list = [] + for item, s in items: + list.append(s) + return list + +class ClassBrowserTreeItem(TreeItem): + + def __init__(self, name, classes, file): + self.name = name + self.classes = classes + self.file = file + try: + self.cl = self.classes[self.name] + except (IndexError, KeyError): + self.cl = None + self.isfunction = isinstance(self.cl, pyclbr.Function) + + def GetText(self): + if self.isfunction: + return "def " + self.name + "(...)" + else: + return "class " + self.name + + def GetIconName(self): + if self.isfunction: + return "python" + else: + return "folder" + + def IsExpandable(self): + if self.cl: + try: + return not not self.cl.methods + except AttributeError: + return False + + def GetSubList(self): + if not self.cl: + return [] + sublist = [] + for name in self.listmethods(): + item = MethodBrowserTreeItem(name, self.cl, self.file) + sublist.append(item) + return sublist + + def OnDoubleClick(self): + if not os.path.exists(self.file): + return + edit = PyShell.flist.open(self.file) + if hasattr(self.cl, 'lineno'): + lineno = self.cl.lineno + edit.gotoline(lineno) + + def listmethods(self): + if not self.cl: + return [] + items = [] + for name, lineno in self.cl.methods.items(): + items.append((lineno, name)) + items.sort() + list = [] + for item, name in items: + list.append(name) + return list + +class MethodBrowserTreeItem(TreeItem): + + def __init__(self, name, cl, file): + self.name = name + self.cl = cl + self.file = file + + def GetText(self): + return "def " + self.name + "(...)" + + def GetIconName(self): + return "python" # XXX + + def IsExpandable(self): + return 0 + + def OnDoubleClick(self): + if not os.path.exists(self.file): + return + edit = PyShell.flist.open(self.file) + edit.gotoline(self.cl.methods[self.name]) + +def _class_browser(parent): #Wrapper for htest + try: + file = __file__ + except NameError: + file = sys.argv[0] + if sys.argv[1:]: + file = sys.argv[1] + else: + file = sys.argv[0] + dir, file = os.path.split(file) + name = os.path.splitext(file)[0] + flist = PyShell.PyShellFileList(parent) + ClassBrowser(flist, name, [dir], _htest=True) + parent.mainloop() + +if __name__ == "__main__": + from idlelib.idle_test.htest import run + run(_class_browser) diff --git a/PythonHome/Lib/idlelib/ClassBrowser.pyc b/PythonHome/Lib/idlelib/ClassBrowser.pyc deleted file mode 100644 index be5ef0b6391e1700c7b10a78b042a38ae1a97222..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 9054 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 diff --git a/PythonHome/Lib/idlelib/CodeContext.py b/PythonHome/Lib/idlelib/CodeContext.py new file mode 100644 index 0000000000..2f6f737b67 --- /dev/null +++ b/PythonHome/Lib/idlelib/CodeContext.py @@ -0,0 +1,176 @@ +"""CodeContext - Extension to display the block context above the edit window + +Once code has scrolled off the top of a window, it can be difficult to +determine which block you are in. This extension implements a pane at the top +of each IDLE edit window which provides block structure hints. These hints are +the lines which contain the block opening keywords, e.g. 'if', for the +enclosing block. The number of hint lines is determined by the numlines +variable in the CodeContext section of config-extensions.def. Lines which do +not open blocks are not shown in the context hints pane. + +""" +import Tkinter +from Tkconstants import TOP, LEFT, X, W, SUNKEN +import re +from sys import maxint as INFINITY +from idlelib.configHandler import idleConf + +BLOCKOPENERS = set(["class", "def", "elif", "else", "except", "finally", "for", + "if", "try", "while", "with"]) +UPDATEINTERVAL = 100 # millisec +FONTUPDATEINTERVAL = 1000 # millisec + +getspacesfirstword =\ + lambda s, c=re.compile(r"^(\s*)(\w*)"): c.match(s).groups() + +class CodeContext: + menudefs = [('options', [('!Code Conte_xt', '<>')])] + context_depth = idleConf.GetOption("extensions", "CodeContext", + "numlines", type="int", default=3) + bgcolor = idleConf.GetOption("extensions", "CodeContext", + "bgcolor", type="str", default="LightGray") + fgcolor = idleConf.GetOption("extensions", "CodeContext", + "fgcolor", type="str", default="Black") + def __init__(self, editwin): + self.editwin = editwin + self.text = editwin.text + self.textfont = self.text["font"] + self.label = None + # self.info is a list of (line number, indent level, line text, block + # keyword) tuples providing the block structure associated with + # self.topvisible (the linenumber of the line displayed at the top of + # the edit window). self.info[0] is initialized as a 'dummy' line which + # starts the toplevel 'block' of the module. + self.info = [(0, -1, "", False)] + self.topvisible = 1 + visible = idleConf.GetOption("extensions", "CodeContext", + "visible", type="bool", default=False) + if visible: + self.toggle_code_context_event() + self.editwin.setvar('<>', True) + # Start two update cycles, one for context lines, one for font changes. + self.text.after(UPDATEINTERVAL, self.timer_event) + self.text.after(FONTUPDATEINTERVAL, self.font_timer_event) + + def toggle_code_context_event(self, event=None): + if not self.label: + # Calculate the border width and horizontal padding required to + # align the context with the text in the main Text widget. + # + # All values are passed through int(str()), since some + # values may be pixel objects, which can't simply be added to ints. + widgets = self.editwin.text, self.editwin.text_frame + # Calculate the required vertical padding + padx = 0 + for widget in widgets: + padx += int(str( widget.pack_info()['padx'] )) + padx += int(str( widget.cget('padx') )) + # Calculate the required border width + border = 0 + for widget in widgets: + border += int(str( widget.cget('border') )) + self.label = Tkinter.Label(self.editwin.top, + text="\n" * (self.context_depth - 1), + anchor=W, justify=LEFT, + font=self.textfont, + bg=self.bgcolor, fg=self.fgcolor, + width=1, #don't request more than we get + padx=padx, border=border, + relief=SUNKEN) + # Pack the label widget before and above the text_frame widget, + # thus ensuring that it will appear directly above text_frame + self.label.pack(side=TOP, fill=X, expand=False, + before=self.editwin.text_frame) + else: + self.label.destroy() + self.label = None + idleConf.SetOption("extensions", "CodeContext", "visible", + str(self.label is not None)) + idleConf.SaveUserCfgFiles() + + def get_line_info(self, linenum): + """Get the line indent value, text, and any block start keyword + + If the line does not start a block, the keyword value is False. + The indentation of empty lines (or comment lines) is INFINITY. + + """ + text = self.text.get("%d.0" % linenum, "%d.end" % linenum) + spaces, firstword = getspacesfirstword(text) + opener = firstword in BLOCKOPENERS and firstword + if len(text) == len(spaces) or text[len(spaces)] == '#': + indent = INFINITY + else: + indent = len(spaces) + return indent, text, opener + + def get_context(self, new_topvisible, stopline=1, stopindent=0): + """Get context lines, starting at new_topvisible and working backwards. + + Stop when stopline or stopindent is reached. Return a tuple of context + data and the indent level at the top of the region inspected. + + """ + assert stopline > 0 + lines = [] + # The indentation level we are currently in: + lastindent = INFINITY + # For a line to be interesting, it must begin with a block opening + # keyword, and have less indentation than lastindent. + for linenum in xrange(new_topvisible, stopline-1, -1): + indent, text, opener = self.get_line_info(linenum) + if indent < lastindent: + lastindent = indent + if opener in ("else", "elif"): + # We also show the if statement + lastindent += 1 + if opener and linenum < new_topvisible and indent >= stopindent: + lines.append((linenum, indent, text, opener)) + if lastindent <= stopindent: + break + lines.reverse() + return lines, lastindent + + def update_code_context(self): + """Update context information and lines visible in the context pane. + + """ + new_topvisible = int(self.text.index("@0,0").split('.')[0]) + if self.topvisible == new_topvisible: # haven't scrolled + return + if self.topvisible < new_topvisible: # scroll down + lines, lastindent = self.get_context(new_topvisible, + self.topvisible) + # retain only context info applicable to the region + # between topvisible and new_topvisible: + while self.info[-1][1] >= lastindent: + del self.info[-1] + elif self.topvisible > new_topvisible: # scroll up + stopindent = self.info[-1][1] + 1 + # retain only context info associated + # with lines above new_topvisible: + while self.info[-1][0] >= new_topvisible: + stopindent = self.info[-1][1] + del self.info[-1] + lines, lastindent = self.get_context(new_topvisible, + self.info[-1][0]+1, + stopindent) + self.info.extend(lines) + self.topvisible = new_topvisible + # empty lines in context pane: + context_strings = [""] * max(0, self.context_depth - len(self.info)) + # followed by the context hint lines: + context_strings += [x[2] for x in self.info[-self.context_depth:]] + self.label["text"] = '\n'.join(context_strings) + + def timer_event(self): + if self.label: + self.update_code_context() + self.text.after(UPDATEINTERVAL, self.timer_event) + + def font_timer_event(self): + newtextfont = self.text["font"] + if self.label and newtextfont != self.textfont: + self.textfont = newtextfont + self.label["font"] = self.textfont + self.text.after(FONTUPDATEINTERVAL, self.font_timer_event) diff --git a/PythonHome/Lib/idlelib/CodeContext.pyc b/PythonHome/Lib/idlelib/CodeContext.pyc deleted file mode 100644 index 75782dba9db07794ff67aa517dd791bbf066d5c9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6522 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 diff --git a/PythonHome/Lib/idlelib/ColorDelegator.py b/PythonHome/Lib/idlelib/ColorDelegator.py new file mode 100644 index 0000000000..0c625d3c5b --- /dev/null +++ b/PythonHome/Lib/idlelib/ColorDelegator.py @@ -0,0 +1,275 @@ +import time +import re +import keyword +import __builtin__ +from Tkinter import * +from idlelib.Delegator import Delegator +from idlelib.configHandler import idleConf + +DEBUG = False + +def any(name, alternates): + "Return a named group pattern matching list of alternates." + return "(?P<%s>" % name + "|".join(alternates) + ")" + +def make_pat(): + kw = r"\b" + any("KEYWORD", keyword.kwlist) + r"\b" + builtinlist = [str(name) for name in dir(__builtin__) + if not name.startswith('_')] + # We don't know whether "print" is a function or a keyword, + # so we always treat is as a keyword (the most common case). + builtinlist.remove('print') + # self.file = file("file") : + # 1st 'file' colorized normal, 2nd as builtin, 3rd as string + builtin = r"([^.'\"\\#]\b|^)" + any("BUILTIN", builtinlist) + r"\b" + comment = any("COMMENT", [r"#[^\n]*"]) + stringprefix = r"(\br|u|ur|R|U|UR|Ur|uR|b|B|br|Br|bR|BR)?" + sqstring = stringprefix + r"'[^'\\\n]*(\\.[^'\\\n]*)*'?" + dqstring = stringprefix + r'"[^"\\\n]*(\\.[^"\\\n]*)*"?' + sq3string = stringprefix + r"'''[^'\\]*((\\.|'(?!''))[^'\\]*)*(''')?" + dq3string = stringprefix + r'"""[^"\\]*((\\.|"(?!""))[^"\\]*)*(""")?' + string = any("STRING", [sq3string, dq3string, sqstring, dqstring]) + return kw + "|" + builtin + "|" + comment + "|" + string +\ + "|" + any("SYNC", [r"\n"]) + +prog = re.compile(make_pat(), re.S) +idprog = re.compile(r"\s+(\w+)", re.S) +asprog = re.compile(r".*?\b(as)\b") + +class ColorDelegator(Delegator): + + def __init__(self): + Delegator.__init__(self) + self.prog = prog + self.idprog = idprog + self.asprog = asprog + self.LoadTagDefs() + + def setdelegate(self, delegate): + if self.delegate is not None: + self.unbind("<>") + Delegator.setdelegate(self, delegate) + if delegate is not None: + self.config_colors() + self.bind("<>", self.toggle_colorize_event) + self.notify_range("1.0", "end") + else: + # No delegate - stop any colorizing + self.stop_colorizing = True + self.allow_colorizing = False + + def config_colors(self): + for tag, cnf in self.tagdefs.items(): + if cnf: + self.tag_configure(tag, **cnf) + self.tag_raise('sel') + + def LoadTagDefs(self): + theme = idleConf.GetOption('main','Theme','name') + self.tagdefs = { + "COMMENT": idleConf.GetHighlight(theme, "comment"), + "KEYWORD": idleConf.GetHighlight(theme, "keyword"), + "BUILTIN": idleConf.GetHighlight(theme, "builtin"), + "STRING": idleConf.GetHighlight(theme, "string"), + "DEFINITION": idleConf.GetHighlight(theme, "definition"), + "SYNC": {'background':None,'foreground':None}, + "TODO": {'background':None,'foreground':None}, + "BREAK": idleConf.GetHighlight(theme, "break"), + "ERROR": idleConf.GetHighlight(theme, "error"), + # The following is used by ReplaceDialog: + "hit": idleConf.GetHighlight(theme, "hit"), + } + + if DEBUG: print 'tagdefs',self.tagdefs + + def insert(self, index, chars, tags=None): + index = self.index(index) + self.delegate.insert(index, chars, tags) + self.notify_range(index, index + "+%dc" % len(chars)) + + def delete(self, index1, index2=None): + index1 = self.index(index1) + self.delegate.delete(index1, index2) + self.notify_range(index1) + + after_id = None + allow_colorizing = True + colorizing = False + + def notify_range(self, index1, index2=None): + self.tag_add("TODO", index1, index2) + if self.after_id: + if DEBUG: print "colorizing already scheduled" + return + if self.colorizing: + self.stop_colorizing = True + if DEBUG: print "stop colorizing" + if self.allow_colorizing: + if DEBUG: print "schedule colorizing" + self.after_id = self.after(1, self.recolorize) + + close_when_done = None # Window to be closed when done colorizing + + def close(self, close_when_done=None): + if self.after_id: + after_id = self.after_id + self.after_id = None + if DEBUG: print "cancel scheduled recolorizer" + self.after_cancel(after_id) + self.allow_colorizing = False + self.stop_colorizing = True + if close_when_done: + if not self.colorizing: + close_when_done.destroy() + else: + self.close_when_done = close_when_done + + def toggle_colorize_event(self, event): + if self.after_id: + after_id = self.after_id + self.after_id = None + if DEBUG: print "cancel scheduled recolorizer" + self.after_cancel(after_id) + if self.allow_colorizing and self.colorizing: + if DEBUG: print "stop colorizing" + self.stop_colorizing = True + self.allow_colorizing = not self.allow_colorizing + if self.allow_colorizing and not self.colorizing: + self.after_id = self.after(1, self.recolorize) + if DEBUG: + print "auto colorizing turned",\ + self.allow_colorizing and "on" or "off" + return "break" + + def recolorize(self): + self.after_id = None + if not self.delegate: + if DEBUG: print "no delegate" + return + if not self.allow_colorizing: + if DEBUG: print "auto colorizing is off" + return + if self.colorizing: + if DEBUG: print "already colorizing" + return + try: + self.stop_colorizing = False + self.colorizing = True + if DEBUG: print "colorizing..." + t0 = time.clock() + self.recolorize_main() + t1 = time.clock() + if DEBUG: print "%.3f seconds" % (t1-t0) + finally: + self.colorizing = False + if self.allow_colorizing and self.tag_nextrange("TODO", "1.0"): + if DEBUG: print "reschedule colorizing" + self.after_id = self.after(1, self.recolorize) + if self.close_when_done: + top = self.close_when_done + self.close_when_done = None + top.destroy() + + def recolorize_main(self): + next = "1.0" + while True: + item = self.tag_nextrange("TODO", next) + if not item: + break + head, tail = item + self.tag_remove("SYNC", head, tail) + item = self.tag_prevrange("SYNC", head) + if item: + head = item[1] + else: + head = "1.0" + + chars = "" + next = head + lines_to_get = 1 + ok = False + while not ok: + mark = next + next = self.index(mark + "+%d lines linestart" % + lines_to_get) + lines_to_get = min(lines_to_get * 2, 100) + ok = "SYNC" in self.tag_names(next + "-1c") + line = self.get(mark, next) + ##print head, "get", mark, next, "->", repr(line) + if not line: + return + for tag in self.tagdefs.keys(): + self.tag_remove(tag, mark, next) + chars = chars + line + m = self.prog.search(chars) + while m: + for key, value in m.groupdict().items(): + if value: + a, b = m.span(key) + self.tag_add(key, + head + "+%dc" % a, + head + "+%dc" % b) + if value in ("def", "class"): + m1 = self.idprog.match(chars, b) + if m1: + a, b = m1.span(1) + self.tag_add("DEFINITION", + head + "+%dc" % a, + head + "+%dc" % b) + elif value == "import": + # color all the "as" words on same line, except + # if in a comment; cheap approximation to the + # truth + if '#' in chars: + endpos = chars.index('#') + else: + endpos = len(chars) + while True: + m1 = self.asprog.match(chars, b, endpos) + if not m1: + break + a, b = m1.span(1) + self.tag_add("KEYWORD", + head + "+%dc" % a, + head + "+%dc" % b) + m = self.prog.search(chars, m.end()) + if "SYNC" in self.tag_names(next + "-1c"): + head = next + chars = "" + else: + ok = False + if not ok: + # We're in an inconsistent state, and the call to + # update may tell us to stop. It may also change + # the correct value for "next" (since this is a + # line.col string, not a true mark). So leave a + # crumb telling the next invocation to resume here + # in case update tells us to leave. + self.tag_add("TODO", next) + self.update() + if self.stop_colorizing: + if DEBUG: print "colorizing stopped" + return + + def removecolors(self): + for tag in self.tagdefs.keys(): + self.tag_remove(tag, "1.0", "end") + +def _color_delegator(parent): + from idlelib.Percolator import Percolator + root = Tk() + root.title("Test ColorDelegator") + width, height, x, y = list(map(int, re.split('[x+]', parent.geometry()))) + root.geometry("+%d+%d"%(x, y + 150)) + source = "if somename: x = 'abc' # comment\nprint" + text = Text(root, background="white") + text.insert("insert", source) + text.pack(expand=1, fill="both") + p = Percolator(text) + d = ColorDelegator() + p.insertfilter(d) + root.mainloop() + +if __name__ == "__main__": + from idlelib.idle_test.htest import run + run(_color_delegator) diff --git a/PythonHome/Lib/idlelib/ColorDelegator.pyc b/PythonHome/Lib/idlelib/ColorDelegator.pyc deleted file mode 100644 index f9e34154d1f7801740b28e2c5636e7d81480eed5..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 9036 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 L{@)8zMfCn37ALmq diff --git a/PythonHome/Lib/idlelib/Debugger.py b/PythonHome/Lib/idlelib/Debugger.py new file mode 100644 index 0000000000..94a8cb2514 --- /dev/null +++ b/PythonHome/Lib/idlelib/Debugger.py @@ -0,0 +1,481 @@ +import os +import bdb +import types +from Tkinter import * +from idlelib.WindowList import ListedToplevel +from idlelib.ScrolledList import ScrolledList +from idlelib import macosxSupport + + +class Idb(bdb.Bdb): + + def __init__(self, gui): + self.gui = gui + bdb.Bdb.__init__(self) + + def user_line(self, frame): + if self.in_rpc_code(frame): + self.set_step() + return + message = self.__frame2message(frame) + self.gui.interaction(message, frame) + + def user_exception(self, frame, info): + if self.in_rpc_code(frame): + self.set_step() + return + message = self.__frame2message(frame) + self.gui.interaction(message, frame, info) + + def in_rpc_code(self, frame): + if frame.f_code.co_filename.count('rpc.py'): + return True + else: + prev_frame = frame.f_back + if prev_frame.f_code.co_filename.count('Debugger.py'): + # (that test will catch both Debugger.py and RemoteDebugger.py) + return False + return self.in_rpc_code(prev_frame) + + def __frame2message(self, frame): + code = frame.f_code + filename = code.co_filename + lineno = frame.f_lineno + basename = os.path.basename(filename) + message = "%s:%s" % (basename, lineno) + if code.co_name != "?": + message = "%s: %s()" % (message, code.co_name) + return message + + +class Debugger: + + vstack = vsource = vlocals = vglobals = None + + def __init__(self, pyshell, idb=None): + if idb is None: + idb = Idb(self) + self.pyshell = pyshell + self.idb = idb + self.frame = None + self.make_gui() + self.interacting = 0 + + def run(self, *args): + try: + self.interacting = 1 + return self.idb.run(*args) + finally: + self.interacting = 0 + + def close(self, event=None): + if self.interacting: + self.top.bell() + return + if self.stackviewer: + self.stackviewer.close(); self.stackviewer = None + # Clean up pyshell if user clicked debugger control close widget. + # (Causes a harmless extra cycle through close_debugger() if user + # toggled debugger from pyshell Debug menu) + self.pyshell.close_debugger() + # Now close the debugger control window.... + self.top.destroy() + + def make_gui(self): + pyshell = self.pyshell + self.flist = pyshell.flist + self.root = root = pyshell.root + self.top = top = ListedToplevel(root) + self.top.wm_title("Debug Control") + self.top.wm_iconname("Debug") + top.wm_protocol("WM_DELETE_WINDOW", self.close) + self.top.bind("", self.close) + # + self.bframe = bframe = Frame(top) + self.bframe.pack(anchor="w") + self.buttons = bl = [] + # + self.bcont = b = Button(bframe, text="Go", command=self.cont) + bl.append(b) + self.bstep = b = Button(bframe, text="Step", command=self.step) + bl.append(b) + self.bnext = b = Button(bframe, text="Over", command=self.next) + bl.append(b) + self.bret = b = Button(bframe, text="Out", command=self.ret) + bl.append(b) + self.bret = b = Button(bframe, text="Quit", command=self.quit) + bl.append(b) + # + for b in bl: + b.configure(state="disabled") + b.pack(side="left") + # + self.cframe = cframe = Frame(bframe) + self.cframe.pack(side="left") + # + if not self.vstack: + self.__class__.vstack = BooleanVar(top) + self.vstack.set(1) + self.bstack = Checkbutton(cframe, + text="Stack", command=self.show_stack, variable=self.vstack) + self.bstack.grid(row=0, column=0) + if not self.vsource: + self.__class__.vsource = BooleanVar(top) + self.bsource = Checkbutton(cframe, + text="Source", command=self.show_source, variable=self.vsource) + self.bsource.grid(row=0, column=1) + if not self.vlocals: + self.__class__.vlocals = BooleanVar(top) + self.vlocals.set(1) + self.blocals = Checkbutton(cframe, + text="Locals", command=self.show_locals, variable=self.vlocals) + self.blocals.grid(row=1, column=0) + if not self.vglobals: + self.__class__.vglobals = BooleanVar(top) + self.bglobals = Checkbutton(cframe, + text="Globals", command=self.show_globals, variable=self.vglobals) + self.bglobals.grid(row=1, column=1) + # + self.status = Label(top, anchor="w") + self.status.pack(anchor="w") + self.error = Label(top, anchor="w") + self.error.pack(anchor="w", fill="x") + self.errorbg = self.error.cget("background") + # + self.fstack = Frame(top, height=1) + self.fstack.pack(expand=1, fill="both") + self.flocals = Frame(top) + self.flocals.pack(expand=1, fill="both") + self.fglobals = Frame(top, height=1) + self.fglobals.pack(expand=1, fill="both") + # + if self.vstack.get(): + self.show_stack() + if self.vlocals.get(): + self.show_locals() + if self.vglobals.get(): + self.show_globals() + + def interaction(self, message, frame, info=None): + self.frame = frame + self.status.configure(text=message) + # + if info: + type, value, tb = info + try: + m1 = type.__name__ + except AttributeError: + m1 = "%s" % str(type) + if value is not None: + try: + m1 = "%s: %s" % (m1, str(value)) + except: + pass + bg = "yellow" + else: + m1 = "" + tb = None + bg = self.errorbg + self.error.configure(text=m1, background=bg) + # + sv = self.stackviewer + if sv: + stack, i = self.idb.get_stack(self.frame, tb) + sv.load_stack(stack, i) + # + self.show_variables(1) + # + if self.vsource.get(): + self.sync_source_line() + # + for b in self.buttons: + b.configure(state="normal") + # + self.top.wakeup() + self.root.mainloop() + # + for b in self.buttons: + b.configure(state="disabled") + self.status.configure(text="") + self.error.configure(text="", background=self.errorbg) + self.frame = None + + def sync_source_line(self): + frame = self.frame + if not frame: + return + filename, lineno = self.__frame2fileline(frame) + if filename[:1] + filename[-1:] != "<>" and os.path.exists(filename): + self.flist.gotofileline(filename, lineno) + + def __frame2fileline(self, frame): + code = frame.f_code + filename = code.co_filename + lineno = frame.f_lineno + return filename, lineno + + def cont(self): + self.idb.set_continue() + self.root.quit() + + def step(self): + self.idb.set_step() + self.root.quit() + + def next(self): + self.idb.set_next(self.frame) + self.root.quit() + + def ret(self): + self.idb.set_return(self.frame) + self.root.quit() + + def quit(self): + self.idb.set_quit() + self.root.quit() + + stackviewer = None + + def show_stack(self): + if not self.stackviewer and self.vstack.get(): + self.stackviewer = sv = StackViewer(self.fstack, self.flist, self) + if self.frame: + stack, i = self.idb.get_stack(self.frame, None) + sv.load_stack(stack, i) + else: + sv = self.stackviewer + if sv and not self.vstack.get(): + self.stackviewer = None + sv.close() + self.fstack['height'] = 1 + + def show_source(self): + if self.vsource.get(): + self.sync_source_line() + + def show_frame(self, stackitem): + self.frame = stackitem[0] # lineno is stackitem[1] + self.show_variables() + + localsviewer = None + globalsviewer = None + + def show_locals(self): + lv = self.localsviewer + if self.vlocals.get(): + if not lv: + self.localsviewer = NamespaceViewer(self.flocals, "Locals") + else: + if lv: + self.localsviewer = None + lv.close() + self.flocals['height'] = 1 + self.show_variables() + + def show_globals(self): + gv = self.globalsviewer + if self.vglobals.get(): + if not gv: + self.globalsviewer = NamespaceViewer(self.fglobals, "Globals") + else: + if gv: + self.globalsviewer = None + gv.close() + self.fglobals['height'] = 1 + self.show_variables() + + def show_variables(self, force=0): + lv = self.localsviewer + gv = self.globalsviewer + frame = self.frame + if not frame: + ldict = gdict = None + else: + ldict = frame.f_locals + gdict = frame.f_globals + if lv and gv and ldict is gdict: + ldict = None + if lv: + lv.load_dict(ldict, force, self.pyshell.interp.rpcclt) + if gv: + gv.load_dict(gdict, force, self.pyshell.interp.rpcclt) + + def set_breakpoint_here(self, filename, lineno): + self.idb.set_break(filename, lineno) + + def clear_breakpoint_here(self, filename, lineno): + self.idb.clear_break(filename, lineno) + + def clear_file_breaks(self, filename): + self.idb.clear_all_file_breaks(filename) + + def load_breakpoints(self): + "Load PyShellEditorWindow breakpoints into subprocess debugger" + pyshell_edit_windows = self.pyshell.flist.inversedict.keys() + for editwin in pyshell_edit_windows: + filename = editwin.io.filename + try: + for lineno in editwin.breakpoints: + self.set_breakpoint_here(filename, lineno) + except AttributeError: + continue + +class StackViewer(ScrolledList): + + def __init__(self, master, flist, gui): + if macosxSupport.isAquaTk(): + # At least on with the stock AquaTk version on OSX 10.4 you'll + # get an shaking GUI that eventually kills IDLE if the width + # argument is specified. + ScrolledList.__init__(self, master) + else: + ScrolledList.__init__(self, master, width=80) + self.flist = flist + self.gui = gui + self.stack = [] + + def load_stack(self, stack, index=None): + self.stack = stack + self.clear() + for i in range(len(stack)): + frame, lineno = stack[i] + try: + modname = frame.f_globals["__name__"] + except: + modname = "?" + code = frame.f_code + filename = code.co_filename + funcname = code.co_name + import linecache + sourceline = linecache.getline(filename, lineno) + import string + sourceline = string.strip(sourceline) + if funcname in ("?", "", None): + item = "%s, line %d: %s" % (modname, lineno, sourceline) + else: + item = "%s.%s(), line %d: %s" % (modname, funcname, + lineno, sourceline) + if i == index: + item = "> " + item + self.append(item) + if index is not None: + self.select(index) + + def popup_event(self, event): + "override base method" + if self.stack: + return ScrolledList.popup_event(self, event) + + def fill_menu(self): + "override base method" + menu = self.menu + menu.add_command(label="Go to source line", + command=self.goto_source_line) + menu.add_command(label="Show stack frame", + command=self.show_stack_frame) + + def on_select(self, index): + "override base method" + if 0 <= index < len(self.stack): + self.gui.show_frame(self.stack[index]) + + def on_double(self, index): + "override base method" + self.show_source(index) + + def goto_source_line(self): + index = self.listbox.index("active") + self.show_source(index) + + def show_stack_frame(self): + index = self.listbox.index("active") + if 0 <= index < len(self.stack): + self.gui.show_frame(self.stack[index]) + + def show_source(self, index): + if not (0 <= index < len(self.stack)): + return + frame, lineno = self.stack[index] + code = frame.f_code + filename = code.co_filename + if os.path.isfile(filename): + edit = self.flist.open(filename) + if edit: + edit.gotoline(lineno) + + +class NamespaceViewer: + + def __init__(self, master, title, dict=None): + width = 0 + height = 40 + if dict: + height = 20*len(dict) # XXX 20 == observed height of Entry widget + self.master = master + self.title = title + import repr + self.repr = repr.Repr() + self.repr.maxstring = 60 + self.repr.maxother = 60 + self.frame = frame = Frame(master) + self.frame.pack(expand=1, fill="both") + self.label = Label(frame, text=title, borderwidth=2, relief="groove") + self.label.pack(fill="x") + self.vbar = vbar = Scrollbar(frame, name="vbar") + vbar.pack(side="right", fill="y") + self.canvas = canvas = Canvas(frame, + height=min(300, max(40, height)), + scrollregion=(0, 0, width, height)) + canvas.pack(side="left", fill="both", expand=1) + vbar["command"] = canvas.yview + canvas["yscrollcommand"] = vbar.set + self.subframe = subframe = Frame(canvas) + self.sfid = canvas.create_window(0, 0, window=subframe, anchor="nw") + self.load_dict(dict) + + dict = -1 + + def load_dict(self, dict, force=0, rpc_client=None): + if dict is self.dict and not force: + return + subframe = self.subframe + frame = self.frame + for c in subframe.children.values(): + c.destroy() + self.dict = None + if not dict: + l = Label(subframe, text="None") + l.grid(row=0, column=0) + else: + names = dict.keys() + names.sort() + row = 0 + for name in names: + value = dict[name] + svalue = self.repr.repr(value) # repr(value) + # Strip extra quotes caused by calling repr on the (already) + # repr'd value sent across the RPC interface: + if rpc_client: + svalue = svalue[1:-1] + l = Label(subframe, text=name) + l.grid(row=row, column=0, sticky="nw") + l = Entry(subframe, width=0, borderwidth=0) + l.insert(0, svalue) + l.grid(row=row, column=1, sticky="nw") + row = row+1 + self.dict = dict + # XXX Could we use a callback for the following? + subframe.update_idletasks() # Alas! + width = subframe.winfo_reqwidth() + height = subframe.winfo_reqheight() + canvas = self.canvas + self.canvas["scrollregion"] = (0, 0, width, height) + if height > 300: + canvas["height"] = 300 + frame.pack(expand=1) + else: + canvas["height"] = height + frame.pack(expand=0) + + def close(self): + self.frame.destroy() diff --git a/PythonHome/Lib/idlelib/Debugger.pyc b/PythonHome/Lib/idlelib/Debugger.pyc deleted file mode 100644 index 453e1e052a259a1d9694bdbd72fd503ae7617d7c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 16270 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 diff --git a/PythonHome/Lib/idlelib/Delegator.py b/PythonHome/Lib/idlelib/Delegator.py new file mode 100644 index 0000000000..c4765163f8 --- /dev/null +++ b/PythonHome/Lib/idlelib/Delegator.py @@ -0,0 +1,25 @@ +class Delegator: + + # The cache is only used to be able to change delegates! + + def __init__(self, delegate=None): + self.delegate = delegate + self.__cache = set() + + def __getattr__(self, name): + attr = getattr(self.delegate, name) # May raise AttributeError + setattr(self, name, attr) + self.__cache.add(name) + return attr + + def resetcache(self): + for key in self.__cache: + try: + delattr(self, key) + except AttributeError: + pass + self.__cache.clear() + + def setdelegate(self, delegate): + self.resetcache() + self.delegate = delegate diff --git a/PythonHome/Lib/idlelib/Delegator.pyc b/PythonHome/Lib/idlelib/Delegator.pyc deleted file mode 100644 index 29e79587f08ddbc047f40065f5a7f17eb7f44216..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1178 zcmb7DO>fgc5S_K%Gzl#COb3l&5Ywe`~BbJucJa%pBT?KIPDXN62DkVBex<;kE}g-(AWAKG7@nw~RSb zoFLj~&<;;OR%fSGS-Tp~P5j}Hg_g0lnpNIfB5s*SOwTBE)}`YZr#*u33U>+ufF8+B zBt9YmQi^05i-9qXWt!*>1Dib#yqMqbLYzCFd*3Kjb%2{XlsQFSmfD7l)s@>UzjUhb z;@$Z@K)ki9g4S}*En6$*u{prEAT&0xgQGM*K>2k|MO*3!2ZcXj-MyDF+ zGw#AI?oPUofX1Pzx*v~VwR;c(zOfmYebWu&{bw`zjs*C`zS>bN{FVf-X9pCzV`?g~ z`>h;D0&MH$X5H1+_02G4e^y(`kz4D@#@fqyc~#S7#o>JBGPWvXvVe*2#', self.destroy, '+') + + def nearwindow(self, near): + # Place the help dialog near the window specified by parent. + # Note - this may not reposition the window in Metacity + # if "/apps/metacity/general/disable_workarounds" is enabled + dlg = self.dlg + geom = (near.winfo_rootx() + 10, near.winfo_rooty() + 10) + dlg.withdraw() + dlg.geometry("=+%d+%d" % geom) + dlg.deiconify() + dlg.lift() + + def destroy(self, ev=None): + self.dlg = None + self.parent = None + +helpDialog = HelpDialog() # singleton instance +def _help_dialog(parent): # wrapper for htest + helpDialog.show_dialog(parent) + + +class EditorWindow(object): + from idlelib.Percolator import Percolator + from idlelib.ColorDelegator import ColorDelegator + from idlelib.UndoDelegator import UndoDelegator + from idlelib.IOBinding import IOBinding, filesystemencoding, encoding + from idlelib import Bindings + from Tkinter import Toplevel + from idlelib.MultiStatusBar import MultiStatusBar + + help_url = None + + def __init__(self, flist=None, filename=None, key=None, root=None): + if EditorWindow.help_url is None: + dochome = os.path.join(sys.prefix, 'Doc', 'index.html') + if sys.platform.count('linux'): + # look for html docs in a couple of standard places + pyver = 'python-docs-' + '%s.%s.%s' % sys.version_info[:3] + if os.path.isdir('/var/www/html/python/'): # "python2" rpm + dochome = '/var/www/html/python/index.html' + else: + basepath = '/usr/share/doc/' # standard location + dochome = os.path.join(basepath, pyver, + 'Doc', 'index.html') + elif sys.platform[:3] == 'win': + chmfile = os.path.join(sys.prefix, 'Doc', + 'Python%s.chm' % _sphinx_version()) + if os.path.isfile(chmfile): + dochome = chmfile + elif sys.platform == 'darwin': + # documentation may be stored inside a python framework + dochome = os.path.join(sys.prefix, + 'Resources/English.lproj/Documentation/index.html') + dochome = os.path.normpath(dochome) + if os.path.isfile(dochome): + EditorWindow.help_url = dochome + if sys.platform == 'darwin': + # Safari requires real file:-URLs + EditorWindow.help_url = 'file://' + EditorWindow.help_url + else: + EditorWindow.help_url = "http://docs.python.org/%d.%d" % sys.version_info[:2] + currentTheme=idleConf.CurrentTheme() + self.flist = flist + root = root or flist.root + self.root = root + try: + sys.ps1 + except AttributeError: + sys.ps1 = '>>> ' + self.menubar = Menu(root) + self.top = top = WindowList.ListedToplevel(root, menu=self.menubar) + if flist: + self.tkinter_vars = flist.vars + #self.top.instance_dict makes flist.inversedict available to + #configDialog.py so it can access all EditorWindow instances + self.top.instance_dict = flist.inversedict + else: + self.tkinter_vars = {} # keys: Tkinter event names + # values: Tkinter variable instances + self.top.instance_dict = {} + self.recent_files_path = os.path.join(idleConf.GetUserCfgDir(), + 'recent-files.lst') + self.text_frame = text_frame = Frame(top) + self.vbar = vbar = Scrollbar(text_frame, name='vbar') + self.width = idleConf.GetOption('main','EditorWindow','width', type='int') + text_options = { + 'name': 'text', + 'padx': 5, + 'wrap': 'none', + 'width': self.width, + 'height': idleConf.GetOption('main', 'EditorWindow', 'height', type='int')} + if TkVersion >= 8.5: + # Starting with tk 8.5 we have to set the new tabstyle option + # to 'wordprocessor' to achieve the same display of tabs as in + # older tk versions. + text_options['tabstyle'] = 'wordprocessor' + self.text = text = MultiCallCreator(Text)(text_frame, **text_options) + self.top.focused_widget = self.text + + self.createmenubar() + self.apply_bindings() + + self.top.protocol("WM_DELETE_WINDOW", self.close) + self.top.bind("<>", self.close_event) + if macosxSupport.isAquaTk(): + # Command-W on editorwindows doesn't work without this. + text.bind('<>', self.close_event) + # Some OS X systems have only one mouse button, + # so use control-click for pulldown menus there. + # (Note, AquaTk defines <2> as the right button if + # present and the Tk Text widget already binds <2>.) + text.bind("",self.right_menu_event) + else: + # Elsewhere, use right-click for pulldown menus. + text.bind("<3>",self.right_menu_event) + text.bind("<>", self.cut) + text.bind("<>", self.copy) + text.bind("<>", self.paste) + text.bind("<>", self.center_insert_event) + text.bind("<>", self.help_dialog) + text.bind("<>", self.python_docs) + text.bind("<>", self.about_dialog) + text.bind("<>", self.config_dialog) + text.bind("<>", self.open_module) + text.bind("<>", lambda event: "break") + text.bind("<>", self.select_all) + text.bind("<>", self.remove_selection) + text.bind("<>", self.find_event) + text.bind("<>", self.find_again_event) + text.bind("<>", self.find_in_files_event) + text.bind("<>", self.find_selection_event) + text.bind("<>", self.replace_event) + text.bind("<>", self.goto_line_event) + text.bind("<>",self.smart_backspace_event) + text.bind("<>",self.newline_and_indent_event) + text.bind("<>",self.smart_indent_event) + text.bind("<>",self.indent_region_event) + text.bind("<>",self.dedent_region_event) + text.bind("<>",self.comment_region_event) + text.bind("<>",self.uncomment_region_event) + text.bind("<>",self.tabify_region_event) + text.bind("<>",self.untabify_region_event) + text.bind("<>",self.toggle_tabs_event) + text.bind("<>",self.change_indentwidth_event) + text.bind("", self.move_at_edge_if_selection(0)) + text.bind("", self.move_at_edge_if_selection(1)) + text.bind("<>", self.del_word_left) + text.bind("<>", self.del_word_right) + text.bind("<>", self.home_callback) + + if flist: + flist.inversedict[self] = key + if key: + flist.dict[key] = self + text.bind("<>", self.new_callback) + text.bind("<>", self.flist.close_all_callback) + text.bind("<>", self.open_class_browser) + text.bind("<>", self.open_path_browser) + + self.set_status_bar() + vbar['command'] = text.yview + vbar.pack(side=RIGHT, fill=Y) + text['yscrollcommand'] = vbar.set + fontWeight = 'normal' + if idleConf.GetOption('main', 'EditorWindow', 'font-bold', type='bool'): + fontWeight='bold' + text.config(font=(idleConf.GetOption('main', 'EditorWindow', 'font'), + idleConf.GetOption('main', 'EditorWindow', + 'font-size', type='int'), + fontWeight)) + text_frame.pack(side=LEFT, fill=BOTH, expand=1) + text.pack(side=TOP, fill=BOTH, expand=1) + text.focus_set() + + # usetabs true -> literal tab characters are used by indent and + # dedent cmds, possibly mixed with spaces if + # indentwidth is not a multiple of tabwidth, + # which will cause Tabnanny to nag! + # false -> tab characters are converted to spaces by indent + # and dedent cmds, and ditto TAB keystrokes + # Although use-spaces=0 can be configured manually in config-main.def, + # configuration of tabs v. spaces is not supported in the configuration + # dialog. IDLE promotes the preferred Python indentation: use spaces! + usespaces = idleConf.GetOption('main', 'Indent', 'use-spaces', type='bool') + self.usetabs = not usespaces + + # tabwidth is the display width of a literal tab character. + # CAUTION: telling Tk to use anything other than its default + # tab setting causes it to use an entirely different tabbing algorithm, + # treating tab stops as fixed distances from the left margin. + # Nobody expects this, so for now tabwidth should never be changed. + self.tabwidth = 8 # must remain 8 until Tk is fixed. + + # indentwidth is the number of screen characters per indent level. + # The recommended Python indentation is four spaces. + self.indentwidth = self.tabwidth + self.set_notabs_indentwidth() + + # If context_use_ps1 is true, parsing searches back for a ps1 line; + # else searches for a popular (if, def, ...) Python stmt. + self.context_use_ps1 = False + + # When searching backwards for a reliable place to begin parsing, + # first start num_context_lines[0] lines back, then + # num_context_lines[1] lines back if that didn't work, and so on. + # The last value should be huge (larger than the # of lines in a + # conceivable file). + # Making the initial values larger slows things down more often. + self.num_context_lines = 50, 500, 5000000 + + self.per = per = self.Percolator(text) + + self.undo = undo = self.UndoDelegator() + per.insertfilter(undo) + text.undo_block_start = undo.undo_block_start + text.undo_block_stop = undo.undo_block_stop + undo.set_saved_change_hook(self.saved_change_hook) + + # IOBinding implements file I/O and printing functionality + self.io = io = self.IOBinding(self) + io.set_filename_change_hook(self.filename_change_hook) + + # Create the recent files submenu + self.recent_files_menu = Menu(self.menubar) + self.menudict['file'].insert_cascade(3, label='Recent Files', + underline=0, + menu=self.recent_files_menu) + self.update_recent_files_list() + + self.color = None # initialized below in self.ResetColorizer + if filename: + if os.path.exists(filename) and not os.path.isdir(filename): + io.loadfile(filename) + else: + io.set_filename(filename) + self.ResetColorizer() + self.saved_change_hook() + + self.set_indentation_params(self.ispythonsource(filename)) + + self.load_extensions() + + menu = self.menudict.get('windows') + if menu: + end = menu.index("end") + if end is None: + end = -1 + if end >= 0: + menu.add_separator() + end = end + 1 + self.wmenu_end = end + WindowList.register_callback(self.postwindowsmenu) + + # Some abstractions so IDLE extensions are cross-IDE + self.askyesno = tkMessageBox.askyesno + self.askinteger = tkSimpleDialog.askinteger + self.showerror = tkMessageBox.showerror + + self._highlight_workaround() # Fix selection tags on Windows + + def _highlight_workaround(self): + # On Windows, Tk removes painting of the selection + # tags which is different behavior than on Linux and Mac. + # See issue14146 for more information. + if not sys.platform.startswith('win'): + return + + text = self.text + text.event_add("<>", "") + text.event_add("<>", "") + def highlight_fix(focus): + sel_range = text.tag_ranges("sel") + if sel_range: + if focus == 'out': + HILITE_CONFIG = idleConf.GetHighlight( + idleConf.CurrentTheme(), 'hilite') + text.tag_config("sel_fix", HILITE_CONFIG) + text.tag_raise("sel_fix") + text.tag_add("sel_fix", *sel_range) + elif focus == 'in': + text.tag_remove("sel_fix", "1.0", "end") + + text.bind("<>", + lambda ev: highlight_fix("out")) + text.bind("<>", + lambda ev: highlight_fix("in")) + + + def _filename_to_unicode(self, filename): + """convert filename to unicode in order to display it in Tk""" + if isinstance(filename, unicode) or not filename: + return filename + else: + try: + return filename.decode(self.filesystemencoding) + except UnicodeDecodeError: + # XXX + try: + return filename.decode(self.encoding) + except UnicodeDecodeError: + # byte-to-byte conversion + return filename.decode('iso8859-1') + + def new_callback(self, event): + dirname, basename = self.io.defaultfilename() + self.flist.new(dirname) + return "break" + + def home_callback(self, event): + if (event.state & 4) != 0 and event.keysym == "Home": + # state&4==Control. If , use the Tk binding. + return + if self.text.index("iomark") and \ + self.text.compare("iomark", "<=", "insert lineend") and \ + self.text.compare("insert linestart", "<=", "iomark"): + # In Shell on input line, go to just after prompt + insertpt = int(self.text.index("iomark").split(".")[1]) + else: + line = self.text.get("insert linestart", "insert lineend") + for insertpt in xrange(len(line)): + if line[insertpt] not in (' ','\t'): + break + else: + insertpt=len(line) + lineat = int(self.text.index("insert").split('.')[1]) + if insertpt == lineat: + insertpt = 0 + dest = "insert linestart+"+str(insertpt)+"c" + if (event.state&1) == 0: + # shift was not pressed + self.text.tag_remove("sel", "1.0", "end") + else: + if not self.text.index("sel.first"): + self.text.mark_set("my_anchor", "insert") # there was no previous selection + else: + if self.text.compare(self.text.index("sel.first"), "<", self.text.index("insert")): + self.text.mark_set("my_anchor", "sel.first") # extend back + else: + self.text.mark_set("my_anchor", "sel.last") # extend forward + first = self.text.index(dest) + last = self.text.index("my_anchor") + if self.text.compare(first,">",last): + first,last = last,first + self.text.tag_remove("sel", "1.0", "end") + self.text.tag_add("sel", first, last) + self.text.mark_set("insert", dest) + self.text.see("insert") + return "break" + + def set_status_bar(self): + self.status_bar = self.MultiStatusBar(self.top) + if sys.platform == "darwin": + # Insert some padding to avoid obscuring some of the statusbar + # by the resize widget. + self.status_bar.set_label('_padding1', ' ', side=RIGHT) + self.status_bar.set_label('column', 'Col: ?', side=RIGHT) + self.status_bar.set_label('line', 'Ln: ?', side=RIGHT) + self.status_bar.pack(side=BOTTOM, fill=X) + self.text.bind("<>", self.set_line_and_column) + self.text.event_add("<>", + "", "") + self.text.after_idle(self.set_line_and_column) + + def set_line_and_column(self, event=None): + line, column = self.text.index(INSERT).split('.') + self.status_bar.set_label('column', 'Col: %s' % column) + self.status_bar.set_label('line', 'Ln: %s' % line) + + menu_specs = [ + ("file", "_File"), + ("edit", "_Edit"), + ("format", "F_ormat"), + ("run", "_Run"), + ("options", "_Options"), + ("windows", "_Windows"), + ("help", "_Help"), + ] + + if sys.platform == "darwin": + menu_specs[-2] = ("windows", "_Window") + + + def createmenubar(self): + mbar = self.menubar + self.menudict = menudict = {} + for name, label in self.menu_specs: + underline, label = prepstr(label) + menudict[name] = menu = Menu(mbar, name=name) + mbar.add_cascade(label=label, menu=menu, underline=underline) + + if macosxSupport.isCarbonTk(): + # Insert the application menu + menudict['application'] = menu = Menu(mbar, name='apple') + mbar.add_cascade(label='IDLE', menu=menu) + + self.fill_menus() + self.base_helpmenu_length = self.menudict['help'].index(END) + self.reset_help_menu_entries() + + def postwindowsmenu(self): + # Only called when Windows menu exists + menu = self.menudict['windows'] + end = menu.index("end") + if end is None: + end = -1 + if end > self.wmenu_end: + menu.delete(self.wmenu_end+1, end) + WindowList.add_windows_to_menu(menu) + + rmenu = None + + def right_menu_event(self, event): + self.text.mark_set("insert", "@%d,%d" % (event.x, event.y)) + if not self.rmenu: + self.make_rmenu() + rmenu = self.rmenu + self.event = event + iswin = sys.platform[:3] == 'win' + if iswin: + self.text.config(cursor="arrow") + + for item in self.rmenu_specs: + try: + label, eventname, verify_state = item + except ValueError: # see issue1207589 + continue + + if verify_state is None: + continue + state = getattr(self, verify_state)() + rmenu.entryconfigure(label, state=state) + + rmenu.tk_popup(event.x_root, event.y_root) + if iswin: + self.text.config(cursor="ibeam") + + rmenu_specs = [ + # ("Label", "<>", "statefuncname"), ... + ("Close", "<>", None), # Example + ] + + def make_rmenu(self): + rmenu = Menu(self.text, tearoff=0) + for item in self.rmenu_specs: + label, eventname = item[0], item[1] + if label is not None: + def command(text=self.text, eventname=eventname): + text.event_generate(eventname) + rmenu.add_command(label=label, command=command) + else: + rmenu.add_separator() + self.rmenu = rmenu + + def rmenu_check_cut(self): + return self.rmenu_check_copy() + + def rmenu_check_copy(self): + try: + indx = self.text.index('sel.first') + except TclError: + return 'disabled' + else: + return 'normal' if indx else 'disabled' + + def rmenu_check_paste(self): + try: + self.text.tk.call('tk::GetSelection', self.text, 'CLIPBOARD') + except TclError: + return 'disabled' + else: + return 'normal' + + def about_dialog(self, event=None): + aboutDialog.AboutDialog(self.top,'About IDLE') + + def config_dialog(self, event=None): + configDialog.ConfigDialog(self.top,'Settings') + + def help_dialog(self, event=None): + if self.root: + parent = self.root + else: + parent = self.top + helpDialog.display(parent, near=self.top) + + def python_docs(self, event=None): + if sys.platform[:3] == 'win': + try: + os.startfile(self.help_url) + except WindowsError as why: + tkMessageBox.showerror(title='Document Start Failure', + message=str(why), parent=self.text) + else: + webbrowser.open(self.help_url) + return "break" + + def cut(self,event): + self.text.event_generate("<>") + return "break" + + def copy(self,event): + if not self.text.tag_ranges("sel"): + # There is no selection, so do nothing and maybe interrupt. + return + self.text.event_generate("<>") + return "break" + + def paste(self,event): + self.text.event_generate("<>") + self.text.see("insert") + return "break" + + def select_all(self, event=None): + self.text.tag_add("sel", "1.0", "end-1c") + self.text.mark_set("insert", "1.0") + self.text.see("insert") + return "break" + + def remove_selection(self, event=None): + self.text.tag_remove("sel", "1.0", "end") + self.text.see("insert") + + def move_at_edge_if_selection(self, edge_index): + """Cursor move begins at start or end of selection + + When a left/right cursor key is pressed create and return to Tkinter a + function which causes a cursor move from the associated edge of the + selection. + + """ + self_text_index = self.text.index + self_text_mark_set = self.text.mark_set + edges_table = ("sel.first+1c", "sel.last-1c") + def move_at_edge(event): + if (event.state & 5) == 0: # no shift(==1) or control(==4) pressed + try: + self_text_index("sel.first") + self_text_mark_set("insert", edges_table[edge_index]) + except TclError: + pass + return move_at_edge + + def del_word_left(self, event): + self.text.event_generate('') + return "break" + + def del_word_right(self, event): + self.text.event_generate('') + return "break" + + def find_event(self, event): + SearchDialog.find(self.text) + return "break" + + def find_again_event(self, event): + SearchDialog.find_again(self.text) + return "break" + + def find_selection_event(self, event): + SearchDialog.find_selection(self.text) + return "break" + + def find_in_files_event(self, event): + GrepDialog.grep(self.text, self.io, self.flist) + return "break" + + def replace_event(self, event): + ReplaceDialog.replace(self.text) + return "break" + + def goto_line_event(self, event): + text = self.text + lineno = tkSimpleDialog.askinteger("Goto", + "Go to line number:",parent=text) + if lineno is None: + return "break" + if lineno <= 0: + text.bell() + return "break" + text.mark_set("insert", "%d.0" % lineno) + text.see("insert") + + def open_module(self, event=None): + # XXX Shouldn't this be in IOBinding or in FileList? + try: + name = self.text.get("sel.first", "sel.last") + except TclError: + name = "" + else: + name = name.strip() + name = tkSimpleDialog.askstring("Module", + "Enter the name of a Python module\n" + "to search on sys.path and open:", + parent=self.text, initialvalue=name) + if name: + name = name.strip() + if not name: + return + # XXX Ought to insert current file's directory in front of path + try: + (f, file, (suffix, mode, type)) = _find_module(name) + except (NameError, ImportError) as msg: + tkMessageBox.showerror("Import error", str(msg), parent=self.text) + return + if type != imp.PY_SOURCE: + tkMessageBox.showerror("Unsupported type", + "%s is not a source module" % name, parent=self.text) + return + if f: + f.close() + if self.flist: + self.flist.open(file) + else: + self.io.loadfile(file) + + def open_class_browser(self, event=None): + filename = self.io.filename + if not filename: + tkMessageBox.showerror( + "No filename", + "This buffer has no associated filename", + master=self.text) + self.text.focus_set() + return None + head, tail = os.path.split(filename) + base, ext = os.path.splitext(tail) + from idlelib import ClassBrowser + ClassBrowser.ClassBrowser(self.flist, base, [head]) + + def open_path_browser(self, event=None): + from idlelib import PathBrowser + PathBrowser.PathBrowser(self.flist) + + def gotoline(self, lineno): + if lineno is not None and lineno > 0: + self.text.mark_set("insert", "%d.0" % lineno) + self.text.tag_remove("sel", "1.0", "end") + self.text.tag_add("sel", "insert", "insert +1l") + self.center() + + def ispythonsource(self, filename): + if not filename or os.path.isdir(filename): + return True + base, ext = os.path.splitext(os.path.basename(filename)) + if os.path.normcase(ext) in (".py", ".pyw"): + return True + try: + f = open(filename) + line = f.readline() + f.close() + except IOError: + return False + return line.startswith('#!') and line.find('python') >= 0 + + def close_hook(self): + if self.flist: + self.flist.unregister_maybe_terminate(self) + self.flist = None + + def set_close_hook(self, close_hook): + self.close_hook = close_hook + + def filename_change_hook(self): + if self.flist: + self.flist.filename_changed_edit(self) + self.saved_change_hook() + self.top.update_windowlist_registry(self) + self.ResetColorizer() + + def _addcolorizer(self): + if self.color: + return + if self.ispythonsource(self.io.filename): + self.color = self.ColorDelegator() + # can add more colorizers here... + if self.color: + self.per.removefilter(self.undo) + self.per.insertfilter(self.color) + self.per.insertfilter(self.undo) + + def _rmcolorizer(self): + if not self.color: + return + self.color.removecolors() + self.per.removefilter(self.color) + self.color = None + + def ResetColorizer(self): + "Update the colour theme" + # Called from self.filename_change_hook and from configDialog.py + self._rmcolorizer() + self._addcolorizer() + theme = idleConf.GetOption('main','Theme','name') + normal_colors = idleConf.GetHighlight(theme, 'normal') + cursor_color = idleConf.GetHighlight(theme, 'cursor', fgBg='fg') + select_colors = idleConf.GetHighlight(theme, 'hilite') + self.text.config( + foreground=normal_colors['foreground'], + background=normal_colors['background'], + insertbackground=cursor_color, + selectforeground=select_colors['foreground'], + selectbackground=select_colors['background'], + ) + + def ResetFont(self): + "Update the text widgets' font if it is changed" + # Called from configDialog.py + fontWeight='normal' + if idleConf.GetOption('main','EditorWindow','font-bold',type='bool'): + fontWeight='bold' + self.text.config(font=(idleConf.GetOption('main','EditorWindow','font'), + idleConf.GetOption('main','EditorWindow','font-size', + type='int'), + fontWeight)) + + def RemoveKeybindings(self): + "Remove the keybindings before they are changed." + # Called from configDialog.py + self.Bindings.default_keydefs = keydefs = idleConf.GetCurrentKeySet() + for event, keylist in keydefs.items(): + self.text.event_delete(event, *keylist) + for extensionName in self.get_standard_extension_names(): + xkeydefs = idleConf.GetExtensionBindings(extensionName) + if xkeydefs: + for event, keylist in xkeydefs.items(): + self.text.event_delete(event, *keylist) + + def ApplyKeybindings(self): + "Update the keybindings after they are changed" + # Called from configDialog.py + self.Bindings.default_keydefs = keydefs = idleConf.GetCurrentKeySet() + self.apply_bindings() + for extensionName in self.get_standard_extension_names(): + xkeydefs = idleConf.GetExtensionBindings(extensionName) + if xkeydefs: + self.apply_bindings(xkeydefs) + #update menu accelerators + menuEventDict = {} + for menu in self.Bindings.menudefs: + menuEventDict[menu[0]] = {} + for item in menu[1]: + if item: + menuEventDict[menu[0]][prepstr(item[0])[1]] = item[1] + for menubarItem in self.menudict.keys(): + menu = self.menudict[menubarItem] + end = menu.index(END) + if end is None: + # Skip empty menus + continue + end += 1 + for index in range(0, end): + if menu.type(index) == 'command': + accel = menu.entrycget(index, 'accelerator') + if accel: + itemName = menu.entrycget(index, 'label') + event = '' + if menubarItem in menuEventDict: + if itemName in menuEventDict[menubarItem]: + event = menuEventDict[menubarItem][itemName] + if event: + accel = get_accelerator(keydefs, event) + menu.entryconfig(index, accelerator=accel) + + def set_notabs_indentwidth(self): + "Update the indentwidth if changed and not using tabs in this window" + # Called from configDialog.py + if not self.usetabs: + self.indentwidth = idleConf.GetOption('main', 'Indent','num-spaces', + type='int') + + def reset_help_menu_entries(self): + "Update the additional help entries on the Help menu" + help_list = idleConf.GetAllExtraHelpSourcesList() + helpmenu = self.menudict['help'] + # first delete the extra help entries, if any + helpmenu_length = helpmenu.index(END) + if helpmenu_length > self.base_helpmenu_length: + helpmenu.delete((self.base_helpmenu_length + 1), helpmenu_length) + # then rebuild them + if help_list: + helpmenu.add_separator() + for entry in help_list: + cmd = self.__extra_help_callback(entry[1]) + helpmenu.add_command(label=entry[0], command=cmd) + # and update the menu dictionary + self.menudict['help'] = helpmenu + + def __extra_help_callback(self, helpfile): + "Create a callback with the helpfile value frozen at definition time" + def display_extra_help(helpfile=helpfile): + if not helpfile.startswith(('www', 'http')): + helpfile = os.path.normpath(helpfile) + if sys.platform[:3] == 'win': + try: + os.startfile(helpfile) + except WindowsError as why: + tkMessageBox.showerror(title='Document Start Failure', + message=str(why), parent=self.text) + else: + webbrowser.open(helpfile) + return display_extra_help + + def update_recent_files_list(self, new_file=None): + "Load and update the recent files list and menus" + rf_list = [] + if os.path.exists(self.recent_files_path): + with open(self.recent_files_path, 'r') as rf_list_file: + rf_list = rf_list_file.readlines() + if new_file: + new_file = os.path.abspath(new_file) + '\n' + if new_file in rf_list: + rf_list.remove(new_file) # move to top + rf_list.insert(0, new_file) + # clean and save the recent files list + bad_paths = [] + for path in rf_list: + if '\0' in path or not os.path.exists(path[0:-1]): + bad_paths.append(path) + rf_list = [path for path in rf_list if path not in bad_paths] + ulchars = "1234567890ABCDEFGHIJK" + rf_list = rf_list[0:len(ulchars)] + try: + with open(self.recent_files_path, 'w') as rf_file: + rf_file.writelines(rf_list) + except IOError as err: + if not getattr(self.root, "recentfilelist_error_displayed", False): + self.root.recentfilelist_error_displayed = True + tkMessageBox.showerror(title='IDLE Error', + message='Unable to update Recent Files list:\n%s' + % str(err), + parent=self.text) + # for each edit window instance, construct the recent files menu + for instance in self.top.instance_dict.keys(): + menu = instance.recent_files_menu + menu.delete(0, END) # clear, and rebuild: + for i, file_name in enumerate(rf_list): + file_name = file_name.rstrip() # zap \n + # make unicode string to display non-ASCII chars correctly + ufile_name = self._filename_to_unicode(file_name) + callback = instance.__recent_file_callback(file_name) + menu.add_command(label=ulchars[i] + " " + ufile_name, + command=callback, + underline=0) + + def __recent_file_callback(self, file_name): + def open_recent_file(fn_closure=file_name): + self.io.open(editFile=fn_closure) + return open_recent_file + + def saved_change_hook(self): + short = self.short_title() + long = self.long_title() + if short and long: + title = short + " - " + long + elif short: + title = short + elif long: + title = long + else: + title = "Untitled" + icon = short or long or title + if not self.get_saved(): + title = "*%s*" % title + icon = "*%s" % icon + self.top.wm_title(title) + self.top.wm_iconname(icon) + + def get_saved(self): + return self.undo.get_saved() + + def set_saved(self, flag): + self.undo.set_saved(flag) + + def reset_undo(self): + self.undo.reset_undo() + + def short_title(self): + pyversion = "Python " + python_version() + ": " + filename = self.io.filename + if filename: + filename = os.path.basename(filename) + else: + filename = "Untitled" + # return unicode string to display non-ASCII chars correctly + return pyversion + self._filename_to_unicode(filename) + + def long_title(self): + # return unicode string to display non-ASCII chars correctly + return self._filename_to_unicode(self.io.filename or "") + + def center_insert_event(self, event): + self.center() + + def center(self, mark="insert"): + text = self.text + top, bot = self.getwindowlines() + lineno = self.getlineno(mark) + height = bot - top + newtop = max(1, lineno - height//2) + text.yview(float(newtop)) + + def getwindowlines(self): + text = self.text + top = self.getlineno("@0,0") + bot = self.getlineno("@0,65535") + if top == bot and text.winfo_height() == 1: + # Geometry manager hasn't run yet + height = int(text['height']) + bot = top + height - 1 + return top, bot + + def getlineno(self, mark="insert"): + text = self.text + return int(float(text.index(mark))) + + def get_geometry(self): + "Return (width, height, x, y)" + geom = self.top.wm_geometry() + m = re.match(r"(\d+)x(\d+)\+(-?\d+)\+(-?\d+)", geom) + tuple = (map(int, m.groups())) + return tuple + + def close_event(self, event): + self.close() + + def maybesave(self): + if self.io: + if not self.get_saved(): + if self.top.state()!='normal': + self.top.deiconify() + self.top.lower() + self.top.lift() + return self.io.maybesave() + + def close(self): + reply = self.maybesave() + if str(reply) != "cancel": + self._close() + return reply + + def _close(self): + if self.io.filename: + self.update_recent_files_list(new_file=self.io.filename) + WindowList.unregister_callback(self.postwindowsmenu) + self.unload_extensions() + self.io.close() + self.io = None + self.undo = None + if self.color: + self.color.close(False) + self.color = None + self.text = None + self.tkinter_vars = None + self.per.close() + self.per = None + self.top.destroy() + if self.close_hook: + # unless override: unregister from flist, terminate if last window + self.close_hook() + + def load_extensions(self): + self.extensions = {} + self.load_standard_extensions() + + def unload_extensions(self): + for ins in self.extensions.values(): + if hasattr(ins, "close"): + ins.close() + self.extensions = {} + + def load_standard_extensions(self): + for name in self.get_standard_extension_names(): + try: + self.load_extension(name) + except: + print "Failed to load extension", repr(name) + import traceback + traceback.print_exc() + + def get_standard_extension_names(self): + return idleConf.GetExtensions(editor_only=True) + + def load_extension(self, name): + try: + mod = __import__(name, globals(), locals(), []) + except ImportError: + print "\nFailed to import extension: ", name + return + cls = getattr(mod, name) + keydefs = idleConf.GetExtensionBindings(name) + if hasattr(cls, "menudefs"): + self.fill_menus(cls.menudefs, keydefs) + ins = cls(self) + self.extensions[name] = ins + if keydefs: + self.apply_bindings(keydefs) + for vevent in keydefs.keys(): + methodname = vevent.replace("-", "_") + while methodname[:1] == '<': + methodname = methodname[1:] + while methodname[-1:] == '>': + methodname = methodname[:-1] + methodname = methodname + "_event" + if hasattr(ins, methodname): + self.text.bind(vevent, getattr(ins, methodname)) + + def apply_bindings(self, keydefs=None): + if keydefs is None: + keydefs = self.Bindings.default_keydefs + text = self.text + text.keydefs = keydefs + for event, keylist in keydefs.items(): + if keylist: + text.event_add(event, *keylist) + + def fill_menus(self, menudefs=None, keydefs=None): + """Add appropriate entries to the menus and submenus + + Menus that are absent or None in self.menudict are ignored. + """ + if menudefs is None: + menudefs = self.Bindings.menudefs + if keydefs is None: + keydefs = self.Bindings.default_keydefs + menudict = self.menudict + text = self.text + for mname, entrylist in menudefs: + menu = menudict.get(mname) + if not menu: + continue + for entry in entrylist: + if not entry: + menu.add_separator() + else: + label, eventname = entry + checkbutton = (label[:1] == '!') + if checkbutton: + label = label[1:] + underline, label = prepstr(label) + accelerator = get_accelerator(keydefs, eventname) + def command(text=text, eventname=eventname): + text.event_generate(eventname) + if checkbutton: + var = self.get_var_obj(eventname, BooleanVar) + menu.add_checkbutton(label=label, underline=underline, + command=command, accelerator=accelerator, + variable=var) + else: + menu.add_command(label=label, underline=underline, + command=command, + accelerator=accelerator) + + def getvar(self, name): + var = self.get_var_obj(name) + if var: + value = var.get() + return value + else: + raise NameError, name + + def setvar(self, name, value, vartype=None): + var = self.get_var_obj(name, vartype) + if var: + var.set(value) + else: + raise NameError, name + + def get_var_obj(self, name, vartype=None): + var = self.tkinter_vars.get(name) + if not var and vartype: + # create a Tkinter variable object with self.text as master: + self.tkinter_vars[name] = var = vartype(self.text) + return var + + # Tk implementations of "virtual text methods" -- each platform + # reusing IDLE's support code needs to define these for its GUI's + # flavor of widget. + + # Is character at text_index in a Python string? Return 0 for + # "guaranteed no", true for anything else. This info is expensive + # to compute ab initio, but is probably already known by the + # platform's colorizer. + + def is_char_in_string(self, text_index): + if self.color: + # Return true iff colorizer hasn't (re)gotten this far + # yet, or the character is tagged as being in a string + return self.text.tag_prevrange("TODO", text_index) or \ + "STRING" in self.text.tag_names(text_index) + else: + # The colorizer is missing: assume the worst + return 1 + + # If a selection is defined in the text widget, return (start, + # end) as Tkinter text indices, otherwise return (None, None) + def get_selection_indices(self): + try: + first = self.text.index("sel.first") + last = self.text.index("sel.last") + return first, last + except TclError: + return None, None + + # Return the text widget's current view of what a tab stop means + # (equivalent width in spaces). + + def get_tabwidth(self): + current = self.text['tabs'] or TK_TABWIDTH_DEFAULT + return int(current) + + # Set the text widget's current view of what a tab stop means. + + def set_tabwidth(self, newtabwidth): + text = self.text + if self.get_tabwidth() != newtabwidth: + pixels = text.tk.call("font", "measure", text["font"], + "-displayof", text.master, + "n" * newtabwidth) + text.configure(tabs=pixels) + + # If ispythonsource and guess are true, guess a good value for + # indentwidth based on file content (if possible), and if + # indentwidth != tabwidth set usetabs false. + # In any case, adjust the Text widget's view of what a tab + # character means. + + def set_indentation_params(self, ispythonsource, guess=True): + if guess and ispythonsource: + i = self.guess_indent() + if 2 <= i <= 8: + self.indentwidth = i + if self.indentwidth != self.tabwidth: + self.usetabs = False + self.set_tabwidth(self.tabwidth) + + def smart_backspace_event(self, event): + text = self.text + first, last = self.get_selection_indices() + if first and last: + text.delete(first, last) + text.mark_set("insert", first) + return "break" + # Delete whitespace left, until hitting a real char or closest + # preceding virtual tab stop. + chars = text.get("insert linestart", "insert") + if chars == '': + if text.compare("insert", ">", "1.0"): + # easy: delete preceding newline + text.delete("insert-1c") + else: + text.bell() # at start of buffer + return "break" + if chars[-1] not in " \t": + # easy: delete preceding real char + text.delete("insert-1c") + return "break" + # Ick. It may require *inserting* spaces if we back up over a + # tab character! This is written to be clear, not fast. + tabwidth = self.tabwidth + have = len(chars.expandtabs(tabwidth)) + assert have > 0 + want = ((have - 1) // self.indentwidth) * self.indentwidth + # Debug prompt is multilined.... + if self.context_use_ps1: + last_line_of_prompt = sys.ps1.split('\n')[-1] + else: + last_line_of_prompt = '' + ncharsdeleted = 0 + while 1: + if chars == last_line_of_prompt: + break + chars = chars[:-1] + ncharsdeleted = ncharsdeleted + 1 + have = len(chars.expandtabs(tabwidth)) + if have <= want or chars[-1] not in " \t": + break + text.undo_block_start() + text.delete("insert-%dc" % ncharsdeleted, "insert") + if have < want: + text.insert("insert", ' ' * (want - have)) + text.undo_block_stop() + return "break" + + def smart_indent_event(self, event): + # if intraline selection: + # delete it + # elif multiline selection: + # do indent-region + # else: + # indent one level + text = self.text + first, last = self.get_selection_indices() + text.undo_block_start() + try: + if first and last: + if index2line(first) != index2line(last): + return self.indent_region_event(event) + text.delete(first, last) + text.mark_set("insert", first) + prefix = text.get("insert linestart", "insert") + raw, effective = classifyws(prefix, self.tabwidth) + if raw == len(prefix): + # only whitespace to the left + self.reindent_to(effective + self.indentwidth) + else: + # tab to the next 'stop' within or to right of line's text: + if self.usetabs: + pad = '\t' + else: + effective = len(prefix.expandtabs(self.tabwidth)) + n = self.indentwidth + pad = ' ' * (n - effective % n) + text.insert("insert", pad) + text.see("insert") + return "break" + finally: + text.undo_block_stop() + + def newline_and_indent_event(self, event): + text = self.text + first, last = self.get_selection_indices() + text.undo_block_start() + try: + if first and last: + text.delete(first, last) + text.mark_set("insert", first) + line = text.get("insert linestart", "insert") + i, n = 0, len(line) + while i < n and line[i] in " \t": + i = i+1 + if i == n: + # the cursor is in or at leading indentation in a continuation + # line; just inject an empty line at the start + text.insert("insert linestart", '\n') + return "break" + indent = line[:i] + # strip whitespace before insert point unless it's in the prompt + i = 0 + last_line_of_prompt = sys.ps1.split('\n')[-1] + while line and line[-1] in " \t" and line != last_line_of_prompt: + line = line[:-1] + i = i+1 + if i: + text.delete("insert - %d chars" % i, "insert") + # strip whitespace after insert point + while text.get("insert") in " \t": + text.delete("insert") + # start new line + text.insert("insert", '\n') + + # adjust indentation for continuations and block + # open/close first need to find the last stmt + lno = index2line(text.index('insert')) + y = PyParse.Parser(self.indentwidth, self.tabwidth) + if not self.context_use_ps1: + for context in self.num_context_lines: + startat = max(lno - context, 1) + startatindex = repr(startat) + ".0" + rawtext = text.get(startatindex, "insert") + y.set_str(rawtext) + bod = y.find_good_parse_start( + self.context_use_ps1, + self._build_char_in_string_func(startatindex)) + if bod is not None or startat == 1: + break + y.set_lo(bod or 0) + else: + r = text.tag_prevrange("console", "insert") + if r: + startatindex = r[1] + else: + startatindex = "1.0" + rawtext = text.get(startatindex, "insert") + y.set_str(rawtext) + y.set_lo(0) + + c = y.get_continuation_type() + if c != PyParse.C_NONE: + # The current stmt hasn't ended yet. + if c == PyParse.C_STRING_FIRST_LINE: + # after the first line of a string; do not indent at all + pass + elif c == PyParse.C_STRING_NEXT_LINES: + # inside a string which started before this line; + # just mimic the current indent + text.insert("insert", indent) + elif c == PyParse.C_BRACKET: + # line up with the first (if any) element of the + # last open bracket structure; else indent one + # level beyond the indent of the line with the + # last open bracket + self.reindent_to(y.compute_bracket_indent()) + elif c == PyParse.C_BACKSLASH: + # if more than one line in this stmt already, just + # mimic the current indent; else if initial line + # has a start on an assignment stmt, indent to + # beyond leftmost =; else to beyond first chunk of + # non-whitespace on initial line + if y.get_num_lines_in_stmt() > 1: + text.insert("insert", indent) + else: + self.reindent_to(y.compute_backslash_indent()) + else: + assert 0, "bogus continuation type %r" % (c,) + return "break" + + # This line starts a brand new stmt; indent relative to + # indentation of initial line of closest preceding + # interesting stmt. + indent = y.get_base_indent_string() + text.insert("insert", indent) + if y.is_block_opener(): + self.smart_indent_event(event) + elif indent and y.is_block_closer(): + self.smart_backspace_event(event) + return "break" + finally: + text.see("insert") + text.undo_block_stop() + + # Our editwin provides a is_char_in_string function that works + # with a Tk text index, but PyParse only knows about offsets into + # a string. This builds a function for PyParse that accepts an + # offset. + + def _build_char_in_string_func(self, startindex): + def inner(offset, _startindex=startindex, + _icis=self.is_char_in_string): + return _icis(_startindex + "+%dc" % offset) + return inner + + def indent_region_event(self, event): + head, tail, chars, lines = self.get_region() + for pos in range(len(lines)): + line = lines[pos] + if line: + raw, effective = classifyws(line, self.tabwidth) + effective = effective + self.indentwidth + lines[pos] = self._make_blanks(effective) + line[raw:] + self.set_region(head, tail, chars, lines) + return "break" + + def dedent_region_event(self, event): + head, tail, chars, lines = self.get_region() + for pos in range(len(lines)): + line = lines[pos] + if line: + raw, effective = classifyws(line, self.tabwidth) + effective = max(effective - self.indentwidth, 0) + lines[pos] = self._make_blanks(effective) + line[raw:] + self.set_region(head, tail, chars, lines) + return "break" + + def comment_region_event(self, event): + head, tail, chars, lines = self.get_region() + for pos in range(len(lines) - 1): + line = lines[pos] + lines[pos] = '##' + line + self.set_region(head, tail, chars, lines) + + def uncomment_region_event(self, event): + head, tail, chars, lines = self.get_region() + for pos in range(len(lines)): + line = lines[pos] + if not line: + continue + if line[:2] == '##': + line = line[2:] + elif line[:1] == '#': + line = line[1:] + lines[pos] = line + self.set_region(head, tail, chars, lines) + + def tabify_region_event(self, event): + head, tail, chars, lines = self.get_region() + tabwidth = self._asktabwidth() + if tabwidth is None: return + for pos in range(len(lines)): + line = lines[pos] + if line: + raw, effective = classifyws(line, tabwidth) + ntabs, nspaces = divmod(effective, tabwidth) + lines[pos] = '\t' * ntabs + ' ' * nspaces + line[raw:] + self.set_region(head, tail, chars, lines) + + def untabify_region_event(self, event): + head, tail, chars, lines = self.get_region() + tabwidth = self._asktabwidth() + if tabwidth is None: return + for pos in range(len(lines)): + lines[pos] = lines[pos].expandtabs(tabwidth) + self.set_region(head, tail, chars, lines) + + def toggle_tabs_event(self, event): + if self.askyesno( + "Toggle tabs", + "Turn tabs " + ("on", "off")[self.usetabs] + + "?\nIndent width " + + ("will be", "remains at")[self.usetabs] + " 8." + + "\n Note: a tab is always 8 columns", + parent=self.text): + self.usetabs = not self.usetabs + # Try to prevent inconsistent indentation. + # User must change indent width manually after using tabs. + self.indentwidth = 8 + return "break" + + # XXX this isn't bound to anything -- see tabwidth comments +## def change_tabwidth_event(self, event): +## new = self._asktabwidth() +## if new != self.tabwidth: +## self.tabwidth = new +## self.set_indentation_params(0, guess=0) +## return "break" + + def change_indentwidth_event(self, event): + new = self.askinteger( + "Indent width", + "New indent width (2-16)\n(Always use 8 when using tabs)", + parent=self.text, + initialvalue=self.indentwidth, + minvalue=2, + maxvalue=16) + if new and new != self.indentwidth and not self.usetabs: + self.indentwidth = new + return "break" + + def get_region(self): + text = self.text + first, last = self.get_selection_indices() + if first and last: + head = text.index(first + " linestart") + tail = text.index(last + "-1c lineend +1c") + else: + head = text.index("insert linestart") + tail = text.index("insert lineend +1c") + chars = text.get(head, tail) + lines = chars.split("\n") + return head, tail, chars, lines + + def set_region(self, head, tail, chars, lines): + text = self.text + newchars = "\n".join(lines) + if newchars == chars: + text.bell() + return + text.tag_remove("sel", "1.0", "end") + text.mark_set("insert", head) + text.undo_block_start() + text.delete(head, tail) + text.insert(head, newchars) + text.undo_block_stop() + text.tag_add("sel", head, "insert") + + # Make string that displays as n leading blanks. + + def _make_blanks(self, n): + if self.usetabs: + ntabs, nspaces = divmod(n, self.tabwidth) + return '\t' * ntabs + ' ' * nspaces + else: + return ' ' * n + + # Delete from beginning of line to insert point, then reinsert + # column logical (meaning use tabs if appropriate) spaces. + + def reindent_to(self, column): + text = self.text + text.undo_block_start() + if text.compare("insert linestart", "!=", "insert"): + text.delete("insert linestart", "insert") + if column: + text.insert("insert", self._make_blanks(column)) + text.undo_block_stop() + + def _asktabwidth(self): + return self.askinteger( + "Tab width", + "Columns per tab? (2-16)", + parent=self.text, + initialvalue=self.indentwidth, + minvalue=2, + maxvalue=16) + + # Guess indentwidth from text content. + # Return guessed indentwidth. This should not be believed unless + # it's in a reasonable range (e.g., it will be 0 if no indented + # blocks are found). + + def guess_indent(self): + opener, indented = IndentSearcher(self.text, self.tabwidth).run() + if opener and indented: + raw, indentsmall = classifyws(opener, self.tabwidth) + raw, indentlarge = classifyws(indented, self.tabwidth) + else: + indentsmall = indentlarge = 0 + return indentlarge - indentsmall + +# "line.col" -> line, as an int +def index2line(index): + return int(float(index)) + +# Look at the leading whitespace in s. +# Return pair (# of leading ws characters, +# effective # of leading blanks after expanding +# tabs to width tabwidth) + +def classifyws(s, tabwidth): + raw = effective = 0 + for ch in s: + if ch == ' ': + raw = raw + 1 + effective = effective + 1 + elif ch == '\t': + raw = raw + 1 + effective = (effective // tabwidth + 1) * tabwidth + else: + break + return raw, effective + +import tokenize +_tokenize = tokenize +del tokenize + +class IndentSearcher(object): + + # .run() chews over the Text widget, looking for a block opener + # and the stmt following it. Returns a pair, + # (line containing block opener, line containing stmt) + # Either or both may be None. + + def __init__(self, text, tabwidth): + self.text = text + self.tabwidth = tabwidth + self.i = self.finished = 0 + self.blkopenline = self.indentedline = None + + def readline(self): + if self.finished: + return "" + i = self.i = self.i + 1 + mark = repr(i) + ".0" + if self.text.compare(mark, ">=", "end"): + return "" + return self.text.get(mark, mark + " lineend+1c") + + def tokeneater(self, type, token, start, end, line, + INDENT=_tokenize.INDENT, + NAME=_tokenize.NAME, + OPENERS=('class', 'def', 'for', 'if', 'try', 'while')): + if self.finished: + pass + elif type == NAME and token in OPENERS: + self.blkopenline = line + elif type == INDENT and self.blkopenline: + self.indentedline = line + self.finished = 1 + + def run(self): + save_tabsize = _tokenize.tabsize + _tokenize.tabsize = self.tabwidth + try: + try: + _tokenize.tokenize(self.readline, self.tokeneater) + except (_tokenize.TokenError, SyntaxError): + # since we cut off the tokenizer early, we can trigger + # spurious errors + pass + finally: + _tokenize.tabsize = save_tabsize + return self.blkopenline, self.indentedline + +### end autoindent code ### + +def prepstr(s): + # Helper to extract the underscore from a string, e.g. + # prepstr("Co_py") returns (2, "Copy"). + i = s.find('_') + if i >= 0: + s = s[:i] + s[i+1:] + return i, s + + +keynames = { + 'bracketleft': '[', + 'bracketright': ']', + 'slash': '/', +} + +def get_accelerator(keydefs, eventname): + keylist = keydefs.get(eventname) + # issue10940: temporary workaround to prevent hang with OS X Cocoa Tk 8.5 + # if not keylist: + if (not keylist) or (macosxSupport.isCocoaTk() and eventname in { + "<>", + "<>", + "<>"}): + return "" + s = keylist[0] + s = re.sub(r"-[a-z]\b", lambda m: m.group().upper(), s) + s = re.sub(r"\b\w+\b", lambda m: keynames.get(m.group(), m.group()), s) + s = re.sub("Key-", "", s) + s = re.sub("Cancel","Ctrl-Break",s) # dscherer@cmu.edu + s = re.sub("Control-", "Ctrl-", s) + s = re.sub("-", "+", s) + s = re.sub("><", " ", s) + s = re.sub("<", "", s) + s = re.sub(">", "", s) + return s + + +def fixwordbreaks(root): + # Make sure that Tk's double-click and next/previous word + # operations use our definition of a word (i.e. an identifier) + tk = root.tk + tk.call('tcl_wordBreakAfter', 'a b', 0) # make sure word.tcl is loaded + tk.call('set', 'tcl_wordchars', '[a-zA-Z0-9_]') + tk.call('set', 'tcl_nonwordchars', '[^a-zA-Z0-9_]') + + +def _editor_window(parent): + root = parent + fixwordbreaks(root) + if sys.argv[1:]: + filename = sys.argv[1] + else: + filename = None + macosxSupport.setupApp(root, None) + edit = EditorWindow(root=root, filename=filename) + edit.text.bind("<>", edit.close_event) + parent.mainloop() + + +if __name__ == '__main__': + from idlelib.idle_test.htest import run + run(_help_dialog, _editor_window) diff --git a/PythonHome/Lib/idlelib/EditorWindow.pyc b/PythonHome/Lib/idlelib/EditorWindow.pyc deleted file mode 100644 index 465877ec502c2f1870ee6e84844ad931c881b1b4..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 55973 zcmc(|33Q#;b>Dj~0FnR%4&qFWR|73-0IAuM4AUY(Qlce6^ask2Xwoo%djVV$xEH+l zLIfN!9;kSVouoWe3<9VZ>x1=*$;(3#wx27{&(iO*<9X1}+tZot@qArc*pU`@rZYR^dC2*@(wSXpad$eiJ1y=>XZA$iX6Nlq zXZG?;7xtyn*7PdCxgnKrOr>qX*kv|YJZQhMpkEvbBqVrOnmr5&zQ zOr@Qza=Y5)ZcC-z&b~dB_Be7!3q*IOGk2yk;r{f2J5yq|zOZ+?&exrP7`0LQksS*rN&CpB9GG z;=y$0U@DXkrgAZr?@d>FQlVXEaFoJwh-OwC9bBw?abE!8ePTWK^SZHTn-@>G3h z{#a#dp*Ghk`Bc5U)Sb4Ol396aVQQw_ovgQ*U|%{0-?sZ>oRV`7}(8jcK2X(Rizw4Qc#<;L&)A;6$yyIMpmR zRvQQNxtpw1XKTe~t+-ULm6m79#pZmuIKDJrsjd|BBE?3tUa8I%mmB4hN>-|kCiCi& zGxLkZQf;Qu=%e-hjs1-V6op80fPZGDs-;S4s#$h!eTHNKX|__GTBs072UNJJ`JhLJ zdUvl52&%5JICUOytL|c@+K$cCYfck3Ei_fQQLck9O%1nRUMNp7{X~<4#?8bIo_)45 zeO8#Tz`w^!6%aG9?;t3>l@gN;kG+N3`$%eRCrCYe3)>1C3p)!#{@qxZQRjuedb1~f zoF%{vFxe|Vq-h2NnC~lvbnM(;)ciBSWM3Fa^+yyx-y>?Fbp{B|GryFecuzVDs(>(k zNeE)p*ryWAHrO(kPUST=x(0Yd)eY$i#W$wa&FPhm>HH=k-NeP+sSm`yFqrB;nhJ#i zlLAU9e=zO&cuyk#MSc@&-vLIQD6l>l0A0Vl$!%^*=ZDmziR$(3HvhZYym+GUVvM=D zIi25<&TmzJsCbqU^ry=M=@s7E=dRyXD6t?0jNSc8-$RR(rhbfXmVpQIw?;)uj=qBM z`-9#TYqQ15;?hA7sWiC=+Afq2+zmQ{+4G>>Lb*|#uaxT|AeEV^g<=#bR;L!rji$)d z!HVXtv5R1=R&3Ok>mdGYt==kWd<7$B8p2H?V+TainnLoiTD5GnYb-5PnvTsZ)EZ@@ zF}*Tn>FSwR!l{=g$De;88$Isah1yiB-=;g0lS@<0`N>I>)+0?;+w^j?e7s%<)kUXH zE{fX3vq;Y5q=rIyVc+B=FD0AD$eXP!C{H7-HQZ&j?o4+XB6mO)oie+;u%N~=tq~Vi zb&sVv*Nh@0sECJJDmP~8UTXnVgLBapr&(^Us29-MH7`3++sQ77?dQ4ipjznNSlG>a z+g!M@u%pmd*jwl&zL|e_^bY0mzMhRd4;2OqgN0oML*(i5Le3;+)QJ8QFplzTyo;a= zi?(?4DiM|>E39C)4kq@POOn#-$VTV(Id@aa#!ZrDghKkMRiR~LH$e%K%{bh!A~Xya zGy54c%gJt_ltH&NRWDbYhE-`H=War+MtNa&U66|juT(3{{?lqett4PEBfQnG-Nnaw z5J@sqztErRxB8KFW(p-L1W6KMqL4`yYq%`~sF}uB35v%mAkoySiT^x+E|$!q4-O6% zyZ(z27Ke*@MX5EAuJjiA)YhPx6rAQdQEVZ?knsOX2>*fn zWA2(J@L+SL>A^nDgNXwqVQQfv&OdStN?Wh39yWcr_kiUzK_|OQfk5M`=WCU!+4a

40n0 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', self.Ok) + self.wait_window() + + def CreateWidgets(self): + self.menu = StringVar(self) + self.path = StringVar(self) + self.fontSize = StringVar(self) + self.frameMain = Frame(self, borderwidth=2, relief=GROOVE) + self.frameMain.pack(side=TOP, expand=TRUE, fill=BOTH) + labelMenu = Label(self.frameMain, anchor=W, justify=LEFT, + text='Menu Item:') + self.entryMenu = Entry(self.frameMain, textvariable=self.menu, + width=30) + self.entryMenu.focus_set() + labelPath = Label(self.frameMain, anchor=W, justify=LEFT, + text='Help File Path: Enter URL or browse for file') + self.entryPath = Entry(self.frameMain, textvariable=self.path, + width=40) + self.entryMenu.focus_set() + labelMenu.pack(anchor=W, padx=5, pady=3) + self.entryMenu.pack(anchor=W, padx=5, pady=3) + labelPath.pack(anchor=W, padx=5, pady=3) + self.entryPath.pack(anchor=W, padx=5, pady=3) + browseButton = Button(self.frameMain, text='Browse', width=8, + command=self.browseFile) + browseButton.pack(pady=3) + frameButtons = Frame(self) + frameButtons.pack(side=BOTTOM, fill=X) + self.buttonOk = Button(frameButtons, text='OK', + width=8, default=ACTIVE, command=self.Ok) + self.buttonOk.grid(row=0, column=0, padx=5,pady=5) + self.buttonCancel = Button(frameButtons, text='Cancel', + width=8, command=self.Cancel) + self.buttonCancel.grid(row=0, column=1, padx=5, pady=5) + + def browseFile(self): + filetypes = [ + ("HTML Files", "*.htm *.html", "TEXT"), + ("PDF Files", "*.pdf", "TEXT"), + ("Windows Help Files", "*.chm"), + ("Text Files", "*.txt", "TEXT"), + ("All Files", "*")] + path = self.path.get() + if path: + dir, base = os.path.split(path) + else: + base = None + if sys.platform[:3] == 'win': + dir = os.path.join(os.path.dirname(sys.executable), 'Doc') + if not os.path.isdir(dir): + dir = os.getcwd() + else: + dir = os.getcwd() + opendialog = tkFileDialog.Open(parent=self, filetypes=filetypes) + file = opendialog.show(initialdir=dir, initialfile=base) + if file: + self.path.set(file) + + def MenuOk(self): + "Simple validity check for a sensible menu item name" + menuOk = True + menu = self.menu.get() + menu.strip() + if not menu: + tkMessageBox.showerror(title='Menu Item Error', + message='No menu item specified', + parent=self) + self.entryMenu.focus_set() + menuOk = False + elif len(menu) > 30: + tkMessageBox.showerror(title='Menu Item Error', + message='Menu item too long:' + '\nLimit 30 characters.', + parent=self) + self.entryMenu.focus_set() + menuOk = False + return menuOk + + def PathOk(self): + "Simple validity check for menu file path" + pathOk = True + path = self.path.get() + path.strip() + if not path: #no path specified + tkMessageBox.showerror(title='File Path Error', + message='No help file path specified.', + parent=self) + self.entryPath.focus_set() + pathOk = False + elif path.startswith(('www.', 'http')): + pass + else: + if path[:5] == 'file:': + path = path[5:] + if not os.path.exists(path): + tkMessageBox.showerror(title='File Path Error', + message='Help file path does not exist.', + parent=self) + self.entryPath.focus_set() + pathOk = False + return pathOk + + def Ok(self, event=None): + if self.MenuOk() and self.PathOk(): + self.result = (self.menu.get().strip(), + self.path.get().strip()) + if sys.platform == 'darwin': + path = self.result[1] + if path.startswith(('www', 'file:', 'http:')): + pass + else: + # Mac Safari insists on using the URI form for local files + self.result = list(self.result) + self.result[1] = "file://" + path + self.destroy() + + def Cancel(self, event=None): + self.result = None + self.destroy() + +if __name__ == '__main__': + from idlelib.idle_test.htest import run + run(GetHelpSourceDialog) diff --git a/PythonHome/Lib/idlelib/configHelpSourceEdit.pyc b/PythonHome/Lib/idlelib/configHelpSourceEdit.pyc deleted file mode 100644 index f1a8a39b1453e9f7620a650f5e7d609401e65e15..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6414 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 J^e0|f{tGHgDNX30: #name too long + tkMessageBox.showerror(title='Name Error', + message='Name too long. It should be no more than '+ + '30 characters.', parent=self) + name = '' + elif name in self.used_names: + tkMessageBox.showerror(title='Name Error', + message='This name is already in use.', parent=self) + name = '' + return name + def Ok(self, event=None): + name = self.name_ok() + if name: + self.result = name + self.destroy() + def Cancel(self, event=None): + self.result = '' + self.destroy() +if __name__ == '__main__': + import unittest + unittest.main('idlelib.idle_test.test_config_name', verbosity=2, exit=False) + + from idlelib.idle_test.htest import run + run(GetCfgSectionNameDialog) diff --git a/PythonHome/Lib/idlelib/configSectionNameDialog.pyc b/PythonHome/Lib/idlelib/configSectionNameDialog.pyc deleted file mode 100644 index ee7f55b4e59f007aadc1441ff146f375ece9f141..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4268 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 diff --git a/PythonHome/Lib/idlelib/idle.py b/PythonHome/Lib/idlelib/idle.py new file mode 100644 index 0000000000..a249557dd1 --- /dev/null +++ b/PythonHome/Lib/idlelib/idle.py @@ -0,0 +1,11 @@ +import os.path +import sys + +# If we are working on a development version of IDLE, we need to prepend the +# parent of this idlelib dir to sys.path. Otherwise, importing idlelib gets +# the version installed with the Python used to call this module: +idlelib_dir = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) +sys.path.insert(0, idlelib_dir) + +import idlelib.PyShell +idlelib.PyShell.main() diff --git a/PythonHome/Lib/idlelib/idle.pyc b/PythonHome/Lib/idlelib/idle.pyc deleted file mode 100644 index da68244da04a996f802cd0afef7666c37499b03d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 391 zcmZWjOKQU~5Pg!9ICUJlD7}Np!Y2r&2PmcBMZp9VyHbga>;y|)c',self.FinalKeySelected) + self.listKeysFinal.grid(row=0,column=4,rowspan=4,sticky=NS) + scrollKeysFinal=Scrollbar(self.frameControlsBasic,orient=VERTICAL, + command=self.listKeysFinal.yview) + self.listKeysFinal.config(yscrollcommand=scrollKeysFinal.set) + scrollKeysFinal.grid(row=0,column=5,rowspan=4,sticky=NS) + self.buttonClear=Button(self.frameControlsBasic, + text='Clear Keys',command=self.ClearKeySeq) + self.buttonClear.grid(row=2,column=0,columnspan=4) + labelTitleAdvanced = Label(self.frameKeySeqAdvanced,justify=LEFT, + text="Enter new binding(s) for '"+self.action+"' :\n"+ + "(These bindings will not be checked for validity!)") + labelTitleAdvanced.pack(anchor=W) + self.entryKeysAdvanced=Entry(self.frameKeySeqAdvanced, + textvariable=self.keyString) + self.entryKeysAdvanced.pack(fill=X) + labelHelpAdvanced=Label(self.frameHelpAdvanced,justify=LEFT, + text="Key bindings are specified using Tkinter keysyms as\n"+ + "in these samples: , , ,\n" + ", , .\n" + "Upper case is used when the Shift modifier is present!\n\n" + + "'Emacs style' multi-keystroke bindings are specified as\n" + + "follows: , where the first key\n" + + "is the 'do-nothing' keybinding.\n\n" + + "Multiple separate bindings for one action should be\n"+ + "separated by a space, eg., ." ) + labelHelpAdvanced.grid(row=0,column=0,sticky=NSEW) + + def SetModifiersForPlatform(self): + """Determine list of names of key modifiers for this platform. + + The names are used to build Tk bindings -- it doesn't matter if the + keyboard has these keys, it matters if Tk understands them. The + order is also important: key binding equality depends on it, so + config-keys.def must use the same ordering. + """ + if sys.platform == "darwin": + self.modifiers = ['Shift', 'Control', 'Option', 'Command'] + else: + self.modifiers = ['Control', 'Alt', 'Shift'] + self.modifier_label = {'Control': 'Ctrl'} # short name + + def ToggleLevel(self): + if self.buttonLevel.cget('text')[:8]=='Advanced': + self.ClearKeySeq() + self.buttonLevel.config(text='<< Basic Key Binding Entry') + self.frameKeySeqAdvanced.lift() + self.frameHelpAdvanced.lift() + self.entryKeysAdvanced.focus_set() + self.advanced = True + else: + self.ClearKeySeq() + self.buttonLevel.config(text='Advanced Key Binding Entry >>') + self.frameKeySeqBasic.lift() + self.frameControlsBasic.lift() + self.advanced = False + + def FinalKeySelected(self,event): + self.BuildKeyString() + + def BuildKeyString(self): + keyList = modifiers = self.GetModifiers() + finalKey = self.listKeysFinal.get(ANCHOR) + if finalKey: + finalKey = self.TranslateKey(finalKey, modifiers) + keyList.append(finalKey) + self.keyString.set('<' + string.join(keyList,'-') + '>') + + def GetModifiers(self): + modList = [variable.get() for variable in self.modifier_vars] + return [mod for mod in modList if mod] + + def ClearKeySeq(self): + self.listKeysFinal.select_clear(0,END) + self.listKeysFinal.yview(MOVETO, '0.0') + for variable in self.modifier_vars: + variable.set('') + self.keyString.set('') + + def LoadFinalKeyList(self): + #these tuples are also available for use in validity checks + self.functionKeys=('F1','F2','F2','F4','F5','F6','F7','F8','F9', + 'F10','F11','F12') + self.alphanumKeys=tuple(string.ascii_lowercase+string.digits) + self.punctuationKeys=tuple('~!@#%^&*()_-+={}[]|;:,.<>/?') + self.whitespaceKeys=('Tab','Space','Return') + self.editKeys=('BackSpace','Delete','Insert') + self.moveKeys=('Home','End','Page Up','Page Down','Left Arrow', + 'Right Arrow','Up Arrow','Down Arrow') + #make a tuple of most of the useful common 'final' keys + keys=(self.alphanumKeys+self.punctuationKeys+self.functionKeys+ + self.whitespaceKeys+self.editKeys+self.moveKeys) + self.listKeysFinal.insert(END, *keys) + + def TranslateKey(self, key, modifiers): + "Translate from keycap symbol to the Tkinter keysym" + translateDict = {'Space':'space', + '~':'asciitilde','!':'exclam','@':'at','#':'numbersign', + '%':'percent','^':'asciicircum','&':'ampersand','*':'asterisk', + '(':'parenleft',')':'parenright','_':'underscore','-':'minus', + '+':'plus','=':'equal','{':'braceleft','}':'braceright', + '[':'bracketleft',']':'bracketright','|':'bar',';':'semicolon', + ':':'colon',',':'comma','.':'period','<':'less','>':'greater', + '/':'slash','?':'question','Page Up':'Prior','Page Down':'Next', + 'Left Arrow':'Left','Right Arrow':'Right','Up Arrow':'Up', + 'Down Arrow': 'Down', 'Tab':'Tab'} + if key in translateDict.keys(): + key = translateDict[key] + if 'Shift' in modifiers and key in string.ascii_lowercase: + key = key.upper() + key = 'Key-' + key + return key + + def OK(self, event=None): + if self.advanced or self.KeysOK(): # doesn't check advanced string yet + self.result=self.keyString.get() + self.destroy() + + def Cancel(self, event=None): + self.result='' + self.destroy() + + def KeysOK(self): + '''Validity check on user's 'basic' keybinding selection. + + Doesn't check the string produced by the advanced dialog because + 'modifiers' isn't set. + + ''' + keys = self.keyString.get() + keys.strip() + finalKey = self.listKeysFinal.get(ANCHOR) + modifiers = self.GetModifiers() + # create a key sequence list for overlap check: + keySequence = keys.split() + keysOK = False + title = 'Key Sequence Error' + if not keys: + tkMessageBox.showerror(title=title, parent=self, + message='No keys specified.') + elif not keys.endswith('>'): + tkMessageBox.showerror(title=title, parent=self, + message='Missing the final Key') + elif (not modifiers + and finalKey not in self.functionKeys + self.moveKeys): + tkMessageBox.showerror(title=title, parent=self, + message='No modifier key(s) specified.') + elif (modifiers == ['Shift']) \ + and (finalKey not in + self.functionKeys + self.moveKeys + ('Tab', 'Space')): + msg = 'The shift modifier by itself may not be used with'\ + ' this key symbol.' + tkMessageBox.showerror(title=title, parent=self, message=msg) + elif keySequence in self.currentKeySequences: + msg = 'This key combination is already in use.' + tkMessageBox.showerror(title=title, parent=self, message=msg) + else: + keysOK = True + return keysOK + +if __name__ == '__main__': + from idlelib.idle_test.htest import run + run(GetKeysDialog) diff --git a/PythonHome/Lib/idlelib/keybindingDialog.pyc b/PythonHome/Lib/idlelib/keybindingDialog.pyc deleted file mode 100644 index bcf0e60b5a6f136e8681bb07cc1ec11ebbf849ab..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 11901 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 Tnu=i%#2V$VaQcU%2nYNR-!mO& diff --git a/PythonHome/Lib/idlelib/macosxSupport.py b/PythonHome/Lib/idlelib/macosxSupport.py new file mode 100644 index 0000000000..4f5259c465 --- /dev/null +++ b/PythonHome/Lib/idlelib/macosxSupport.py @@ -0,0 +1,235 @@ +""" +A number of functions that enhance IDLE on Mac OSX. +""" +import sys +import Tkinter +from os import path + + +import warnings + +def runningAsOSXApp(): + warnings.warn("runningAsOSXApp() is deprecated, use isAquaTk()", + DeprecationWarning, stacklevel=2) + return isAquaTk() + +def isCarbonAquaTk(root): + warnings.warn("isCarbonAquaTk(root) is deprecated, use isCarbonTk()", + DeprecationWarning, stacklevel=2) + return isCarbonTk() + +_tk_type = None + +def _initializeTkVariantTests(root): + """ + Initializes OS X Tk variant values for + isAquaTk(), isCarbonTk(), isCocoaTk(), and isXQuartz(). + """ + global _tk_type + if sys.platform == 'darwin': + ws = root.tk.call('tk', 'windowingsystem') + if 'x11' in ws: + _tk_type = "xquartz" + elif 'aqua' not in ws: + _tk_type = "other" + elif 'AppKit' in root.tk.call('winfo', 'server', '.'): + _tk_type = "cocoa" + else: + _tk_type = "carbon" + else: + _tk_type = "other" + +def isAquaTk(): + """ + Returns True if IDLE is using a native OS X Tk (Cocoa or Carbon). + """ + assert _tk_type is not None + return _tk_type == "cocoa" or _tk_type == "carbon" + +def isCarbonTk(): + """ + Returns True if IDLE is using a Carbon Aqua Tk (instead of the + newer Cocoa Aqua Tk). + """ + assert _tk_type is not None + return _tk_type == "carbon" + +def isCocoaTk(): + """ + Returns True if IDLE is using a Cocoa Aqua Tk. + """ + assert _tk_type is not None + return _tk_type == "cocoa" + +def isXQuartz(): + """ + Returns True if IDLE is using an OS X X11 Tk. + """ + assert _tk_type is not None + return _tk_type == "xquartz" + +def tkVersionWarning(root): + """ + Returns a string warning message if the Tk version in use appears to + be one known to cause problems with IDLE. + 1. Apple Cocoa-based Tk 8.5.7 shipped with Mac OS X 10.6 is unusable. + 2. Apple Cocoa-based Tk 8.5.9 in OS X 10.7 and 10.8 is better but + can still crash unexpectedly. + """ + + if isCocoaTk(): + patchlevel = root.tk.call('info', 'patchlevel') + if patchlevel not in ('8.5.7', '8.5.9'): + return False + return (r"WARNING: The version of Tcl/Tk ({0}) in use may" + r" be unstable.\n" + r"Visit http://www.python.org/download/mac/tcltk/" + r" for current information.".format(patchlevel)) + else: + return False + +def addOpenEventSupport(root, flist): + """ + This ensures that the application will respond to open AppleEvents, which + makes is feasible to use IDLE as the default application for python files. + """ + def doOpenFile(*args): + for fn in args: + flist.open(fn) + + # The command below is a hook in aquatk that is called whenever the app + # receives a file open event. The callback can have multiple arguments, + # one for every file that should be opened. + root.createcommand("::tk::mac::OpenDocument", doOpenFile) + +def hideTkConsole(root): + try: + root.tk.call('console', 'hide') + except Tkinter.TclError: + # Some versions of the Tk framework don't have a console object + pass + +def overrideRootMenu(root, flist): + """ + Replace the Tk root menu by something that is more appropriate for + IDLE with an Aqua Tk. + """ + # The menu that is attached to the Tk root (".") is also used by AquaTk for + # all windows that don't specify a menu of their own. The default menubar + # contains a number of menus, none of which are appropriate for IDLE. The + # Most annoying of those is an 'About Tck/Tk...' menu in the application + # menu. + # + # This function replaces the default menubar by a mostly empty one, it + # should only contain the correct application menu and the window menu. + # + # Due to a (mis-)feature of TkAqua the user will also see an empty Help + # menu. + from Tkinter import Menu, Text, Text + from idlelib.EditorWindow import prepstr, get_accelerator + from idlelib import Bindings + from idlelib import WindowList + from idlelib.MultiCall import MultiCallCreator + + closeItem = Bindings.menudefs[0][1][-2] + + # Remove the last 3 items of the file menu: a separator, close window and + # quit. Close window will be reinserted just above the save item, where + # it should be according to the HIG. Quit is in the application menu. + del Bindings.menudefs[0][1][-3:] + Bindings.menudefs[0][1].insert(6, closeItem) + + # Remove the 'About' entry from the help menu, it is in the application + # menu + del Bindings.menudefs[-1][1][0:2] + + # Remove the 'Configure' entry from the options menu, it is in the + # application menu as 'Preferences' + del Bindings.menudefs[-2][1][0:2] + + menubar = Menu(root) + root.configure(menu=menubar) + menudict = {} + + menudict['windows'] = menu = Menu(menubar, name='windows') + menubar.add_cascade(label='Window', menu=menu, underline=0) + + def postwindowsmenu(menu=menu): + end = menu.index('end') + if end is None: + end = -1 + + if end > 0: + menu.delete(0, end) + WindowList.add_windows_to_menu(menu) + WindowList.register_callback(postwindowsmenu) + + def about_dialog(event=None): + from idlelib import aboutDialog + aboutDialog.AboutDialog(root, 'About IDLE') + + def config_dialog(event=None): + from idlelib import configDialog + root.instance_dict = flist.inversedict + configDialog.ConfigDialog(root, 'Settings') + + def help_dialog(event=None): + from idlelib import textView + fn = path.join(path.abspath(path.dirname(__file__)), 'help.txt') + textView.view_file(root, 'Help', fn) + + root.bind('<>', about_dialog) + root.bind('<>', config_dialog) + root.createcommand('::tk::mac::ShowPreferences', config_dialog) + if flist: + root.bind('<>', flist.close_all_callback) + + # The binding above doesn't reliably work on all versions of Tk + # on MacOSX. Adding command definition below does seem to do the + # right thing for now. + root.createcommand('exit', flist.close_all_callback) + + if isCarbonTk(): + # for Carbon AquaTk, replace the default Tk apple menu + menudict['application'] = menu = Menu(menubar, name='apple') + menubar.add_cascade(label='IDLE', menu=menu) + Bindings.menudefs.insert(0, + ('application', [ + ('About IDLE', '<>'), + None, + ])) + tkversion = root.tk.eval('info patchlevel') + if tuple(map(int, tkversion.split('.'))) < (8, 4, 14): + # for earlier AquaTk versions, supply a Preferences menu item + Bindings.menudefs[0][1].append( + ('_Preferences....', '<>'), + ) + if isCocoaTk(): + # replace default About dialog with About IDLE one + root.createcommand('tkAboutDialog', about_dialog) + # replace default "Help" item in Help menu + root.createcommand('::tk::mac::ShowHelp', help_dialog) + # remove redundant "IDLE Help" from menu + del Bindings.menudefs[-1][1][0] + +def setupApp(root, flist): + """ + Perform initial OS X customizations if needed. + Called from PyShell.main() after initial calls to Tk() + + There are currently three major versions of Tk in use on OS X: + 1. Aqua Cocoa Tk (native default since OS X 10.6) + 2. Aqua Carbon Tk (original native, 32-bit only, deprecated) + 3. X11 (supported by some third-party distributors, deprecated) + There are various differences among the three that affect IDLE + behavior, primarily with menus, mouse key events, and accelerators. + Some one-time customizations are performed here. + Others are dynamically tested throughout idlelib by calls to the + isAquaTk(), isCarbonTk(), isCocoaTk(), isXQuartz() functions which + are initialized here as well. + """ + _initializeTkVariantTests(root) + if isAquaTk(): + hideTkConsole(root) + overrideRootMenu(root, flist) + addOpenEventSupport(root, flist) diff --git a/PythonHome/Lib/idlelib/macosxSupport.pyc b/PythonHome/Lib/idlelib/macosxSupport.pyc deleted file mode 100644 index 1c06608747bad34dc459e6fbc2734fce91ae3e68..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8284 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 lT5>erf, '\n' + '-'*40 + print>>erf, 'Unhandled server exception!' + print>>erf, 'Thread: %s' % threading.currentThread().getName() + print>>erf, 'Client Address: ', client_address + print>>erf, 'Request: ', repr(request) + traceback.print_exc(file=erf) + print>>erf, '\n*** Unrecoverable, server exiting!' + print>>erf, '-'*40 + os._exit(0) + +#----------------- end class RPCServer -------------------- + +objecttable = {} +request_queue = Queue.Queue(0) +response_queue = Queue.Queue(0) + + +class SocketIO(object): + + nextseq = 0 + + def __init__(self, sock, objtable=None, debugging=None): + self.sockthread = threading.currentThread() + if debugging is not None: + self.debugging = debugging + self.sock = sock + if objtable is None: + objtable = objecttable + self.objtable = objtable + self.responses = {} + self.cvars = {} + + def close(self): + sock = self.sock + self.sock = None + if sock is not None: + sock.close() + + def exithook(self): + "override for specific exit action" + os._exit(0) + + def debug(self, *args): + if not self.debugging: + return + s = self.location + " " + str(threading.currentThread().getName()) + for a in args: + s = s + " " + str(a) + print>>sys.__stderr__, s + + def register(self, oid, object): + self.objtable[oid] = object + + def unregister(self, oid): + try: + del self.objtable[oid] + except KeyError: + pass + + def localcall(self, seq, request): + self.debug("localcall:", request) + try: + how, (oid, methodname, args, kwargs) = request + except TypeError: + return ("ERROR", "Bad request format") + if oid not in self.objtable: + return ("ERROR", "Unknown object id: %r" % (oid,)) + obj = self.objtable[oid] + if methodname == "__methods__": + methods = {} + _getmethods(obj, methods) + return ("OK", methods) + if methodname == "__attributes__": + attributes = {} + _getattributes(obj, attributes) + return ("OK", attributes) + if not hasattr(obj, methodname): + return ("ERROR", "Unsupported method name: %r" % (methodname,)) + method = getattr(obj, methodname) + try: + if how == 'CALL': + ret = method(*args, **kwargs) + if isinstance(ret, RemoteObject): + ret = remoteref(ret) + return ("OK", ret) + elif how == 'QUEUE': + request_queue.put((seq, (method, args, kwargs))) + return("QUEUED", None) + else: + return ("ERROR", "Unsupported message type: %s" % how) + except SystemExit: + raise + except socket.error: + raise + except: + msg = "*** Internal Error: rpc.py:SocketIO.localcall()\n\n"\ + " Object: %s \n Method: %s \n Args: %s\n" + print>>sys.__stderr__, msg % (oid, method, args) + traceback.print_exc(file=sys.__stderr__) + return ("EXCEPTION", None) + + def remotecall(self, oid, methodname, args, kwargs): + self.debug("remotecall:asynccall: ", oid, methodname) + seq = self.asynccall(oid, methodname, args, kwargs) + return self.asyncreturn(seq) + + def remotequeue(self, oid, methodname, args, kwargs): + self.debug("remotequeue:asyncqueue: ", oid, methodname) + seq = self.asyncqueue(oid, methodname, args, kwargs) + return self.asyncreturn(seq) + + def asynccall(self, oid, methodname, args, kwargs): + request = ("CALL", (oid, methodname, args, kwargs)) + seq = self.newseq() + if threading.currentThread() != self.sockthread: + cvar = threading.Condition() + self.cvars[seq] = cvar + self.debug(("asynccall:%d:" % seq), oid, methodname, args, kwargs) + self.putmessage((seq, request)) + return seq + + def asyncqueue(self, oid, methodname, args, kwargs): + request = ("QUEUE", (oid, methodname, args, kwargs)) + seq = self.newseq() + if threading.currentThread() != self.sockthread: + cvar = threading.Condition() + self.cvars[seq] = cvar + self.debug(("asyncqueue:%d:" % seq), oid, methodname, args, kwargs) + self.putmessage((seq, request)) + return seq + + def asyncreturn(self, seq): + self.debug("asyncreturn:%d:call getresponse(): " % seq) + response = self.getresponse(seq, wait=0.05) + self.debug(("asyncreturn:%d:response: " % seq), response) + return self.decoderesponse(response) + + def decoderesponse(self, response): + how, what = response + if how == "OK": + return what + if how == "QUEUED": + return None + if how == "EXCEPTION": + self.debug("decoderesponse: EXCEPTION") + return None + if how == "EOF": + self.debug("decoderesponse: EOF") + self.decode_interrupthook() + return None + if how == "ERROR": + self.debug("decoderesponse: Internal ERROR:", what) + raise RuntimeError, what + raise SystemError, (how, what) + + def decode_interrupthook(self): + "" + raise EOFError + + def mainloop(self): + """Listen on socket until I/O not ready or EOF + + pollresponse() will loop looking for seq number None, which + never comes, and exit on EOFError. + + """ + try: + self.getresponse(myseq=None, wait=0.05) + except EOFError: + self.debug("mainloop:return") + return + + def getresponse(self, myseq, wait): + response = self._getresponse(myseq, wait) + if response is not None: + how, what = response + if how == "OK": + response = how, self._proxify(what) + return response + + def _proxify(self, obj): + if isinstance(obj, RemoteProxy): + return RPCProxy(self, obj.oid) + if isinstance(obj, types.ListType): + return map(self._proxify, obj) + # XXX Check for other types -- not currently needed + return obj + + def _getresponse(self, myseq, wait): + self.debug("_getresponse:myseq:", myseq) + if threading.currentThread() is self.sockthread: + # this thread does all reading of requests or responses + while 1: + response = self.pollresponse(myseq, wait) + if response is not None: + return response + else: + # wait for notification from socket handling thread + cvar = self.cvars[myseq] + cvar.acquire() + while myseq not in self.responses: + cvar.wait() + response = self.responses[myseq] + self.debug("_getresponse:%s: thread woke up: response: %s" % + (myseq, response)) + del self.responses[myseq] + del self.cvars[myseq] + cvar.release() + return response + + def newseq(self): + self.nextseq = seq = self.nextseq + 2 + return seq + + def putmessage(self, message): + self.debug("putmessage:%d:" % message[0]) + try: + s = pickle.dumps(message) + except pickle.PicklingError: + print >>sys.__stderr__, "Cannot pickle:", repr(message) + raise + s = struct.pack(" 0: + try: + r, w, x = select.select([], [self.sock], []) + n = self.sock.send(s[:BUFSIZE]) + except (AttributeError, TypeError): + raise IOError, "socket no longer exists" + except socket.error: + raise + else: + s = s[n:] + + buffer = "" + bufneed = 4 + bufstate = 0 # meaning: 0 => reading count; 1 => reading data + + def pollpacket(self, wait): + self._stage0() + if len(self.buffer) < self.bufneed: + r, w, x = select.select([self.sock.fileno()], [], [], wait) + if len(r) == 0: + return None + try: + s = self.sock.recv(BUFSIZE) + except socket.error: + raise EOFError + if len(s) == 0: + raise EOFError + self.buffer += s + self._stage0() + return self._stage1() + + def _stage0(self): + if self.bufstate == 0 and len(self.buffer) >= 4: + s = self.buffer[:4] + self.buffer = self.buffer[4:] + self.bufneed = struct.unpack("= self.bufneed: + packet = self.buffer[:self.bufneed] + self.buffer = self.buffer[self.bufneed:] + self.bufneed = 4 + self.bufstate = 0 + return packet + + def pollmessage(self, wait): + packet = self.pollpacket(wait) + if packet is None: + return None + try: + message = pickle.loads(packet) + except pickle.UnpicklingError: + print >>sys.__stderr__, "-----------------------" + print >>sys.__stderr__, "cannot unpickle packet:", repr(packet) + traceback.print_stack(file=sys.__stderr__) + print >>sys.__stderr__, "-----------------------" + raise + return message + + def pollresponse(self, myseq, wait): + """Handle messages received on the socket. + + Some messages received may be asynchronous 'call' or 'queue' requests, + and some may be responses for other threads. + + 'call' requests are passed to self.localcall() with the expectation of + immediate execution, during which time the socket is not serviced. + + 'queue' requests are used for tasks (which may block or hang) to be + processed in a different thread. These requests are fed into + request_queue by self.localcall(). Responses to queued requests are + taken from response_queue and sent across the link with the associated + sequence numbers. Messages in the queues are (sequence_number, + request/response) tuples and code using this module removing messages + from the request_queue is responsible for returning the correct + sequence number in the response_queue. + + pollresponse() will loop until a response message with the myseq + sequence number is received, and will save other responses in + self.responses and notify the owning thread. + + """ + while 1: + # send queued response if there is one available + try: + qmsg = response_queue.get(0) + except Queue.Empty: + pass + else: + seq, response = qmsg + message = (seq, ('OK', response)) + self.putmessage(message) + # poll for message on link + try: + message = self.pollmessage(wait) + if message is None: # socket not ready + return None + except EOFError: + self.handle_EOF() + return None + except AttributeError: + return None + seq, resq = message + how = resq[0] + self.debug("pollresponse:%d:myseq:%s" % (seq, myseq)) + # process or queue a request + if how in ("CALL", "QUEUE"): + self.debug("pollresponse:%d:localcall:call:" % seq) + response = self.localcall(seq, resq) + self.debug("pollresponse:%d:localcall:response:%s" + % (seq, response)) + if how == "CALL": + self.putmessage((seq, response)) + elif how == "QUEUE": + # don't acknowledge the 'queue' request! + pass + continue + # return if completed message transaction + elif seq == myseq: + return resq + # must be a response for a different thread: + else: + cv = self.cvars.get(seq, None) + # response involving unknown sequence number is discarded, + # probably intended for prior incarnation of server + if cv is not None: + cv.acquire() + self.responses[seq] = resq + cv.notify() + cv.release() + continue + + def handle_EOF(self): + "action taken upon link being closed by peer" + self.EOFhook() + self.debug("handle_EOF") + for key in self.cvars: + cv = self.cvars[key] + cv.acquire() + self.responses[key] = ('EOF', None) + cv.notify() + cv.release() + # call our (possibly overridden) exit function + self.exithook() + + def EOFhook(self): + "Classes using rpc client/server can override to augment EOF action" + pass + +#----------------- end class SocketIO -------------------- + +class RemoteObject(object): + # Token mix-in class + pass + +def remoteref(obj): + oid = id(obj) + objecttable[oid] = obj + return RemoteProxy(oid) + +class RemoteProxy(object): + + def __init__(self, oid): + self.oid = oid + +class RPCHandler(SocketServer.BaseRequestHandler, SocketIO): + + debugging = False + location = "#S" # Server + + def __init__(self, sock, addr, svr): + svr.current_handler = self ## cgt xxx + SocketIO.__init__(self, sock) + SocketServer.BaseRequestHandler.__init__(self, sock, addr, svr) + + def handle(self): + "handle() method required by SocketServer" + self.mainloop() + + def get_remote_proxy(self, oid): + return RPCProxy(self, oid) + +class RPCClient(SocketIO): + + debugging = False + location = "#C" # Client + + nextseq = 1 # Requests coming from the client are odd numbered + + def __init__(self, address, family=socket.AF_INET, type=socket.SOCK_STREAM): + self.listening_sock = socket.socket(family, type) + self.listening_sock.bind(address) + self.listening_sock.listen(1) + + def accept(self): + working_sock, address = self.listening_sock.accept() + if self.debugging: + print>>sys.__stderr__, "****** Connection request from ", address + if address[0] == LOCALHOST: + SocketIO.__init__(self, working_sock) + else: + print>>sys.__stderr__, "** Invalid host: ", address + raise socket.error + + def get_remote_proxy(self, oid): + return RPCProxy(self, oid) + +class RPCProxy(object): + + __methods = None + __attributes = None + + def __init__(self, sockio, oid): + self.sockio = sockio + self.oid = oid + + def __getattr__(self, name): + if self.__methods is None: + self.__getmethods() + if self.__methods.get(name): + return MethodProxy(self.sockio, self.oid, name) + if self.__attributes is None: + self.__getattributes() + if name in self.__attributes: + value = self.sockio.remotecall(self.oid, '__getattribute__', + (name,), {}) + return value + else: + raise AttributeError, name + + def __getattributes(self): + self.__attributes = self.sockio.remotecall(self.oid, + "__attributes__", (), {}) + + def __getmethods(self): + self.__methods = self.sockio.remotecall(self.oid, + "__methods__", (), {}) + +def _getmethods(obj, methods): + # Helper to get a list of methods from an object + # Adds names to dictionary argument 'methods' + for name in dir(obj): + attr = getattr(obj, name) + if hasattr(attr, '__call__'): + methods[name] = 1 + if type(obj) == types.InstanceType: + _getmethods(obj.__class__, methods) + if type(obj) == types.ClassType: + for super in obj.__bases__: + _getmethods(super, methods) + +def _getattributes(obj, attributes): + for name in dir(obj): + attr = getattr(obj, name) + if not hasattr(attr, '__call__'): + attributes[name] = 1 + +class MethodProxy(object): + + def __init__(self, sockio, oid, name): + self.sockio = sockio + self.oid = oid + self.name = name + + def __call__(self, *args, **kwargs): + value = self.sockio.remotecall(self.oid, self.name, args, kwargs) + return value + + +# XXX KBK 09Sep03 We need a proper unit test for this module. Previously +# existing test code was removed at Rev 1.27 (r34098). diff --git a/PythonHome/Lib/idlelib/rpc.pyc b/PythonHome/Lib/idlelib/rpc.pyc deleted file mode 100644 index 8612fb50455ee2e370ccd95b043ea455b0324a32..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 20887 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 1) + port = int(sys.argv[-1]) + except: + print>>sys.stderr, "IDLE Subprocess: no IP port passed in sys.argv." + return + + capture_warnings(True) + sys.argv[:] = [""] + sockthread = threading.Thread(target=manage_socket, + name='SockThread', + args=((LOCALHOST, port),)) + sockthread.setDaemon(True) + sockthread.start() + while 1: + try: + if exit_now: + try: + exit() + except KeyboardInterrupt: + # exiting but got an extra KBI? Try again! + continue + try: + seq, request = rpc.request_queue.get(block=True, timeout=0.05) + except Queue.Empty: + continue + method, args, kwargs = request + ret = method(*args, **kwargs) + rpc.response_queue.put((seq, ret)) + except KeyboardInterrupt: + if quitting: + exit_now = True + continue + except SystemExit: + capture_warnings(False) + raise + except: + type, value, tb = sys.exc_info() + try: + print_exception() + rpc.response_queue.put((seq, None)) + except: + # Link didn't work, print same exception to __stderr__ + traceback.print_exception(type, value, tb, file=sys.__stderr__) + exit() + else: + continue + +def manage_socket(address): + for i in range(3): + time.sleep(i) + try: + server = MyRPCServer(address, MyHandler) + break + except socket.error as err: + print>>sys.__stderr__,"IDLE Subprocess: socket error: "\ + + err.args[1] + ", retrying...." + else: + print>>sys.__stderr__, "IDLE Subprocess: Connection to "\ + "IDLE GUI failed, exiting." + show_socket_error(err, address) + global exit_now + exit_now = True + return + server.handle_request() # A single request only + +def show_socket_error(err, address): + import Tkinter + import tkMessageBox + root = Tkinter.Tk() + root.withdraw() + if err.args[0] == 61: # connection refused + msg = "IDLE's subprocess can't connect to %s:%d. This may be due "\ + "to your personal firewall configuration. It is safe to "\ + "allow this internal connection because no data is visible on "\ + "external ports." % address + tkMessageBox.showerror("IDLE Subprocess Error", msg, parent=root) + else: + tkMessageBox.showerror("IDLE Subprocess Error", + "Socket Error: %s" % err.args[1]) + root.destroy() + +def print_exception(): + import linecache + linecache.checkcache() + flush_stdout() + efile = sys.stderr + typ, val, tb = excinfo = sys.exc_info() + sys.last_type, sys.last_value, sys.last_traceback = excinfo + tbe = traceback.extract_tb(tb) + print>>efile, '\nTraceback (most recent call last):' + exclude = ("run.py", "rpc.py", "threading.py", "Queue.py", + "RemoteDebugger.py", "bdb.py") + cleanup_traceback(tbe, exclude) + traceback.print_list(tbe, file=efile) + lines = traceback.format_exception_only(typ, val) + for line in lines: + print>>efile, line, + +def cleanup_traceback(tb, exclude): + "Remove excluded traces from beginning/end of tb; get cached lines" + orig_tb = tb[:] + while tb: + for rpcfile in exclude: + if tb[0][0].count(rpcfile): + break # found an exclude, break for: and delete tb[0] + else: + break # no excludes, have left RPC code, break while: + del tb[0] + while tb: + for rpcfile in exclude: + if tb[-1][0].count(rpcfile): + break + else: + break + del tb[-1] + if len(tb) == 0: + # exception was in IDLE internals, don't prune! + tb[:] = orig_tb[:] + print>>sys.stderr, "** IDLE Internal Exception: " + rpchandler = rpc.objecttable['exec'].rpchandler + for i in range(len(tb)): + fn, ln, nm, line = tb[i] + if nm == '?': + nm = "-toplevel-" + if not line and fn.startswith(">erf, '\n' + '-'*40 + print>>erf, 'Unhandled server exception!' + print>>erf, 'Thread: %s' % threading.currentThread().getName() + print>>erf, 'Client Address: ', client_address + print>>erf, 'Request: ', repr(request) + traceback.print_exc(file=erf) + print>>erf, '\n*** Unrecoverable, server exiting!' + print>>erf, '-'*40 + quitting = True + thread.interrupt_main() + +class MyHandler(rpc.RPCHandler): + + def handle(self): + """Override base method""" + executive = Executive(self) + self.register("exec", executive) + self.console = self.get_remote_proxy("console") + sys.stdin = PyShell.PseudoInputFile(self.console, "stdin", + IOBinding.encoding) + sys.stdout = PyShell.PseudoOutputFile(self.console, "stdout", + IOBinding.encoding) + sys.stderr = PyShell.PseudoOutputFile(self.console, "stderr", + IOBinding.encoding) + + # Keep a reference to stdin so that it won't try to exit IDLE if + # sys.stdin gets changed from within IDLE's shell. See issue17838. + self._keep_stdin = sys.stdin + + self.interp = self.get_remote_proxy("interp") + rpc.RPCHandler.getresponse(self, myseq=None, wait=0.05) + + def exithook(self): + "override SocketIO method - wait for MainThread to shut us down" + time.sleep(10) + + def EOFhook(self): + "Override SocketIO method - terminate wait on callback and exit thread" + global quitting + quitting = True + thread.interrupt_main() + + def decode_interrupthook(self): + "interrupt awakened thread" + global quitting + quitting = True + thread.interrupt_main() + + +class Executive(object): + + def __init__(self, rpchandler): + self.rpchandler = rpchandler + self.locals = __main__.__dict__ + self.calltip = CallTips.CallTips() + self.autocomplete = AutoComplete.AutoComplete() + + def runcode(self, code): + global interruptable + try: + self.usr_exc_info = None + interruptable = True + try: + exec code in self.locals + finally: + interruptable = False + except SystemExit: + # Scripts that raise SystemExit should just + # return to the interactive prompt + pass + except: + self.usr_exc_info = sys.exc_info() + if quitting: + exit() + print_exception() + jit = self.rpchandler.console.getvar("<>") + if jit: + self.rpchandler.interp.open_remote_stack_viewer() + else: + flush_stdout() + + def interrupt_the_server(self): + if interruptable: + thread.interrupt_main() + + def start_the_debugger(self, gui_adap_oid): + return RemoteDebugger.start_debugger(self.rpchandler, gui_adap_oid) + + def stop_the_debugger(self, idb_adap_oid): + "Unregister the Idb Adapter. Link objects and Idb then subject to GC" + self.rpchandler.unregister(idb_adap_oid) + + def get_the_calltip(self, name): + return self.calltip.fetch_tip(name) + + def get_the_completion_list(self, what, mode): + return self.autocomplete.fetch_completions(what, mode) + + def stackviewer(self, flist_oid=None): + if self.usr_exc_info: + typ, val, tb = self.usr_exc_info + else: + return None + flist = None + if flist_oid is not None: + flist = self.rpchandler.get_remote_proxy(flist_oid) + while tb and tb.tb_frame.f_globals["__name__"] in ["rpc", "run"]: + tb = tb.tb_next + sys.last_type = typ + sys.last_value = val + item = StackViewer.StackTreeItem(flist, tb) + return RemoteObjectBrowser.remote_object_tree_item(item) + +capture_warnings(False) # Make sure turned off; see issue 18081 diff --git a/PythonHome/Lib/idlelib/run.pyc b/PythonHome/Lib/idlelib/run.pyc deleted file mode 100644 index 281f78a0bd04b053f54175c58c0972b5cf2e9603..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 12421 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

nyVmR~6qPrTs8n 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""" + if not tab_name in self._tab_names: + raise KeyError("No such Tab: '%s" % page_name) + + self._tab_names.remove(tab_name) + self._arrange_tabs() + + def set_selected_tab(self, tab_name): + """Show the tab named as the selected one""" + if tab_name == self._selected_tab: + return + if tab_name is not None and tab_name not in self._tabs: + raise KeyError("No such Tab: '%s" % page_name) + + # deselect the current selected tab + if self._selected_tab is not None: + self._tabs[self._selected_tab].set_normal() + self._selected_tab = None + + if tab_name is not None: + # activate the tab named tab_name + self._selected_tab = tab_name + tab = self._tabs[tab_name] + tab.set_selected() + # move the tab row with the selected tab to the bottom + tab_row = self._tab2row[tab] + tab_row.pack_forget() + tab_row.pack(side=TOP, fill=X, expand=0) + + def _add_tab_row(self, tab_names, expand_tabs): + if not tab_names: + return + + tab_row = Frame(self) + tab_row.pack(side=TOP, fill=X, expand=0) + self._tab_rows.append(tab_row) + + for tab_name in tab_names: + tab = TabSet.TabButton(tab_name, self.select_command, + tab_row, self) + if expand_tabs: + tab.pack(side=LEFT, fill=X, expand=True) + else: + tab.pack(side=LEFT) + self._tabs[tab_name] = tab + self._tab2row[tab] = tab_row + + # tab is the last one created in the above loop + tab.is_last_in_row = True + + def _reset_tab_rows(self): + while self._tab_rows: + tab_row = self._tab_rows.pop() + tab_row.destroy() + self._tab2row = {} + + def _arrange_tabs(self): + """ + Arrange the tabs in rows, in the order in which they were added. + + If n_rows >= 1, this will be the number of rows used. Otherwise the + number of rows will be calculated according to the number of tabs and + max_tabs_per_row. In this case, the number of rows may change when + adding/removing tabs. + + """ + # remove all tabs and rows + for tab_name in self._tabs.keys(): + self._tabs.pop(tab_name).destroy() + self._reset_tab_rows() + + if not self._tab_names: + return + + if self.n_rows is not None and self.n_rows > 0: + n_rows = self.n_rows + else: + # calculate the required number of rows + n_rows = (len(self._tab_names) - 1) // self.max_tabs_per_row + 1 + + # not expanding the tabs with more than one row is very ugly + expand_tabs = self.expand_tabs or n_rows > 1 + i = 0 # index in self._tab_names + for row_index in xrange(n_rows): + # calculate required number of tabs in this row + n_tabs = (len(self._tab_names) - i - 1) // (n_rows - row_index) + 1 + tab_names = self._tab_names[i:i + n_tabs] + i += n_tabs + self._add_tab_row(tab_names, expand_tabs) + + # re-select selected tab so it is properly displayed + selected = self._selected_tab + self.set_selected_tab(None) + if selected in self._tab_names: + self.set_selected_tab(selected) + + class TabButton(Frame): + """A simple tab-like widget.""" + + bw = 2 # borderwidth + + def __init__(self, name, select_command, tab_row, tab_set): + """Constructor arguments: + + name -- The tab's name, which will appear in its button. + + select_command -- The command to be called upon selection of the + tab. It is called with the tab's name as an argument. + + """ + Frame.__init__(self, tab_row, borderwidth=self.bw, relief=RAISED) + + self.name = name + self.select_command = select_command + self.tab_set = tab_set + self.is_last_in_row = False + + self.button = Radiobutton( + self, text=name, command=self._select_event, + padx=5, pady=1, takefocus=FALSE, indicatoron=FALSE, + highlightthickness=0, selectcolor='', borderwidth=0) + self.button.pack(side=LEFT, fill=X, expand=True) + + self._init_masks() + self.set_normal() + + def _select_event(self, *args): + """Event handler for tab selection. + + With TabbedPageSet, this calls TabbedPageSet.change_page, so that + selecting a tab changes the page. + + Note that this does -not- call set_selected -- it will be called by + TabSet.set_selected_tab, which should be called when whatever the + tabs are related to changes. + + """ + self.select_command(self.name) + return + + def set_selected(self): + """Assume selected look""" + self._place_masks(selected=True) + + def set_normal(self): + """Assume normal look""" + self._place_masks(selected=False) + + def _init_masks(self): + page_set = self.tab_set.page_set + background = page_set.pages_frame.cget('background') + # mask replaces the middle of the border with the background color + self.mask = Frame(page_set, borderwidth=0, relief=FLAT, + background=background) + # mskl replaces the bottom-left corner of the border with a normal + # left border + self.mskl = Frame(page_set, borderwidth=0, relief=FLAT, + background=background) + self.mskl.ml = Frame(self.mskl, borderwidth=self.bw, + relief=RAISED) + self.mskl.ml.place(x=0, y=-self.bw, + width=2*self.bw, height=self.bw*4) + # mskr replaces the bottom-right corner of the border with a normal + # right border + self.mskr = Frame(page_set, borderwidth=0, relief=FLAT, + background=background) + self.mskr.mr = Frame(self.mskr, borderwidth=self.bw, + relief=RAISED) + + def _place_masks(self, selected=False): + height = self.bw + if selected: + height += self.bw + + self.mask.place(in_=self, + relx=0.0, x=0, + rely=1.0, y=0, + relwidth=1.0, width=0, + relheight=0.0, height=height) + + self.mskl.place(in_=self, + relx=0.0, x=-self.bw, + rely=1.0, y=0, + relwidth=0.0, width=self.bw, + relheight=0.0, height=height) + + page_set = self.tab_set.page_set + if selected and ((not self.is_last_in_row) or + (self.winfo_rootx() + self.winfo_width() < + page_set.winfo_rootx() + page_set.winfo_width()) + ): + # for a selected tab, if its rightmost edge isn't on the + # rightmost edge of the page set, the right mask should be one + # borderwidth shorter (vertically) + height -= self.bw + + self.mskr.place(in_=self, + relx=1.0, x=0, + rely=1.0, y=0, + relwidth=0.0, width=self.bw, + relheight=0.0, height=height) + + self.mskr.mr.place(x=-self.bw, y=-self.bw, + width=2*self.bw, height=height + self.bw*2) + + # finally, lower the tab set so that all of the frames we just + # placed hide it + self.tab_set.lower() + +class TabbedPageSet(Frame): + """A Tkinter tabbed-pane widget. + + Constains set of 'pages' (or 'panes') with tabs above for selecting which + page is displayed. Only one page will be displayed at a time. + + Pages may be accessed through the 'pages' attribute, which is a dictionary + of pages, using the name given as the key. A page is an instance of a + subclass of Tk's Frame widget. + + The page widgets will be created (and destroyed when required) by the + TabbedPageSet. Do not call the page's pack/place/grid/destroy methods. + + Pages may be added or removed at any time using the add_page() and + remove_page() methods. + + """ + class Page(object): + """Abstract base class for TabbedPageSet's pages. + + Subclasses must override the _show() and _hide() methods. + + """ + uses_grid = False + + def __init__(self, page_set): + self.frame = Frame(page_set, borderwidth=2, relief=RAISED) + + def _show(self): + raise NotImplementedError + + def _hide(self): + raise NotImplementedError + + class PageRemove(Page): + """Page class using the grid placement manager's "remove" mechanism.""" + uses_grid = True + + def _show(self): + self.frame.grid(row=0, column=0, sticky=NSEW) + + def _hide(self): + self.frame.grid_remove() + + class PageLift(Page): + """Page class using the grid placement manager's "lift" mechanism.""" + uses_grid = True + + def __init__(self, page_set): + super(TabbedPageSet.PageLift, self).__init__(page_set) + self.frame.grid(row=0, column=0, sticky=NSEW) + self.frame.lower() + + def _show(self): + self.frame.lift() + + def _hide(self): + self.frame.lower() + + class PagePackForget(Page): + """Page class using the pack placement manager's "forget" mechanism.""" + def _show(self): + self.frame.pack(fill=BOTH, expand=True) + + def _hide(self): + self.frame.pack_forget() + + def __init__(self, parent, page_names=None, page_class=PageLift, + n_rows=1, max_tabs_per_row=5, expand_tabs=False, + **kw): + """Constructor arguments: + + page_names -- A list of strings, each will be the dictionary key to a + page's widget, and the name displayed on the page's tab. Should be + specified in the desired page order. The first page will be the default + and first active page. If page_names is None or empty, the + TabbedPageSet will be initialized empty. + + n_rows, max_tabs_per_row -- Parameters for the TabSet which will + manage the tabs. See TabSet's docs for details. + + page_class -- Pages can be shown/hidden using three mechanisms: + + * PageLift - All pages will be rendered one on top of the other. When + a page is selected, it will be brought to the top, thus hiding all + other pages. Using this method, the TabbedPageSet will not be resized + when pages are switched. (It may still be resized when pages are + added/removed.) + + * PageRemove - When a page is selected, the currently showing page is + hidden, and the new page shown in its place. Using this method, the + TabbedPageSet may resize when pages are changed. + + * PagePackForget - This mechanism uses the pack placement manager. + When a page is shown it is packed, and when it is hidden it is + unpacked (i.e. pack_forget). This mechanism may also cause the + TabbedPageSet to resize when the page is changed. + + """ + Frame.__init__(self, parent, **kw) + + self.page_class = page_class + self.pages = {} + self._pages_order = [] + self._current_page = None + self._default_page = None + + self.columnconfigure(0, weight=1) + self.rowconfigure(1, weight=1) + + self.pages_frame = Frame(self) + self.pages_frame.grid(row=1, column=0, sticky=NSEW) + if self.page_class.uses_grid: + self.pages_frame.columnconfigure(0, weight=1) + self.pages_frame.rowconfigure(0, weight=1) + + # the order of the following commands is important + self._tab_set = TabSet(self, self.change_page, n_rows=n_rows, + max_tabs_per_row=max_tabs_per_row, + expand_tabs=expand_tabs) + if page_names: + for name in page_names: + self.add_page(name) + self._tab_set.grid(row=0, column=0, sticky=NSEW) + + self.change_page(self._default_page) + + def add_page(self, page_name): + """Add a new page with the name given in page_name.""" + if not page_name: + raise InvalidNameError("Invalid TabPage name: '%s'" % page_name) + if page_name in self.pages: + raise AlreadyExistsError( + "TabPage named '%s' already exists" % page_name) + + self.pages[page_name] = self.page_class(self.pages_frame) + self._pages_order.append(page_name) + self._tab_set.add_tab(page_name) + + if len(self.pages) == 1: # adding first page + self._default_page = page_name + self.change_page(page_name) + + def remove_page(self, page_name): + """Destroy the page whose name is given in page_name.""" + if not page_name in self.pages: + raise KeyError("No such TabPage: '%s" % page_name) + + self._pages_order.remove(page_name) + + # handle removing last remaining, default, or currently shown page + if len(self._pages_order) > 0: + if page_name == self._default_page: + # set a new default page + self._default_page = self._pages_order[0] + else: + self._default_page = None + + if page_name == self._current_page: + self.change_page(self._default_page) + + self._tab_set.remove_tab(page_name) + page = self.pages.pop(page_name) + page.frame.destroy() + + def change_page(self, page_name): + """Show the page whose name is given in page_name.""" + if self._current_page == page_name: + return + if page_name is not None and page_name not in self.pages: + raise KeyError("No such TabPage: '%s'" % page_name) + + if self._current_page is not None: + self.pages[self._current_page]._hide() + self._current_page = None + + if page_name is not None: + self._current_page = page_name + self.pages[page_name]._show() + + self._tab_set.set_selected_tab(page_name) + +def _tabbed_pages(parent): + # test dialog + root=Tk() + width, height, x, y = list(map(int, re.split('[x+]', parent.geometry()))) + root.geometry("+%d+%d"%(x, y + 175)) + root.title("Test tabbed pages") + tabPage=TabbedPageSet(root, page_names=['Foobar','Baz'], n_rows=0, + expand_tabs=False, + ) + tabPage.pack(side=TOP, expand=TRUE, fill=BOTH) + Label(tabPage.pages['Foobar'].frame, text='Foo', pady=20).pack() + Label(tabPage.pages['Foobar'].frame, text='Bar', pady=20).pack() + Label(tabPage.pages['Baz'].frame, text='Baz').pack() + entryPgName=Entry(root) + buttonAdd=Button(root, text='Add Page', + command=lambda:tabPage.add_page(entryPgName.get())) + buttonRemove=Button(root, text='Remove Page', + command=lambda:tabPage.remove_page(entryPgName.get())) + labelPgName=Label(root, text='name of page to add/remove:') + buttonAdd.pack(padx=5, pady=5) + buttonRemove.pack(padx=5, pady=5) + labelPgName.pack(padx=5) + entryPgName.pack(padx=5) + root.mainloop() + + +if __name__ == '__main__': + from idlelib.idle_test.htest import run + run(_tabbed_pages) diff --git a/PythonHome/Lib/idlelib/tabbedpages.pyc b/PythonHome/Lib/idlelib/tabbedpages.pyc deleted file mode 100644 index e3aea6a9ce033c69a6d44ffd8d74ea8bb9080806..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 17961 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 Ky73Ite*PcCbjPy* diff --git a/PythonHome/Lib/idlelib/testcode.py b/PythonHome/Lib/idlelib/testcode.py new file mode 100644 index 0000000000..05eaa562cd --- /dev/null +++ b/PythonHome/Lib/idlelib/testcode.py @@ -0,0 +1,31 @@ +import string + +def f(): + a = 0 + b = 1 + c = 2 + d = 3 + e = 4 + g() + +def g(): + h() + +def h(): + i() + +def i(): + j() + +def j(): + k() + +def k(): + l() + +l = lambda: test() + +def test(): + string.capwords(1) + +f() diff --git a/PythonHome/Lib/idlelib/testcode.pyc b/PythonHome/Lib/idlelib/testcode.pyc deleted file mode 100644 index 63d5a1993f9f18353db7cf83ea4275e42fee4123..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1289 zcmbu8&q~8U5XL8enkKahiXe&)5HEcKDS}tYVS5myplLSNt*I^DhOQv17iF5#f#RbY)9U)$aZ$v{9Z5?lWo@Zuz~)AtPmOzE%r&CGtRi- zx(wOd0ylHR#f;kD0{7^KOBi*y1+H?#q3DnP!Xevjsf?sRe#!)ejOufu)yU;}mCq+S zAD)29gVyze@{#gHx|uoSKI8uMxIfWV_?$^YiLKFPwqBX1sl+Yv<;!BFt<#DWdgT;> z+S*N#eue5%2rs3rkOGCJEBT6)Db&0C?1XC*Fkk5BsvM%}>;X&PPvRt4pMDa21KM}K A-2eap diff --git a/PythonHome/Lib/idlelib/textView.py b/PythonHome/Lib/idlelib/textView.py new file mode 100644 index 0000000000..eb60274156 --- /dev/null +++ b/PythonHome/Lib/idlelib/textView.py @@ -0,0 +1,90 @@ +"""Simple text browser for IDLE + +""" + +from Tkinter import * +import tkMessageBox + +class TextViewer(Toplevel): + """A simple text viewer dialog for IDLE + + """ + def __init__(self, parent, title, text, modal=True, _htest=False): + """Show the given text in a scrollable window with a 'close' button + + If modal option set to False, user can interact with other windows, + otherwise they will be unable to interact with other windows until + the textview window is closed. + + _htest - bool; change box location when running htest. + """ + Toplevel.__init__(self, parent) + self.configure(borderwidth=5) + # place dialog below parent if running htest + self.geometry("=%dx%d+%d+%d" % (625, 500, + parent.winfo_rootx() + 10, + parent.winfo_rooty() + (10 if not _htest else 100))) + #elguavas - config placeholders til config stuff completed + self.bg = '#ffffff' + self.fg = '#000000' + + self.CreateWidgets() + self.title(title) + self.protocol("WM_DELETE_WINDOW", self.Ok) + self.parent = parent + self.textView.focus_set() + #key bindings for this dialog + self.bind('',self.Ok) #dismiss dialog + self.bind('',self.Ok) #dismiss dialog + self.textView.insert(0.0, text) + self.textView.config(state=DISABLED) + + if modal: + self.transient(parent) + self.grab_set() + self.wait_window() + + def CreateWidgets(self): + frameText = Frame(self, relief=SUNKEN, height=700) + frameButtons = Frame(self) + self.buttonOk = Button(frameButtons, text='Close', + command=self.Ok, takefocus=FALSE) + self.scrollbarView = Scrollbar(frameText, orient=VERTICAL, + takefocus=FALSE, highlightthickness=0) + self.textView = Text(frameText, wrap=WORD, highlightthickness=0, + fg=self.fg, bg=self.bg) + self.scrollbarView.config(command=self.textView.yview) + self.textView.config(yscrollcommand=self.scrollbarView.set) + self.buttonOk.pack() + self.scrollbarView.pack(side=RIGHT,fill=Y) + self.textView.pack(side=LEFT,expand=TRUE,fill=BOTH) + frameButtons.pack(side=BOTTOM,fill=X) + frameText.pack(side=TOP,expand=TRUE,fill=BOTH) + + def Ok(self, event=None): + self.destroy() + + +def view_text(parent, title, text, modal=True): + return TextViewer(parent, title, text, modal) + +def view_file(parent, title, filename, encoding=None, modal=True): + try: + if encoding: + import codecs + textFile = codecs.open(filename, 'r') + else: + textFile = open(filename, 'r') + except IOError: + tkMessageBox.showerror(title='File Load Error', + message='Unable to load file %r .' % filename, + parent=parent) + else: + return view_text(parent, title, textFile.read(), modal) + + +if __name__ == '__main__': + import unittest + unittest.main('idlelib.idle_test.test_textview', verbosity=2, exit=False) + from idlelib.idle_test.htest import run + run(TextViewer) diff --git a/PythonHome/Lib/idlelib/textView.pyc b/PythonHome/Lib/idlelib/textView.pyc deleted file mode 100644 index c6f8430fdadfdc51c98afec4a3b07acf5bd56f15..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3724 zcmb7HTTdLx6+YDi0}PkJ#>V#MvK_6gopm%`RH0)ze)w)6jI2 z?ivG<{e<80l;=F;k3`CkO5T(2J3WAtl~zvUs;N4s>fGv_ugZ;oF1I@W_)9OA>DR>X z7iiVr&?O>==#3-^`1qqRg0gb zQC5uJv&+X9GvI7+yA3$D#b`A}7_srOSm?p!On zt0SgB8!52LkUdApdgJ2EcVp|1($_YxQz6a$$gkqE$g*gF{5VVV1gp+cHwNR=I4dgq zsXv%FSLCf0kAvUN&_5}XDD#U`mlnBSS?9aLe->qx{oJ20x8f-G)7;rIid`+Pfa-Fp zp!)n;mXgoX3b{G97vN`^Kd}BJS9>7!2c%$?OS5ZH^ok~GO^`Znz(VQNxcN( z?;j@T50jtkzw}R@Ncu0tJ!LJWC=;oe!k-NFtH;06&+&{7UWD7--EO}d9_;LG?;lk2 zAU+PPo0R#JdeW`p=+r(LfuWyM%`S3wud@z{5c0!qFX^`>+VhqHyQ`Grw@~Lk1)L8IIgCW?Q9&&Vw`=Sy!nME_GQg_OvWq z5f_=R-#>P&+|#JExl^q?A7Y9cG%Vst6(W1w40Ry)ba|R1gPaa)lXd6zPVedFZg*RE zx-!bE^h)Tcj0P%3U5VguoyQ$2SJ{=#hQTe&0wSW4Xo=dcsjS-S#OPp!XjeVJXyd!x zbnso8WH!U^mHiv17XhX7*ehMUuxeJlwplhm^A^m4*TQJcESP0)4ZryFnxM2yOn_~m zF)OyXd#i>sAOqkF_zMI}Q2fSwizz?~SBH_eo*<%tof^-8Sws?rEqHTj8kmN&0ylte zz%MsPL<6h7Hl_q5$EiH_8Ws9i%4)+x3DmAD6s zR<9YegsaObRDuKSY7@JXRdH)zc#2&$sDW`ul3U{LDtjI5hJlyUP4|>~zupAYu0=ig z-VPL3uX7v0+|zR`aa4Aw!?8_AW0(FNNgVtb3-rXd2y2KCOXB1tLfWxBTy$(TBXwg@ zYI;%V7$P!?L9NHfxvi=c)H;jK%IGv;5(LaW$LzYO@$^bGQ@ctNt4TKmys3D5ehR&v zkGP3d{H%;njm)Ut%e_B#YdcLSnBz3Ay~udBsSBQna1hW8Y|2T`f4SKXk$v-NaW zE44NSEUh`3(r4OpaIhb2-&h{d(Lh0j=3Ed%9nALqHDHCSN8qsJELq z1sry`=>}u9+Jc{uf%YMIs`VL#j9$!h!VeBmPM)OdIAKAMz*>S{>$rk zPR2#R2kSp9{S6IdhYo8c#YJM{N)Nj@Mdp#QvtNs3;ke@$wb0GtT;o{bv1h3<_ygHI z8(i9nO1wEF1q|wB66(a}P=!a2o?P&Pd+8icgs%MmXG!T_LPB*1otTDcqCW59Qd~xb zw#=fZ@{##bnulTaF&0hl+71397b>^GPP0N`iN*8UmV=^7-9^fhQvd9E>guv>fP}|e zhX)WmBcJi=AL~;x_=;4fl%{P!<1|RY4o9!pG5OT430_ZBt_o;k@SLoB=)P~Iz7qrd pfAGDO*MR--J3 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/PythonHome/Lib/ihooks.pyc b/PythonHome/Lib/ihooks.pyc deleted file mode 100644 index 875b068e900fbd3b5e779037190a82e5cfe81d2f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 20337 zcmb_kX>1+Wb-wc+xA#Pek|NIJZqAT(vNtYyDPy|R@pb6RnX$k}diU1Azqdx)!El{99QJ_Fjw12vM z-*;x_J<7C6*`_#`cV_N#?%B_|cU1oA_UfOXd1;LD#OjxvFb#b938Vd(_R1I*;#m z>D_iWx81dOxVas!jc#KA507@b2#&{(s?)f>~54&i$TfhK&il^g* zCVRTKc)EuGM&oKbQ9RvCn4`UVy03UT!DVD4+*CZ>$CX9<)OLUI^d{nJ?q-(ZEi4;1 zyVpH82S9IOqq*DoaCY)G5@V|3+{yNGH%|S`Nf?Ig`4jXJ5nl0<%Y z!A}>PiQn!vR$7sNx!G#@?eIe6H&cJPnQ3Dmf)eRfX&iQOizH3Cw5sFUQS_KGa7MmP&G4khEnyvH*x@6Ng+sl4* zg^;pW8pR7?JxVx#f9q=2I*G!#zQ~!vPNSGLY@P4M&2+InrN>wYme;?OI9hID*lPcf z{=!P9o;JH3zg7bf0H9XmQo3;?ir25-Poj3%Nt^Wq$kQO!!B5gKjoMh`l)r-aEx*&f zOf)Wri9a7j9iND6)>m4o2JE)yn;pYw1ccU8(xQjkJ~$S``h{f5Z#6-d>v6jfciaB6 z!KtJ=zv{;Z$@KE-6d?EGC`sdHJq1;wD^Yz#>ti$Cp%F;&OdstV(Eo;;ZC zOc$qp|77YXi`|u01IXuS4Igw6&BG+B8rTcKQWwwSexRZRfPP5p%@~bHkK#?&YW(PP z&@ksw@K6YjA*1>POh5uJ91_f7aORi~AyMgKw_zx#S~s9UBNj5E5yAB!MWY#mak}y9 zgFbN5y%fc9Q=(@wt--2Y;JgmH#F5P-Bs8KlY_`b4y0xhYjolXmQ+Q@D!c?`8RiYVe z_cA!z@B_@pU<)l$8UXweHppF?OtnPRWKLv|j%>RdJ*7 z@;d&{76gK7oDfoc8M;Sc_6Z9Rdlbv$FnWdM_MjnZYWMc|T>1_pt%R-Csxb;zZSVrC z_w}=;N&FU=(;60x3FVmhmm_F<{4H>xspCk@Niwf=teQ_QsR~<3w^|7N`o7H$1e1fR zbAH!Mlc=?TX~Y;A&sD(zA(det71=GDezG_J;X*r8GO0px+DTJGdQF=9m5EXBWY%E4 zRw;y&i$iaL2~7t9O{gazvy))89KMYh0%B3MZfO$?+Bi&Z2ayB_BsSx2AF2hs{3bOt z4;56jrF2JEV38Y9qnh(^*lMP$e%R_t9=d4WqH@MGkWlCeGuJuwGX!K-9@BSIYW+^w zj$k-|ehL_kn)RDJTy3u;DNvoR#8f9evvVnItxz~=uPKYLh?f_kM~Eg_(mKeCp}U>x ze6$#Xs?Z=IECcP(^z?K#5vvD!7LnGd)1|hXl*Iw1>LGP9RXLgaa%g}1c!6eu+DEE8 zYxeXi)MI90mH~YfPah^vRxeA@lQXe)h#=*RGMRB>{{o{pp`8cV#%YtJUGx9&Gg*S` zl+vNS9LAmH)%z}_1KCaT0losDO@dXpOND8Vqc*g!SSN$=zUdF7RdfOb^$V@&Qq*d4 z_?dJU%A;Y@tQ(7-5)Y<>cuGb~(oxjby<&&Q!%ls5-P7^)!{nTv?kKt!kB0FmLq!U| z(5-Z`yC!bjWEn-e4aKqAiL=j~n3+9!dPeP@e!ez)`q|*v3BASLvC~gIee%?a?$WdI$ zM^QxZVLit%!O5{ju;9tDMQ~731(88n6*#{Gstmhec9OWObEy0}#vuv9RnJ{@uBO0b zb`k-Kn^Bn(C9swR#;8t0Q%ME8QJKVLMKXrk^tn^b`Ey2jxJ|Z{TC>xHllUawC!E)L zb&j830)ew&{v`*uyf?W`!TW$j++;Em=6saaGH7RTo6naomwz{1vdzk-nsqDdQDAfP3ZIKpWt&w9k$eXzbe4I=e_`hbk<>C01(F_0n}3xo;MN*ED2l~pHDWy3dse9 z5l_CmtxH&PfE-EvQ^Axp=oYq2wl>_(W%r^(Q_7Cd-L}MkWOY!VqquliOh$ z+{8C}&0-^F2=?IxVqTZ9oAZXe(bD7yY8jVM1=niQ1hq{2;+Bl@+=<}m>Dd#(9@K-q zEGAg&XTd>x^QyMtd*K;ST_#w5VZAe(hG-~v;LIw?3Dy9O zZj^KmrLaF?%N(itVpP9CLxd1w+N@XNA2|Zc*rGuyCWAdD1bv>}x_z3|Xh62(m#1oKQ_i+TZc zjyfA2E6L(j8rqJmA>4yzJsZXX=Q_Omj&PtLf@ZN}Bht?%$j{I?6`>LuVByU)g+tr! z!UsVpcPZ*L8MUW~*=eQ^A+BT3J}gX0GjYaNxHJIa7c?+S5iMm zt#wt4!@{{mTSl`C$U3Ey>Y5^Zj0`o40ulw?q#Fn zFCK7fWoeg^1iI|5mE78ZyE@?F!z^bn9(HFiL@wE!PAY{Vj4W&B)YZ7clzOOd^*Ij^ zz@9eZx-^Ema71u{?6ua~6Vr_(RF<=EiWuD!nrP>ZdK2DuZ?`w(M&817q%a*`u@=g5 z%IP5q!2$f0NfDfH4?}PV8o$hr90GQVgYe=ykKszFLV85#)8EMH&93fqX~``C@1RSG z)B)0G&vbUX0ifkV)y2mh(s{)C**??@iMM0mltxY{kk~`cj3u-duwihJjc9AkVL1`U z-B=!m))w4}H^E&fHd&>QCTqA7I#5LK_EOo~2NV~sL9t#MQ9~})gf+$o$#+nQ_6x`s z^gGK&U@vR*v+ElT=8d#yqIL$&0VWMWKwzcyn@KHOcOYz#_?gdCd+PM@XHT7wuZ3n7 zQ_FQSFDiR42c?ILP0(-%<9`;HOoA(ofy;P_=!C35!g1Vyp6AMxDG1TppnLh|9$Kz~ z;8;3xwGb=H6duHnuv{upGHKWQ=}m^RRg;u`ib0}MZ_(2dX2=dk)VooWWHC~fy=0}3 zw`OOdyUAkTj}g9z%NC1;mc5%xLvZrwn+CN0!L2A{Z)>$iw_dA>3gS7*Mc}g$krr^U z-h8TUB+>y_8sZY84UNItl9qDk?x2e8^X=HXBW15_m zolKUqf)w|dDoAYaR0X;0U8*2`y;~Jztd#(tLy}rK?>Xe9mFAwq6v}MR?RU}5ZVuUK zrL>WXj&5^Hx4XGJ=rGWeNq&MtaSe@=rEz-+K^ajQtt^-`Q+9L}4gkz2&3=f~^}HF; z)$YprJQg0ruwHq3v1k6KWSpYu^V5t1+fjU8`RpPygM6u7~L!;hfQA$ zFCmJT-B;R`zDy@fVbc31%#9kI;ru$rMbjHI{c^2mi^vovAXHFv=@S^!=9MVfvLgQo zI{pr>1lLzz&>ybqmkOqa38@4bsD zW$_iKWh(f_rvDjC{q=V-eQ*SwZ){5T_{O`KQg&1;HfwTYvoi|+=DV4l@d!EFCa-np zmyn*mF&I9EA%4GrVF0!Kl4y}z3m%90f<3xcUgslSXM_?ciF!22L3%bc_z-VDh+-3_ ze*jJX09Woh<*@MY4Z*`~gp6Xn+g^ssYP?g39>hR@^j<(jEhLBaA&m3K z8vw+3Q7EGO*&`X;3fV!JLb#Riv*=%lMP`C~(b7CWl0^nN*vV(_jCvA(EfKo@0`d&s z!dN*asrzzj3QQu_G8ot3NLqkVau=R@-f%|9qUWpAjjRW@ZAx0$YIZ*Rvu_}Vf zdKyr7Ubl#p7NeoE{q{^KH!^JGf!4RtFY|Xsy-@@Y`?efD1oxn?C0>+2-n!*s{@^>D z7?-Q(#*Tl5JJQ-nyw2uux*HEwzKdROVPwb*HV>RobIbDy%X~$mb}c%x2yGcLa8LgT z+gG-LZH9Wagq{DQ0EQFfmloYqMFtG`fss*`>0{G??Sufixl7$_n)q4R6LxSiE4kX+lC=4OQ7g)-3fp!2vp39ESFN%E6tQA2<%YFl+VDm-8{dTGFhw_h)U^~WSL+bNWku? zVpcnhVm>SLr^wVY^du)|vrhSnYuN)y-8KSe?OAtYi+MZscy*b3zlw{e{4~r$Wae)t zn+pWy5c0wEF(TYM59{bq9>)^f`E`uQIE=!~EgT;+Zyuy{`3_oI-YZjELpq};w%ThWTri6@{hQ(U7npAI6L&M>6ytnyVe7R3MSAzbV0Wq zWwY^*apj&OHBo*EEt}6r+1&DcZ2XhAn~&a=t*>7>YGqrUL^(!AW+KBs_svEm^=<|d*h{ueaO(V9<6tE-8hL8Tz0Id}2o`kZT#n9bT1 zx!I@Jx7#2$YrzE#tFgrUSi7CY6pJG)rcv~nnmc)m>#bL(#Nof9g*oJ<-N>}^Y7$v> z@;;+1PO269cnqO_q4Fe{INJMeOnl%cY?_V~eTT0}@-NJ;>7B7r(4cmQUxikFfdi7dvik*j*h~ zig?7WRoq%NZ=om-G`c$C_SqiH>OJ|piW0{a?agd+SMdwLHP`H!i+_l?$yQU<-oZX> z9e8+p78kS3vkH@Dq&%9yn=`smHygDMu_mFG#gm=$`HUwt6fK%*rNs-*qL?HJ`a=J^ za4YkNEyV6+Yy>GZOf3Jr(rPjP9Nf)5%nt`8vCJ>uNV*lA zPA2U@-Bu-_+uYiyTifogZrAM&w>IY1cDk$huvbVm4ZHYHsW0QNunfd{x3OTaKT^f88qeC(tm;Ix3&#Pp|vcEl~Ar8Y9xcDc@FHNf^Q)Wp3Wd}OS# zRds7PC{u-7<8BpFjFx-c(jGVP?3vE{xzSAX zff4p<;=LMruhMjX?_JgH!&v@n*yr%vS#+J%X`DWTlK7zdOqa(_b%HBrBAoinYymVu zLhe2a4}HCgc-uZYL)aWaN0|xo-y}KB?3UDn&s(VniJ#QS2l#B7g>()hKTFYpm2tq* zY)=%~SwwQWp2Rp|t!7z1Sz;!cRCJhW9%V>s0f?KQM`Ah>o1m0x15SS2ot*w|7P5I# zNH6g=WI?g~b-^jWS z;0?t$Sm12DYlLYi#TYz-JEEqFZ345{lL6ik{^CO{`)~>y$`<}&H(B9t76-%3Vjme#b}%3&dnO5i z;d!J&PO>xASwOrlNbcWHEskbkV->yasF#lqdYVY9Hld{FS5h1bE`-h+@PsoDB}q@0 zF*mPc1cWRL$A6Hn zIoclYu}zqcqdrf*NRQ=GDdN3M6`g||W;)eV*KMu%Z-QZ_a3L@?ma*13^fX-9%Voy{Ef&CFHgS8rx5 z)J}BeA*|*TO3!gB_R;j4AeW8d3cmG9sb>wb#ZJwer=%;>7wA#(ZZa=>z}yz|l50rc zGA^w%LLr#?O{vWfi_ae zF^p?Rr+0*D6U=ZDn=c_sD75s`8TkPnBq*-}9s6)&{ENLIFauZsNO`zVf3c~Nw*bA5 zmp_fSTY$*E?0LD5qfwRQ7LdSb^b~Hbq`GJW1&fp(Xa;r#S0?vSyW+Mc&l8m;qz!Nj zcNF!CUYRr?>44`(;Nh%`Rwlj{=XRx_i^t9e(w zGo*{b@tsDPLMX@+nne?+l_4T{1#h;jgeqwK3Q^DtZ+qlo&$M7TEgi@*{40mWD4*b;!VgAiw<6LvgX zhqs7Z;3L@CI&2l#u0XZe6`($NEZ4Wjg@`wip2s()_GL9bfz1+0(~1M?6nn0J0GGHR zMun6|2^Nq(XO0d}AR8clo}__9okP}7=^Wz}#BvC%@SMTkfJ;s>3Y&$wK+t3&7#sRTQ`JJsGlJ{E%DUBfiTQaw!u@OjPcv^fkMed;N zIw#0ks583%v%aCf*&Esf9UVc;hXf*gSAeA$9FXj{BPLmc9&}H6<3z9NwM9bp}1b zt3Fra7>`4pBKpSD{Wt=C6#bFpL;tU_zs(I+i@)T-MT9h>-2_yv(HS1ZcAx+ ziDSZ$7AD{=hMA96yKoKC?(z|_X(7xHqTADwkzD!@9ZU}Oc@y|jgd2TGIAN0;$5rQ( zZfhk)x=B$|^6*>tm+#z|;*nN5C(HQH4)DsU`1{FdRYL?smQvyY|KoyobOxV4Vl^Vj ztiJYFJADFVuA}7p3+zUTTfT6fPN?cI#j2O_9G{_X;aExV2AY1AV*NNO&fDQpphqFn zV`cswz$aCevJ6zIio0>d-n?V3d_SV}Jtao)W2lY7r$TS!Ipt=KV6*{TQU?Ek3gins zO7Xm(6{upWPjfjT7-jG|1WGjs%Dy|`ns<=?(jH7hG6NZmKc#G(vJD6&rxebme7GZDE_`Qgd)>5^Nu#`hGs=Kh#-RmNcoWDN3uh8Hxv8{ zO0m24OA;#FgUK`!S$p{Ux>$ictgj}eeW~~*IhM__4~3hlIZL#B%AgtDe+jqpd?jE_ z^{34Uei<*sa~G8y`XamGvSLGJ{yDt;J5v1~wgc_PKv(3aLBk<$0)OElJM4|*)5x<`$^>6QkKor?$QS!6 zYa#~MZ^R&yh4|o6*1pE#w^4`=ZPH;A68s_>{}V|-zl+~4Rw#IG3}Q8|0A-ISC0r-I zDNTiG{T^Elo!&6|WS`3~bYlG6m{ z;&(Vce$PmBC?zxE z&bMattrG(Tihrdhe}D?Gi>QDs42&WiVH!SnTw(Sv-e1u2L!#yV?kq^Qiu8Zkbx*Ja zT}5?%BZmD(Q2j-=B+}2)NinSpqGDKVPeZ|p3+UoP)DQ!GPVN+&n!JKftSNjC)ZrPS zDY}6{zE2+&6%L`j2f4m*kQL6&m}km}A)vC5Cmei(H5ygn5jw(?$8RoklDJ5nJg1b5XqbN3^7DfAiNiDVWhROq=kQuaL{2d3?2B99A zFn}r4UwFGE^ddtPB1w~s=o)Cq@+i<_KnZjoJkJjcf54o6K?m43$kDa3H;YG*rHu?> zE>!zLOQPSpYkzCs9UMt=n+=og+tUsO-$EgQvM;`hG({jSCTE5W7t8XHG}caA5zJp$ zZslvJNtG?jq!7=WVDeQonE+z4FD&Ui?3Y>Dj<|LkUYb1K%G!rnhy`9@?F|+*Ndc9j zNwA=O6}P= z6!1}zXHjwxb;(P{#RF)aTI{C(H6_b@L~+20^#&@0!CdbRHH*62ZcCQ8?=5D-b+FT2 z#35&NrM+IAfBC}|9K$8-0%o$=dLYS@!Jn|GqUcSe+J>{K9cN=#SF$dm3h5)b`G0Z1 z8MQ4OxvG`{VOu-Wd=G11XK@<~5n5Yo+j&d<957_H!y!|wO|#GzK$$fz)i%&5O-e@y zt;QeU<}G(ZT-**^_&R diff --git a/PythonHome/Lib/imaplib.py b/PythonHome/Lib/imaplib.py new file mode 100644 index 0000000000..10ff340ef9 --- /dev/null +++ b/PythonHome/Lib/imaplib.py @@ -0,0 +1,1535 @@ +"""IMAP4 client. + +Based on RFC 2060. + +Public class: IMAP4 +Public variable: Debug +Public functions: Internaldate2tuple + Int2AP + ParseFlags + Time2Internaldate +""" + +# Author: Piers Lauder December 1997. +# +# Authentication code contributed by Donn Cave June 1998. +# String method conversion by ESR, February 2001. +# GET/SETACL contributed by Anthony Baxter April 2001. +# IMAP4_SSL contributed by Tino Lange March 2002. +# GET/SETQUOTA contributed by Andreas Zeidler June 2002. +# PROXYAUTH contributed by Rick Holbert November 2002. +# GET/SETANNOTATION contributed by Tomas Lindroos 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 + +# Maximal line length when calling readline(). This is to prevent +# reading arbitrary length lines. RFC 3501 and 2060 (IMAP 4rev1) +# don't specify a line length. RFC 2683 however suggests limiting client +# command lines to 1000 octets and server command lines to 8000 octets. +# We have selected 10000 for some extra margin and since that is supposedly +# also what UW and Panda IMAP does. +_MAXLINE = 10000 + + +# 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.*))?') +Flags = re.compile(r'.*FLAGS \((?P[^\)]*)\)') +InternalDate = re.compile(r'.*INTERNALDATE "' + r'(?P[ 0123][0-9])-(?P[A-Z][a-z][a-z])-(?P[0-9][0-9][0-9][0-9])' + r' (?P[0-9][0-9]):(?P[0-9][0-9]):(?P[0-9][0-9])' + r' (?P[-+])(?P[0-9][0-9])(?P[0-9][0-9])' + r'"') +Literal = re.compile(r'.*{(?P\d+)}$') +MapCRLF = re.compile(r'\r\n|\r|\n') +Response_code = re.compile(r'\[(?P[A-Z-]+)( (?P[^\]]*))?\]') +Untagged_response = re.compile(r'\* (?P[A-Z-]+)( (?P.*))?') +Untagged_status = re.compile(r'\* (?P\d+) (?P[A-Z-]+)( (?P.*))?') + + + +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 .error(""). + IMAP4 server errors raise .abort(""), + which is a sub-class of 'error'. Mailbox status changes + from READ-WRITE to READ-ONLY raise the exception class + .readonly(""), 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' + + self.tagpre + + r'\d+) (?P[A-Z]+) (?P.*)') + + # 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.""" + line = self.file.readline(_MAXLINE + 1) + if len(line) > _MAXLINE: + raise self.error("got more than %d bytes" % _MAXLINE) + return line + + + 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 = .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]) = .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]) = .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]) = .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 .capabilities in the + form AUTH=. + + '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]) = .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]) = .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]) = .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]) = .copy(message_set, new_mailbox) + """ + return self._simple_command('COPY', message_set, new_mailbox) + + + def create(self, mailbox): + """Create new mailbox. + + (typ, [data]) = .create(mailbox) + """ + return self._simple_command('CREATE', mailbox) + + + def delete(self, mailbox): + """Delete old mailbox. + + (typ, [data]) = .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]) = .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]) = .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, ...]) = .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]) = .getacl(mailbox) + """ + typ, dat = self._simple_command('GETACL', mailbox) + return self._untagged_response(typ, dat, 'ACL') + + + def getannotation(self, mailbox, entry, attribute): + """(typ, [data]) = .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]) = .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]]) = .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]) = .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]) = .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]) = .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]) = .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, ...]) = .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]) = .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, ...]) = .namespace() + """ + name = 'NAMESPACE' + typ, dat = self._simple_command(name) + return self._untagged_response(typ, dat, name) + + + def noop(self): + """Send NOOP command. + + (typ, [data]) = .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, ...]) = .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]) = .proxyauth(user) + """ + + name = 'PROXYAUTH' + return self._simple_command('PROXYAUTH', user) + + + def rename(self, oldmailbox, newmailbox): + """Rename old mailbox name to new. + + (typ, [data]) = .rename(oldmailbox, newmailbox) + """ + return self._simple_command('RENAME', oldmailbox, newmailbox) + + + def search(self, charset, *criteria): + """Search mailbox for matching messages. + + (typ, [data]) = .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]) = .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 .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]) = .setacl(mailbox, who, what) + """ + return self._simple_command('SETACL', mailbox, who, what) + + + def setannotation(self, *args): + """(typ, [data]) = .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]) = .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]) = .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]) = .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]) = .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]) = .subscribe(mailbox) + """ + return self._simple_command('SUBSCRIBE', mailbox) + + + def thread(self, threading_algorithm, charset, *search_criteria): + """IMAPrev1 extension THREAD command. + + (type, [data]) = .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]) = .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]) = .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]) = .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 + + # If we've seen a BYE at this point, the socket will be + # closed, so report the BYE now. + + self._check_bye() + + # 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 = .socket() + """ + return self.sock + + + def ssl(self): + """Return SSLObject instance used to communicate with the IMAP4 server. + + ssl = ssl.wrap_socket(.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/PythonHome/Lib/imaplib.pyc b/PythonHome/Lib/imaplib.pyc deleted file mode 100644 index 3e5bae5dd7bae1be39b52c12b0d37297381041a7..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 43871 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 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/PythonHome/Lib/imghdr.pyc b/PythonHome/Lib/imghdr.pyc deleted file mode 100644 index 7c747835272595eb73c7f62421c2d3438b5aeddc..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4598 zcmcgvTXP)66+W|<*^9N7EfI_jL_@fErHU1l05&e-B-rv=25nTcR7rqc%Ir?>s#m)+ z>+X@IrKBf#NfmkIFXTN%6_qM}Me@ks$PY-qb7p5H3Sm=%u+p6AKHYuh^mi_OI{%+q z^`D!6X?1Aw%i;Y;JoXO`QAqR=s6#!6K5{6$NMVjXLpx7B3>7HM(`RTDNfoH?k}A@t z4mn{#xTTC+O1VYhmNRZS<+{SHWZX*1EeW@pajPk}EZlP$_gu=Y2zMsq&ZOL`aBCU2 zmU7Pt_k6}ZpK@n}JDYK5Q*KST7c%aJlzU#d7c=g~lshZjISMaGW1g{U)#n(^rKCi69xl*Pfe!JHPsw+VigZ{cv(L2kXrDGWp$>-3 zKjecjH<1GYTVS{9d8pomf<&gRJ-q4_5ZP-pj#N@bPg@AyXMxq7-X;`IplOoH*0xPY~AhxQ`=*bK=06-$z5!y}4Xb<8}kmxuPwURDSgLcZ+ z@ggC17Omw6@9XvhJ?!m-W_dLBd6adx9=9CV$vZR7EdJ(l{J!ASKwW1h=hAscY{3GHZ!%@_w7T%o3RVb)(s+Rj*XVA4XB{44ASQ_Qh>1Utzfd zDSYF*{%}$=mv&vzEOUkuue}1&fcfiJZ(R3+DD!p1c{nDf#mJuWs?2QwS{RPOzyX#(k6q_Vy<4|ksWEhMVHRm^thmRu6 z(M-iuD{rKG=LqmB)mj==?P0SnQ+VA#MX87W(3CYrVbmVJ4*{0lpK^1~>&F2$wb=gy zhiCD*jmAkFdL|fu8wmebm~@Q8Z{Iu(hu#DS|5Z#rD+s;e2Uz{HgCNeZaT0`)K6oMq zzkBO63`Rc%2BYDFr(tk1(|+p=n1(JN_pQCiGl5MMS7rmH*>5EueE9eN7m{^&^enME zO*1SY%*0Y|l0-QY__@s^uYe$Cxp+&XSc*3fhKELXs9$R8-5{h1ZYvpy$ zqFXB~i*la59ICF4lqZpQkVRhVas0vKN^!tj^prBT&#+O^vf43?zRh?fE#e9acP^YBaJ3kuN0xv3i5ngDK&E;V2U`<`4^ z{>A_|?oH$s=m@tTm+dfFEY}>k0q#!c`+{`KBy+r1A2YYr$Zb#x!YkyufCN^~mOb*6@wu%3H zUMQ@1G*FM#K)&t&DPwcWje?=_?=Xi$mU~Z0Nuti@m}~jSWjC6ECETK zxiWZpT+M1uv;GXGiI&^jVcgl?p0p7F+uJ?^A^Y&zo&9;9%dQuUa03l}PPYCfCVZ9i z7nr=n|^v%Lx8<|^*YbD+gq V`V=PbtnZ?qJE`*>)G( z8|xGJG(L?l;RERZWJU}1LLA81Y?AZO`S>OLvC#Xr@o_Dq_6zX)1jF8d$%!^$1?2%1 zf;KS;=?fMEUdcQ31&bY?uk~lx=_bt6G~25y<773Edc?CrZ%5568CChXP;y|Zk-QsC zBK;HJn=FJM3v@A_Vc4%Qj_3$C3OWhMUM1(lI1%(&P>J1uck%Z)q{$k&kd6>i$Wfhy z^!&qPI_}VPnGfwE#2L!FbQJO)95(hJQU`*2Ju;t22*Kj#SPkOXdylb^&$2Uou1(ipR^E0~4)x=)GbhSpU z(jB!b%gRZsoPhoOzEAEP{ti(?Oze|g;dSMKj#jPk*=|i2EwA@iKR;cmoV8&^B zfmYkGw!h8$=9TmDPWs-BjlB#LZN1jpTYrGqN)laamn2a=bqm-}j6xj`RKogPCwmcw zf<>_?=EbrIF&4z7AY(!~4j!JB6HL&dT~8`nXiDyzy?&M$z;PT9;=g?r`E&Ql-Bl{f|%uEW;&i_ zH&)7qsYx@Z%zt9oUe?H8f{z1&CcBI4?Tl0$}Wk)3=l)d6gweyojSs=p5IZ fs#Gykd>VtF{qsF=77v;b9{Fl>g57XFn7i-`7?52F diff --git a/PythonHome/Lib/imputil.py b/PythonHome/Lib/imputil.py new file mode 100644 index 0000000000..a5fa6ea4f7 --- /dev/null +++ b/PythonHome/Lib/imputil.py @@ -0,0 +1,725 @@ +""" +Import utilities + +Exported classes: + ImportManager Manage the import process + + Importer Base class for replacing standard import functions + BuiltinImporter Emulate the import mechanism for builtin and frozen modules + + DynLoadSuffixImporter +""" +from warnings import warnpy3k +warnpy3k("the imputil module has been removed in Python 3.0", stacklevel=2) +del warnpy3k + +# note: avoid importing non-builtin modules +import imp ### not available in Jython? +import sys +import __builtin__ + +# for the DirectoryImporter +import struct +import marshal + +__all__ = ["ImportManager","Importer","BuiltinImporter"] + +_StringType = type('') +_ModuleType = type(sys) ### doesn't work in Jython... + +class ImportManager: + "Manage the import process." + + def install(self, namespace=vars(__builtin__)): + "Install this ImportManager into the specified namespace." + + if isinstance(namespace, _ModuleType): + namespace = vars(namespace) + + # Note: we have no notion of "chaining" + + # Record the previous import hook, then install our own. + self.previous_importer = namespace['__import__'] + self.namespace = namespace + namespace['__import__'] = self._import_hook + + ### fix this + #namespace['reload'] = self._reload_hook + + def uninstall(self): + "Restore the previous import mechanism." + self.namespace['__import__'] = self.previous_importer + + def add_suffix(self, suffix, importFunc): + assert hasattr(importFunc, '__call__') + self.fs_imp.add_suffix(suffix, importFunc) + + ###################################################################### + # + # PRIVATE METHODS + # + + clsFilesystemImporter = None + + def __init__(self, fs_imp=None): + # we're definitely going to be importing something in the future, + # so let's just load the OS-related facilities. + if not _os_stat: + _os_bootstrap() + + # This is the Importer that we use for grabbing stuff from the + # filesystem. It defines one more method (import_from_dir) for our use. + if fs_imp is None: + cls = self.clsFilesystemImporter or _FilesystemImporter + fs_imp = cls() + self.fs_imp = fs_imp + + # Initialize the set of suffixes that we recognize and import. + # The default will import dynamic-load modules first, followed by + # .py files (or a .py file's cached bytecode) + for desc in imp.get_suffixes(): + if desc[2] == imp.C_EXTENSION: + self.add_suffix(desc[0], + DynLoadSuffixImporter(desc).import_file) + self.add_suffix('.py', py_suffix_importer) + + def _import_hook(self, fqname, globals=None, locals=None, fromlist=None): + """Python calls this hook to locate and import a module.""" + + parts = fqname.split('.') + + # determine the context of this import + parent = self._determine_import_context(globals) + + # if there is a parent, then its importer should manage this import + if parent: + module = parent.__importer__._do_import(parent, parts, fromlist) + if module: + return module + + # has the top module already been imported? + try: + top_module = sys.modules[parts[0]] + except KeyError: + + # look for the topmost module + top_module = self._import_top_module(parts[0]) + if not top_module: + # the topmost module wasn't found at all. + raise ImportError, 'No module named ' + fqname + + # fast-path simple imports + if len(parts) == 1: + if not fromlist: + return top_module + + if not top_module.__dict__.get('__ispkg__'): + # __ispkg__ isn't defined (the module was not imported by us), + # or it is zero. + # + # In the former case, there is no way that we could import + # sub-modules that occur in the fromlist (but we can't raise an + # error because it may just be names) because we don't know how + # to deal with packages that were imported by other systems. + # + # In the latter case (__ispkg__ == 0), there can't be any sub- + # modules present, so we can just return. + # + # In both cases, since len(parts) == 1, the top_module is also + # the "bottom" which is the defined return when a fromlist + # exists. + return top_module + + importer = top_module.__dict__.get('__importer__') + if importer: + return importer._finish_import(top_module, parts[1:], fromlist) + + # Grrr, some people "import os.path" or do "from os.path import ..." + if len(parts) == 2 and hasattr(top_module, parts[1]): + if fromlist: + return getattr(top_module, parts[1]) + else: + return top_module + + # If the importer does not exist, then we have to bail. A missing + # importer means that something else imported the module, and we have + # no knowledge of how to get sub-modules out of the thing. + raise ImportError, 'No module named ' + fqname + + def _determine_import_context(self, globals): + """Returns the context in which a module should be imported. + + The context could be a loaded (package) module and the imported module + will be looked for within that package. The context could also be None, + meaning there is no context -- the module should be looked for as a + "top-level" module. + """ + + if not globals or not globals.get('__importer__'): + # globals does not refer to one of our modules or packages. That + # implies there is no relative import context (as far as we are + # concerned), and it should just pick it off the standard path. + return None + + # The globals refer to a module or package of ours. It will define + # the context of the new import. Get the module/package fqname. + parent_fqname = globals['__name__'] + + # if a package is performing the import, then return itself (imports + # refer to pkg contents) + if globals['__ispkg__']: + parent = sys.modules[parent_fqname] + assert globals is parent.__dict__ + return parent + + i = parent_fqname.rfind('.') + + # a module outside of a package has no particular import context + if i == -1: + return None + + # if a module in a package is performing the import, then return the + # package (imports refer to siblings) + parent_fqname = parent_fqname[:i] + parent = sys.modules[parent_fqname] + assert parent.__name__ == parent_fqname + return parent + + def _import_top_module(self, name): + # scan sys.path looking for a location in the filesystem that contains + # the module, or an Importer object that can import the module. + for item in sys.path: + if isinstance(item, _StringType): + module = self.fs_imp.import_from_dir(item, name) + else: + module = item.import_top(name) + if module: + return module + return None + + def _reload_hook(self, module): + "Python calls this hook to reload a module." + + # reloading of a module may or may not be possible (depending on the + # importer), but at least we can validate that it's ours to reload + importer = module.__dict__.get('__importer__') + if not importer: + ### oops. now what... + pass + + # okay. it is using the imputil system, and we must delegate it, but + # we don't know what to do (yet) + ### we should blast the module dict and do another get_code(). need to + ### flesh this out and add proper docco... + raise SystemError, "reload not yet implemented" + + +class Importer: + "Base class for replacing standard import functions." + + def import_top(self, name): + "Import a top-level module." + return self._import_one(None, name, name) + + ###################################################################### + # + # PRIVATE METHODS + # + def _finish_import(self, top, parts, fromlist): + # if "a.b.c" was provided, then load the ".b.c" portion down from + # below the top-level module. + bottom = self._load_tail(top, parts) + + # if the form is "import a.b.c", then return "a" + if not fromlist: + # no fromlist: return the top of the import tree + return top + + # the top module was imported by self. + # + # this means that the bottom module was also imported by self (just + # now, or in the past and we fetched it from sys.modules). + # + # since we imported/handled the bottom module, this means that we can + # also handle its fromlist (and reliably use __ispkg__). + + # if the bottom node is a package, then (potentially) import some + # modules. + # + # note: if it is not a package, then "fromlist" refers to names in + # the bottom module rather than modules. + # note: for a mix of names and modules in the fromlist, we will + # import all modules and insert those into the namespace of + # the package module. Python will pick up all fromlist names + # from the bottom (package) module; some will be modules that + # we imported and stored in the namespace, others are expected + # to be present already. + if bottom.__ispkg__: + self._import_fromlist(bottom, fromlist) + + # if the form is "from a.b import c, d" then return "b" + return bottom + + def _import_one(self, parent, modname, fqname): + "Import a single module." + + # has the module already been imported? + try: + return sys.modules[fqname] + except KeyError: + pass + + # load the module's code, or fetch the module itself + result = self.get_code(parent, modname, fqname) + if result is None: + return None + + module = self._process_result(result, fqname) + + # insert the module into its parent + if parent: + setattr(parent, modname, module) + return module + + def _process_result(self, result, fqname): + ispkg, code, values = result + # did get_code() return an actual module? (rather than a code object) + is_module = isinstance(code, _ModuleType) + + # use the returned module, or create a new one to exec code into + if is_module: + module = code + else: + module = imp.new_module(fqname) + + ### record packages a bit differently?? + module.__importer__ = self + module.__ispkg__ = ispkg + + # insert additional values into the module (before executing the code) + module.__dict__.update(values) + + # the module is almost ready... make it visible + sys.modules[fqname] = module + + # execute the code within the module's namespace + if not is_module: + try: + exec code in module.__dict__ + except: + if fqname in sys.modules: + del sys.modules[fqname] + raise + + # fetch from sys.modules instead of returning module directly. + # also make module's __name__ agree with fqname, in case + # the "exec code in module.__dict__" played games on us. + module = sys.modules[fqname] + module.__name__ = fqname + return module + + def _load_tail(self, m, parts): + """Import the rest of the modules, down from the top-level module. + + Returns the last module in the dotted list of modules. + """ + for part in parts: + fqname = "%s.%s" % (m.__name__, part) + m = self._import_one(m, part, fqname) + if not m: + raise ImportError, "No module named " + fqname + return m + + def _import_fromlist(self, package, fromlist): + 'Import any sub-modules in the "from" list.' + + # if '*' is present in the fromlist, then look for the '__all__' + # variable to find additional items (modules) to import. + if '*' in fromlist: + fromlist = list(fromlist) + \ + list(package.__dict__.get('__all__', [])) + + for sub in fromlist: + # if the name is already present, then don't try to import it (it + # might not be a module!). + if sub != '*' and not hasattr(package, sub): + subname = "%s.%s" % (package.__name__, sub) + submod = self._import_one(package, sub, subname) + if not submod: + raise ImportError, "cannot import name " + subname + + def _do_import(self, parent, parts, fromlist): + """Attempt to import the module relative to parent. + + This method is used when the import context specifies that + imported the parent module. + """ + top_name = parts[0] + top_fqname = parent.__name__ + '.' + top_name + top_module = self._import_one(parent, top_name, top_fqname) + if not top_module: + # this importer and parent could not find the module (relatively) + return None + + return self._finish_import(top_module, parts[1:], fromlist) + + ###################################################################### + # + # METHODS TO OVERRIDE + # + def get_code(self, parent, modname, fqname): + """Find and retrieve the code for the given module. + + parent specifies a parent module to define a context for importing. It + may be None, indicating no particular context for the search. + + modname specifies a single module (not dotted) within the parent. + + fqname specifies the fully-qualified module name. This is a + (potentially) dotted name from the "root" of the module namespace + down to the modname. + If there is no parent, then modname==fqname. + + This method should return None, or a 3-tuple. + + * If the module was not found, then None should be returned. + + * The first item of the 2- or 3-tuple should be the integer 0 or 1, + specifying whether the module that was found is a package or not. + + * The second item is the code object for the module (it will be + executed within the new module's namespace). This item can also + be a fully-loaded module object (e.g. loaded from a shared lib). + + * The third item is a dictionary of name/value pairs that will be + inserted into new module before the code object is executed. This + is provided in case the module's code expects certain values (such + as where the module was found). When the second item is a module + object, then these names/values will be inserted *after* the module + has been loaded/initialized. + """ + raise RuntimeError, "get_code not implemented" + + +###################################################################### +# +# Some handy stuff for the Importers +# + +# byte-compiled file suffix character +_suffix_char = __debug__ and 'c' or 'o' + +# byte-compiled file suffix +_suffix = '.py' + _suffix_char + +def _compile(pathname, timestamp): + """Compile (and cache) a Python source file. + + The file specified by is compiled to a code object and + returned. + + Presuming the appropriate privileges exist, the bytecodes will be + saved back to the filesystem for future imports. The source file's + modification timestamp must be provided as a Long value. + """ + codestring = open(pathname, 'rU').read() + if codestring and codestring[-1] != '\n': + codestring = codestring + '\n' + code = __builtin__.compile(codestring, pathname, 'exec') + + # try to cache the compiled code + try: + f = open(pathname + _suffix_char, 'wb') + except IOError: + pass + else: + f.write('\0\0\0\0') + f.write(struct.pack('= t_py: + f = open(file, 'rb') + if f.read(4) == imp.get_magic(): + t = struct.unpack('>> import foo +# >>> foo +# +# +# ---- revamped import mechanism +# >>> import imputil +# >>> imputil._test_revamp() +# >>> import foo +# >>> foo +# +# +# +# from MAL: +# should BuiltinImporter exist in sys.path or hard-wired in ImportManager? +# need __path__ processing +# performance +# move chaining to a subclass [gjs: it's been nuked] +# deinstall should be possible +# query mechanism needed: is a specific Importer installed? +# py/pyc/pyo piping hooks to filter/process these files +# wish list: +# distutils importer hooked to list of standard Internet repositories +# module->file location mapper to speed FS-based imports +# relative imports +# keep chaining so that it can play nice with other import hooks +# +# from Gordon: +# push MAL's mapper into sys.path[0] as a cache (hard-coded for apps) +# +# from Guido: +# need to change sys.* references for rexec environs +# need hook for MAL's walk-me-up import strategy, or Tim's absolute strategy +# watch out for sys.modules[...] is None +# flag to force absolute imports? (speeds _determine_import_context and +# checking for a relative module) +# insert names of archives into sys.path (see quote below) +# note: reload does NOT blast module dict +# shift import mechanisms and policies around; provide for hooks, overrides +# (see quote below) +# add get_source stuff +# get_topcode and get_subcode +# CRLF handling in _compile +# race condition in _compile +# refactoring of os.py to deal with _os_bootstrap problem +# any special handling to do for importing a module with a SyntaxError? +# (e.g. clean up the traceback) +# implement "domain" for path-type functionality using pkg namespace +# (rather than FS-names like __path__) +# don't use the word "private"... maybe "internal" +# +# +# Guido's comments on sys.path caching: +# +# We could cache this in a dictionary: the ImportManager can have a +# cache dict mapping pathnames to importer objects, and a separate +# method for coming up with an importer given a pathname that's not yet +# in the cache. The method should do a stat and/or look at the +# extension to decide which importer class to use; you can register new +# importer classes by registering a suffix or a Boolean function, plus a +# class. If you register a new importer class, the cache is zapped. +# The cache is independent from sys.path (but maintained per +# ImportManager instance) so that rearrangements of sys.path do the +# right thing. If a path is dropped from sys.path the corresponding +# cache entry is simply no longer used. +# +# My/Guido's comments on factoring ImportManager and Importer: +# +# > However, we still have a tension occurring here: +# > +# > 1) implementing policy in ImportManager assists in single-point policy +# > changes for app/rexec situations +# > 2) implementing policy in Importer assists in package-private policy +# > changes for normal, operating conditions +# > +# > I'll see if I can sort out a way to do this. Maybe the Importer class will +# > implement the methods (which can be overridden to change policy) by +# > delegating to ImportManager. +# +# Maybe also think about what kind of policies an Importer would be +# likely to want to change. I have a feeling that a lot of the code +# there is actually not so much policy but a *necessity* to get things +# working given the calling conventions for the __import__ hook: whether +# to return the head or tail of a dotted name, or when to do the "finish +# fromlist" stuff. +# diff --git a/PythonHome/Lib/imputil.pyc b/PythonHome/Lib/imputil.pyc deleted file mode 100644 index 80e10c2c0d73b5eaaaec8b0f1be1257823177bca..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 15053 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 diff --git a/PythonHome/Lib/inspect.py b/PythonHome/Lib/inspect.py new file mode 100644 index 0000000000..933694394d --- /dev/null +++ b/PythonHome/Lib/inspect.py @@ -0,0 +1,1059 @@ +# -*- 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(), getcallargs() - 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 ' +__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 + +# 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, (type, types.ClassType)) + +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 help(isfunction) 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 iteration 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)) + +def isabstract(object): + """Return true if the object is an abstract base class (ABC).""" + return bool(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): + try: + value = getattr(object, key) + except AttributeError: + continue + 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, and where it was defined. + # Getting an obj from the __dict__ sometimes reveals more than + # using getattr. Static and class methods are dramatic examples. + # Furthermore, some objects may raise an Exception when fetched with + # getattr(). This is the case with some descriptors (bug #1785). + # Thus, we only use getattr() as a last resort. + homecls = None + for base in (cls,) + mro: + if name in base.__dict__: + obj = base.__dict__[name] + homecls = base + break + else: + obj = getattr(cls, name) + homecls = getattr(obj, "__objclass__", homecls) + + # Classify the object. + if isinstance(obj, staticmethod): + kind = "static method" + elif isinstance(obj, classmethod): + kind = "class method" + elif isinstance(obj, property): + kind = "property" + elif ismethoddescriptor(obj): + kind = "method" + elif isdatadescriptor(obj): + kind = "data" + else: + obj_via_getattr = getattr(cls, name) + if (ismethod(obj_via_getattr) or + ismethoddescriptor(obj_via_getattr)): + kind = "method" + else: + kind = "data" + obj = obj_via_getattr + + 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('{!r} is a built-in module'.format(object)) + if isclass(object): + object = sys.modules.get(object.__module__) + if hasattr(object, '__file__'): + return object.__file__ + raise TypeError('{!r} is a built-in class'.format(object)) + 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('{!r} is not a module, class, method, ' + 'function, traceback, frame, or code object'.format(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 filename that can be used to locate an object's source. + Return None if no way can be identified to get the source. + """ + filename = getfile(object) + if string.lower(filename[-4:]) in ('.pyc', '.pyo'): + filename = filename[:-4] + '.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 + # or it is in the linecache + if filename in linecache.cache: + 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 = getfile(object) + sourcefile = getsourcefile(object) + if not sourcefile and file[:1] + file[-1:] != '<>': + raise IOError('source code not available') + file = sourcefile if sourcefile else file + + 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)|(.*(? 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] = [] + if c not in 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('{!r} is not a code object'.format(co)) + + 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(co.co_code): + op = ord(co.co_code[step]) + step = step + 1 + if op >= dis.HAVE_ARGUMENT: + opname = dis.opname[op] + value = ord(co.co_code[step]) + ord(co.co_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('{!r} is not a Python function'.format(func)) + 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, arg in enumerate(args): + spec = strseq(arg, 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, ', ') + ')' + +def getcallargs(func, *positional, **named): + """Get the mapping of arguments to values. + + A dict is returned, with keys the function argument names (including the + names of the * and ** arguments, if any), and values the respective bound + values from 'positional' and 'named'.""" + args, varargs, varkw, defaults = getargspec(func) + f_name = func.__name__ + arg2value = {} + + # The following closures are basically because of tuple parameter unpacking. + assigned_tuple_params = [] + def assign(arg, value): + if isinstance(arg, str): + arg2value[arg] = value + else: + assigned_tuple_params.append(arg) + value = iter(value) + for i, subarg in enumerate(arg): + try: + subvalue = next(value) + except StopIteration: + raise ValueError('need more than %d %s to unpack' % + (i, 'values' if i > 1 else 'value')) + assign(subarg,subvalue) + try: + next(value) + except StopIteration: + pass + else: + raise ValueError('too many values to unpack') + def is_assigned(arg): + if isinstance(arg,str): + return arg in arg2value + return arg in assigned_tuple_params + if ismethod(func) and func.im_self is not None: + # implicit 'self' (or 'cls' for classmethods) argument + positional = (func.im_self,) + positional + num_pos = len(positional) + num_total = num_pos + len(named) + num_args = len(args) + num_defaults = len(defaults) if defaults else 0 + for arg, value in zip(args, positional): + assign(arg, value) + if varargs: + if num_pos > num_args: + assign(varargs, positional[-(num_pos-num_args):]) + else: + assign(varargs, ()) + elif 0 < num_args < num_pos: + raise TypeError('%s() takes %s %d %s (%d given)' % ( + f_name, 'at most' if defaults else 'exactly', num_args, + 'arguments' if num_args > 1 else 'argument', num_total)) + elif num_args == 0 and num_total: + if varkw: + if num_pos: + # XXX: We should use num_pos, but Python also uses num_total: + raise TypeError('%s() takes exactly 0 arguments ' + '(%d given)' % (f_name, num_total)) + else: + raise TypeError('%s() takes no arguments (%d given)' % + (f_name, num_total)) + for arg in args: + if isinstance(arg, str) and arg in named: + if is_assigned(arg): + raise TypeError("%s() got multiple values for keyword " + "argument '%s'" % (f_name, arg)) + else: + assign(arg, named.pop(arg)) + if defaults: # fill in any missing values with the defaults + for arg, value in zip(args[-num_defaults:], defaults): + if not is_assigned(arg): + assign(arg, value) + if varkw: + assign(varkw, named) + elif named: + unexpected = next(iter(named)) + if isinstance(unexpected, unicode): + unexpected = unexpected.encode(sys.getdefaultencoding(), 'replace') + raise TypeError("%s() got an unexpected keyword argument '%s'" % + (f_name, unexpected)) + unassigned = num_args - len([arg for arg in args if is_assigned(arg)]) + if unassigned: + num_required = num_args - num_defaults + raise TypeError('%s() takes %s %d %s (%d given)' % ( + f_name, 'at least' if defaults else 'exactly', num_required, + 'arguments' if num_required > 1 else 'argument', num_total)) + return arg2value + +# -------------------------------------------------- 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('{!r} is not a frame or traceback object'.format(frame)) + + 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/PythonHome/Lib/inspect.pyc b/PythonHome/Lib/inspect.pyc index d3162642a59a8d2643c580af6ab43506c32c79b2..ab0356b8d87d8293bbdde94bcaf53c57351b7eef 100644 GIT binary patch delta 4047 zcmbW3-%C?r7{_;}+ia0wdRCY;3$;Sq63w-&NVZxFZEF*>JhS|9a>Cl0=Nzq!Y_0|_ z=+`q7qUa{2n?QX7p^Pvhf{0e+MGd+rNw4~GQ5RkH{te%&_v*v<`#jJ0d3a~1^|xQ^ zr)6{99-U4n@0R-d)v(qrwZ+cb4hMZl0)Cg|)6_GXD!JuutxxiwQ^T?7q1b6zim-@T z5+Ly1>RLSllBv)p7+FK%!8{007VQ`E*~_9FW_zmGhJm>fBL=RB8!>RrIspU4^+{|r z_e-k;1AA2(#B|Hc=AfCfFVp=D!r`z%-l z{Y~#7tF+bi1{ot|-5W@BKL%L`zxD+OTA(IzX_4ZddVcYzJOfzOR&TvvVy)h*P`BxO zbC};mUkkPZbTgRd8&uZ16S`B>-oAjeos}Q!fV#y-k3SODDtY`T(JP-)4E*hhbSVls zrDenjZ3!h2j?ILeSOLE~RVZpK(lvuAR`hgY;8^b^ERzXEWR>BM2BfpI(JD;T>a{Re z+yOP063QZCmW5R8^F*Us2O>yInhbIN!IKa-HyDMunxP7Q)s7A|W5axK{t6_!V;C!Q zVz?jCW2Or)u)t+6-a`aQ9q|ZeHa~J1`tgt_^$?L|e^bw}I-iVv;yK8qKVv!ImxR*S o79h`o>*Ltn`*C9u0_o1J1mcu7({qShp|=Rf<}(>=nr#!g|3Xihx&QzG delta 1008 zcmbPsf@#wRrVXiF>;eo740n`dyvFv2E?2s-Ed`-Q}y&2nI=!wTL)7+xlI2njJK`)Qap zlh1fcPk!pL1&MFY$hw)u%NK6Yo@DQ795O)w}-DZ{eXt=4HHzllP6iw=#qD`8(5~0^1PHb|> zl*2$bNKCzja04(XCR@!s2-CM&Z`M>qpnaRY6waA^Zf+w?)#Rpm`{C@8`DbD5%_R$_ KAZ)Z=d>a5SBJ#cf diff --git a/PythonHome/Lib/io.py b/PythonHome/Lib/io.py new file mode 100644 index 0000000000..14384930c5 --- /dev/null +++ b/PythonHome/Lib/io.py @@ -0,0 +1,90 @@ +"""The io module provides the Python interfaces to stream handling. The +builtin open function is defined in this module. + +At the top of the I/O hierarchy is the abstract base class IOBase. It +defines the basic interface to a stream. Note, however, that there is no +separation between reading and writing to streams; implementations are +allowed to raise an 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. + +__author__ = ("Guido van Rossum , " + "Mike Verdone , " + "Mark Russell , " + "Antoine Pitrou , " + "Amaury Forgeot d'Arc , " + "Benjamin Peterson ") + +__all__ = ["BlockingIOError", "open", "IOBase", "RawIOBase", "FileIO", + "BytesIO", "StringIO", "BufferedIOBase", + "BufferedReader", "BufferedWriter", "BufferedRWPair", + "BufferedRandom", "TextIOBase", "TextIOWrapper", + "UnsupportedOperation", "SEEK_SET", "SEEK_CUR", "SEEK_END"] + + +import _io +import abc + +from _io import (DEFAULT_BUFFER_SIZE, BlockingIOError, UnsupportedOperation, + open, FileIO, BytesIO, StringIO, BufferedReader, + BufferedWriter, BufferedRWPair, BufferedRandom, + IncrementalNewlineDecoder, TextIOWrapper) + +OpenWrapper = _io.open # for compatibility with _pyio + +# for seek() +SEEK_SET = 0 +SEEK_CUR = 1 +SEEK_END = 2 + +# Declaring ABCs in C is tricky so we do it here. +# Method descriptions and default implementations are inherited from the C +# version however. +class IOBase(_io._IOBase): + __metaclass__ = abc.ABCMeta + __doc__ = _io._IOBase.__doc__ + +class RawIOBase(_io._RawIOBase, IOBase): + __doc__ = _io._RawIOBase.__doc__ + +class BufferedIOBase(_io._BufferedIOBase, IOBase): + __doc__ = _io._BufferedIOBase.__doc__ + +class TextIOBase(_io._TextIOBase, IOBase): + __doc__ = _io._TextIOBase.__doc__ + +RawIOBase.register(FileIO) + +for klass in (BytesIO, BufferedReader, BufferedWriter, BufferedRandom, + BufferedRWPair): + BufferedIOBase.register(klass) + +for klass in (StringIO, TextIOWrapper): + TextIOBase.register(klass) +del klass diff --git a/PythonHome/Lib/io.pyc b/PythonHome/Lib/io.pyc index 77d175989aaea6e5d63ca1a7d8ebe32275d9b9fa..9f5e35872fa70bc53529e589ffc334abaca265ef 100644 GIT binary patch delta 277 zcmaDYJymwYSuR6!1_p*ytC;l6l8n-%nDG1xJ+EMYzn}o;82{3eg3^*0m(--v^q7Fk ml8pR3kNn)!$#=M#$ 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 ' + +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/PythonHome/Lib/json/__init__.pyc b/PythonHome/Lib/json/__init__.pyc index 03736b742c99db33ce02dd285a41e203e6337741..6ef0af96e381b3f8319df073ed80a30904e52df3 100644 GIT binary patch delta 315 zcmaErGbL|>4j-f3W?jC^+=fmJ3=FAOG3l8l8Kp@v;rSJMUcvr;K>^M&{-q@ar6n;g zsY#{jF#(k&8Tol0`MIf+1x&>zt4bLF4G5E(%SoOAn 65535 and \ + 0xd800 <= uni <= 0xdbff and s[end:end + 2] == '\\u': + uni2 = _decode_uXXXX(s, end + 1) + if 0xdc00 <= uni2 <= 0xdfff: + uni = 0x10000 + (((uni - 0xd800) << 10) | (uni2 - 0xdc00)) + end += 6 + char = unichr(uni) + # 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 + 1 + 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 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/PythonHome/Lib/json/decoder.pyc b/PythonHome/Lib/json/decoder.pyc index 386e699722ffedfe583ea26a4b7d62da47e48170..dde6fe535d8a2c36b78df56180039ee996304a07 100644 GIT binary patch delta 731 zcmZpQo0YgBliARbfq@~_DkeR%B%?GbCOp4F&nwv9FDSq{#=o?rptK~$B{iuuJtm;C zBqKl1BR@BFvVfMzne delta 315 zcmbQ0*c7)RlbK(hfq}u7qj&=DXeGWoP_2R8A|GxX9iO)@aZ0ste6Se^g? diff --git a/PythonHome/Lib/json/encoder.py b/PythonHome/Lib/json/encoder.py new file mode 100644 index 0000000000..f5eeed75f0 --- /dev/null +++ b/PythonHome/Lib/json/encoder.py @@ -0,0 +1,448 @@ +"""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 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) + # Let the base class default method raise the TypeError + 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/PythonHome/Lib/json/encoder.pyc b/PythonHome/Lib/json/encoder.pyc index b6e09d0ae6e199fa5aa244983787a9238e7f8ab8..1a7268839ff4f73e83b39b37ba0297f03fa8ce76 100644 GIT binary patch delta 1035 zcmdm)^*c|9`7fP&m()HDl!4d`WgDc?L*so~#hU zNS>c3^DF%$LnkPT43(FYr*rckWpP$AwVG?Hu#lnkpo!Gx7Ts8K0tx8V&8+%=$cY+| TR#hW2a&4_QHYP{wL6Zsq;i_TB delta 453 zcmeyJw=+wK`7^M&{-q@ar6n;g osY#{jF#(k&8Tol0`MIf^1K8LZN!Kt<8 delta 75 zcmeAXS|+&RG$SMX<}-|?Ed25e3=GazF#(k&8Tole=9`Py*cs6UC$D1vh#_`{!vO## CI2E`6 diff --git a/PythonHome/Lib/json/tool.py b/PythonHome/Lib/json/tool.py new file mode 100644 index 0000000000..fc5d74923d --- /dev/null +++ b/PythonHome/Lib/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/PythonHome/Lib/json/tool.pyc b/PythonHome/Lib/json/tool.pyc deleted file mode 100644 index d2e584b19a534e27cca26aee0ceaa6ccb381e1fd..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1264 zcmaJ>OK%e~5FYQQuO+2G1raB#3PC_L5|2{^2!wh;sE7tA>O;#WHm%cLJM20@L~^0r zk@ye%2mTiaj_{2Wka~bsc6L0EZ$8i1iGM67-?v|PdNg|?d>`Pg9zrOh9Y{ecqFm4p zl&K!kPDCoE&j^S~*GSdqD5CNn>6ng*ghg6Jo#q@vofSlnTv23Jt>?yS>7C0Vp9It|f{2g=aJLy@n>O;C;l+ zx{qdg`~>wQIu0G@&R!3em?l$KjV6NZ*OQS^m_bHH^|TbsWK180yRMPlb|utmo|yfD)|NKFY+3WNkrTB64m??9VJx$Br%Ce z0AdV!AugX)hdMCHTI3c#CF}#v$DSrj&Qotr$>5Jfg^CN($*Uu zluy{J2U(eUS5}x4(T$2rv}MJMq{)k|aPp_-<}wVP%jZDhZv|Wi%gTdym=+9P;n;I2 zXkZe&IAb=H>mXbg8z0Qn&Zj&CM6+!NTDVbRKe`DA1yP-Y*4lewx_ex9k1tmX7mlHd%vkPqbp?XNd9ftwkQZk1 zV$=`|A{MJ+1-1ovmW5wLWSVkjnudReKq5_*>!s-y6WZc#Z8acf!F^@MQ<& diff --git a/PythonHome/Lib/keyword.py b/PythonHome/Lib/keyword.py new file mode 100644 index 0000000000..69794bda8c --- /dev/null +++ b/PythonHome/Lib/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/PythonHome/Lib/keyword.pyc b/PythonHome/Lib/keyword.pyc index ab1ea246459fb60d43d312f53139f915c5d15d89..82f48fe5554bb174b19526f28eac3be497bde3a7 100644 GIT binary patch delta 122 zcmZ24@L6C34>KeCW?trF%!W1$3=FAOG3l8l8Kp@v;rSJMUcvr;K>^M&{-q@ar6n;g dsY#{jF#(k&8Tol0`MIf+AF*8|L)RhpTmZrSD*XTe delta 54 vcmew?uwGyT4>Kd{W?trF%=}Ue3=GazF#(k&8Tole=95|2FJg$XapVF3iN_9W diff --git a/PythonHome/Lib/lib-tk/Canvas.py b/PythonHome/Lib/lib-tk/Canvas.py new file mode 100644 index 0000000000..34464ab979 --- /dev/null +++ b/PythonHome/Lib/lib-tk/Canvas.py @@ -0,0 +1,194 @@ +# This module exports classes for the various canvas item types + +# NOTE: This module was an experiment and is now obsolete. +# It's best to use the Tkinter.Canvas class directly. + +from warnings import warnpy3k +warnpy3k("the Canvas module has been removed in Python 3.0", stacklevel=2) +del warnpy3k + +from Tkinter import Canvas, _cnfmerge, _flatten + + +class CanvasItem: + def __init__(self, canvas, itemType, *args, **kw): + self.canvas = canvas + self.id = canvas._create(itemType, args, kw) + if not hasattr(canvas, 'items'): + canvas.items = {} + canvas.items[self.id] = self + def __str__(self): + return str(self.id) + def __repr__(self): + return '<%s, id=%d>' % (self.__class__.__name__, self.id) + def delete(self): + del self.canvas.items[self.id] + self.canvas.delete(self.id) + def __getitem__(self, key): + v = self.canvas.tk.split(self.canvas.tk.call( + self.canvas._w, 'itemconfigure', + self.id, '-' + key)) + return v[4] + cget = __getitem__ + def __setitem__(self, key, value): + self.canvas.itemconfig(self.id, {key: value}) + def keys(self): + if not hasattr(self, '_keys'): + self._keys = map(lambda x, tk=self.canvas.tk: + tk.splitlist(x)[0][1:], + self.canvas.tk.splitlist( + self.canvas._do( + 'itemconfigure', + (self.id,)))) + return self._keys + def has_key(self, key): + return key in self.keys() + def __contains__(self, key): + return key in self.keys() + def addtag(self, tag, option='withtag'): + self.canvas.addtag(tag, option, self.id) + def bbox(self): + x1, y1, x2, y2 = self.canvas.bbox(self.id) + return (x1, y1), (x2, y2) + def bind(self, sequence=None, command=None, add=None): + return self.canvas.tag_bind(self.id, sequence, command, add) + def unbind(self, sequence, funcid=None): + self.canvas.tag_unbind(self.id, sequence, funcid) + def config(self, cnf={}, **kw): + return self.canvas.itemconfig(self.id, _cnfmerge((cnf, kw))) + def coords(self, pts = ()): + flat = () + for x, y in pts: flat = flat + (x, y) + return self.canvas.coords(self.id, *flat) + def dchars(self, first, last=None): + self.canvas.dchars(self.id, first, last) + def dtag(self, ttd): + self.canvas.dtag(self.id, ttd) + def focus(self): + self.canvas.focus(self.id) + def gettags(self): + return self.canvas.gettags(self.id) + def icursor(self, index): + self.canvas.icursor(self.id, index) + def index(self, index): + return self.canvas.index(self.id, index) + def insert(self, beforethis, string): + self.canvas.insert(self.id, beforethis, string) + def lower(self, belowthis=None): + self.canvas.tag_lower(self.id, belowthis) + def move(self, xamount, yamount): + self.canvas.move(self.id, xamount, yamount) + def tkraise(self, abovethis=None): + self.canvas.tag_raise(self.id, abovethis) + raise_ = tkraise # BW compat + def scale(self, xorigin, yorigin, xscale, yscale): + self.canvas.scale(self.id, xorigin, yorigin, xscale, yscale) + def type(self): + return self.canvas.type(self.id) + +class Arc(CanvasItem): + def __init__(self, canvas, *args, **kw): + CanvasItem.__init__(self, canvas, 'arc', *args, **kw) + +class Bitmap(CanvasItem): + def __init__(self, canvas, *args, **kw): + CanvasItem.__init__(self, canvas, 'bitmap', *args, **kw) + +class ImageItem(CanvasItem): + def __init__(self, canvas, *args, **kw): + CanvasItem.__init__(self, canvas, 'image', *args, **kw) + +class Line(CanvasItem): + def __init__(self, canvas, *args, **kw): + CanvasItem.__init__(self, canvas, 'line', *args, **kw) + +class Oval(CanvasItem): + def __init__(self, canvas, *args, **kw): + CanvasItem.__init__(self, canvas, 'oval', *args, **kw) + +class Polygon(CanvasItem): + def __init__(self, canvas, *args, **kw): + CanvasItem.__init__(self, canvas, 'polygon', *args, **kw) + +class Rectangle(CanvasItem): + def __init__(self, canvas, *args, **kw): + CanvasItem.__init__(self, canvas, 'rectangle', *args, **kw) + +# XXX "Text" is taken by the Text widget... +class CanvasText(CanvasItem): + def __init__(self, canvas, *args, **kw): + CanvasItem.__init__(self, canvas, 'text', *args, **kw) + +class Window(CanvasItem): + def __init__(self, canvas, *args, **kw): + CanvasItem.__init__(self, canvas, 'window', *args, **kw) + +class Group: + def __init__(self, canvas, tag=None): + if not tag: + tag = 'Group%d' % id(self) + self.tag = self.id = tag + self.canvas = canvas + self.canvas.dtag(self.tag) + def str(self): + return self.tag + __str__ = str + def _do(self, cmd, *args): + return self.canvas._do(cmd, (self.tag,) + _flatten(args)) + def addtag_above(self, tagOrId): + self._do('addtag', 'above', tagOrId) + def addtag_all(self): + self._do('addtag', 'all') + def addtag_below(self, tagOrId): + self._do('addtag', 'below', tagOrId) + def addtag_closest(self, x, y, halo=None, start=None): + self._do('addtag', 'closest', x, y, halo, start) + def addtag_enclosed(self, x1, y1, x2, y2): + self._do('addtag', 'enclosed', x1, y1, x2, y2) + def addtag_overlapping(self, x1, y1, x2, y2): + self._do('addtag', 'overlapping', x1, y1, x2, y2) + def addtag_withtag(self, tagOrId): + self._do('addtag', 'withtag', tagOrId) + def bbox(self): + return self.canvas._getints(self._do('bbox')) + def bind(self, sequence=None, command=None, add=None): + return self.canvas.tag_bind(self.id, sequence, command, add) + def unbind(self, sequence, funcid=None): + self.canvas.tag_unbind(self.id, sequence, funcid) + def coords(self, *pts): + return self._do('coords', pts) + def dchars(self, first, last=None): + self._do('dchars', first, last) + def delete(self): + self._do('delete') + def dtag(self, tagToDelete=None): + self._do('dtag', tagToDelete) + def focus(self): + self._do('focus') + def gettags(self): + return self.canvas.tk.splitlist(self._do('gettags', self.tag)) + def icursor(self, index): + return self._do('icursor', index) + def index(self, index): + return self.canvas.tk.getint(self._do('index', index)) + def insert(self, beforeThis, string): + self._do('insert', beforeThis, string) + def config(self, cnf={}, **kw): + return self.canvas.itemconfigure(self.tag, _cnfmerge((cnf,kw))) + def lower(self, belowThis=None): + self._do('lower', belowThis) + def move(self, xAmount, yAmount): + self._do('move', xAmount, yAmount) + def tkraise(self, aboveThis=None): + self._do('raise', aboveThis) + lift = tkraise + def scale(self, xOrigin, yOrigin, xScale, yScale): + self._do('scale', xOrigin, yOrigin, xScale, yScale) + def select_adjust(self, index): + self.canvas._do('select', ('adjust', self.tag, index)) + def select_from(self, index): + self.canvas._do('select', ('from', self.tag, index)) + def select_to(self, index): + self.canvas._do('select', ('to', self.tag, index)) + def type(self): + return self._do('type') diff --git a/PythonHome/Lib/lib-tk/Canvas.pyc b/PythonHome/Lib/lib-tk/Canvas.pyc deleted file mode 100644 index cb32fd5d0f6d53ccae437f3459319cf0e9964779..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 14364 zcmcgz3vV1(6~41;J8|M9&ZAD!IK+9W2HNxmEsrFSxKWxuoOBX3>egi#?~LtDnm#y8M z*X}gIkgeU5*AALsudUse*X}aGu&v#n*X}mK0b6@8uN^YMAzS-YUc1KxBewQ%Uc1)> zM{MoUymp@no;JZ3OmHl(8aBbGxjB9U#6|zZzj2Uf(w)eb{B~<$<>mS01=h@kV-tSs zo}Y|0<6yB7j?JMs9fqy3cG!&Xg~3?V8oRNQ&c&^euHR;k~dCRd6|8 zrJw<1Dk&XA(W|#+nqhl3ls3JYhM%TkOJ3KfuBBn~F&$sVTgh3#3=LHaH9|=>DA$n! zR9ullAJxrU{Zu*&17xHIrS;1t^fVv^s75qhgEn?b4HSUNUFH$22egZBYhZfR{tlT( zup01*8t5304VwrCwO7jf#d@G+)E|&%hNXPa1ft~HAu5=Vo-%_L`FFG0*h2Yuu1N$DY2!4tqs^ObscH%mxQMj{k=c-!+1;rWCunhpSp z766A)0P$oOzgno6nTi?7XinJX`LoHhV^MJ7Y;aKrmy9T{-td#e^RjNY{ATERn?g%B z;CbzE0dPrgH{6`BXK=F%>xJxEj0q+J79Ft?Ws-Un^@`dBotR1xHo`RAAg%6GkamOs zDb_f{PMy%mCJ7ftFQbq{1fEV=5rSrT3}qS~0}nXn@I%fP<^e8b@;G{PoDEE-v=5qO zJ#NiJvy1I8Wv`x#cz2w3td>g<>AZ}HWT6qIV!d_0(GctPmQ*Q(DJCSAH6N~suzTeU zie}(>aG!+ZdB<>>P;CabJ>-lyGW6L32cr;i5{10;EL2RSqu(*FV5AqdB+z6Ka>R6c z+y&en#a-#Mo-1T;3ZtTtujBeE`De}O7BGyCYG2KK;Xkai13`V>QA%JldHge*ojJrv=M$khW z(D{?&P&D3%l2pA0Z!Wtu(sJ}riRT-Bb2{)Zo~1ZqF^<_B`G$*#NX zwJ;&3E*4Xc2$~bVXInZK5zbT0L0^N~hl z5=6&QP(J9v@vB}3R#^RvQAUIJg8jMR9s7 z`e*qiy?Uu!FP?{hmyk05e$uJ4DJC`|WRIfI)sKwws(~9{4R$A90HfY?)Cv?Z9+z=0~AyWwTvN3|0<=C1JiNGY-YjTM&wmpso5Ba2gXU0A zY=)SF`kdd+FiUS}FEVS-MD0WuCs;YA<)B{1%ikhYas|ViZmyj$ddOIeH6Hr`NcY%V{u8oKmH51ntGs-AOAeH0is%?^O zgP&DU4x)NB6gzrEL1J#qu)c$<+8mJA@jiL6oDdJwW)(#|QGKzU#Mu^z!c3mdBX#AF@NJ^8NXQM-7Q8e^9F_}VJ5^Ys zP#JOb-_zktj9tSVmWO;08^WkHTMjEdv3O&4vI^KRDI~#;G{eeE9m>LL z+>U0Wma>|a+2XRiA%=^+5?(IH^=-U*i|u7xZ`vc$5>gxnsU>XCFHhm+cRMJu*?kN( zE@uv^v!Vj;8DtuCw!I#?gI;6-y>VTa|$W(|k z%fh)V&LDYP76{ZFEl7qOw@292>**H!IuBpOU_Z9oBO1!2uDRQF-8_ngQYo@$7hBc6 zFS}KKAt`#T;g!r7bx6AiI_&PA=D){%m-SM`^f_f1j%@(R?B{*?XR*A-Xr#gaKq|QI;o;nzy1> zxIGlHwFX-2Jwr3LPg}O6Sx6#FMTV~9>~Z@TiqTr{8M z)X=a$;`|!+N1R^+{s`&gb^IdiUonjKYuF#rehvF0)Gr@*Fw~FWKcwM13Vj7Rz5>vg zKgx*z0|P#ukPkd+2>7E?gZ~Kl%l92MMEg;xk$(jIHS&*uzefHM@Yl#c0{$BLN5Eer z|3~Fh0tEjx;13}h{71}Rga7#G0F@g2KW@U~riPfm2LDknA9vKo_<;bsaFQP*uyBf> zez0(w-vx|;+&pAa#l-|tat#?4;R(JuaI%OS&c{Y@N(z^Y8-3VhdRV6;$F&x)W|w1Y z1makbfVu8AW&NITCJ@D*4Rp~iKK41(>dO5JN}WStt>fL!zGl6pH&^N(B4sgs9GN2g zJJ>mI<8o5EMi|7`*#`5LD=kTBH!jPy$ynEqkh0~TY;8!Pm@w;4Bh$9B$d3?&kB4|% zE>XzCg;T6PJgwb+h9zN!bsbV<4^(dk?jBYnX|^6O6!l}IB1Y?!699n1ukz&=WkS;kIz~RyL_O)^+v?+sW8sYLp>Q8WOAyNxWY+WF7%dIpj zL~y2tRlvt0BI*Tn8&jstVir-O@e#yXJfv&0l*yr40TkuvZk01bDHRsE5^*0Fu+h|* zXw|~i7z#zMI5_j;pMll9@x^*0PC^{`3uB^Lid2|qSh|Evjxgr@Ml7a)Z@Sv$A_OU; zIvKH9LqA20C3njm*a=~X&#?=^nmu6H(|wT{Lx=9m$jb3fmy!Xu4g3sMJwwisgHynE z!(Uk7vF}>+ZyNl84){VFpA_(K(yZMtLq-AXW-Pj35?R#z(*iK^z{DXfHhmO@jvEyp z3P*qm3BOrzPEOg>QPQIIn{BW>Qr`vGpr>uFyJP6$(;9!2EtIeoep2!{w8SptRp2 zZHfrmOaaOUiQwD6TchcGjGV&Fe2iqD0m@c_l?ar`;>`M%*NKG#Usq@O=T+iZHnno3 z#NQ)XYE~&~ozcRzd4ZW+NgIfBQp6wDXg;Us1a7WPj||*`-+hB<_+Ez_IrdiHtFCu5 z5GnVMNR}a*FjEfk$piXLJYFD*Z>u%$LP;a9w-C;B-{x~jPqt`E{1cJ|#g0)dZG-nV z`(?}s-qrO!rFGW(?s?weY*`N91w8p@q#{0xaf0lek_JX7xi z%-;%tXiZE!zY(oeH$;a7jeuCzQucN4=2szQ-2(PO3@GQEMh|<8YlRIr_HG@ z@9*S0ZI$k+|BJwPlEBAopKA#!C{@xMyg2l9QoL<9`>h(w8u? zJ+TTNT&Pv(3f@k!Q>ZVP?gpoOzWpDh%or!f&)`Dh_!`Fbc**UY%XwAf`1Ek@60;R% zJkWGMWcEX551Bn;#*IKBYTpUibFuY=s6G90cj%t}uMy3p8o2+2PkhRZn~jae@e{oB z1El0KvH@oZaeRs3OSFDp9sA!w!Wr_r7)B*M)nv|2V zQ1+BP@(5gbi#_lN@H9LCd{vVrh{J*yyQ{0JtLv|;D)_zMeRcfZIHj9!4f}m8_X~i= zUr|PM#8`u|T+xXlWg4UdS}3YMCf%fyfQlCBHAZxcOp~UHbemohT@!tKvPOEHi4&Z) zNq1<`pz0Nwb<&$;ai>dqgN6n=dNi~|rc1-?2AypDO{QPVY|vTnpJIJ7U~jT9RlwCv z8V|M*fc*pCKmqd%KCICW&^Rroxv6Gm_S>)g_3ryN*cVAv*ka~cl~$AYZr)yv-7Lkv-m;^|n@Tt$J(I-j6Ld z0r7a9E_XzKhe9-=#&Ds-H+HRVexfv5W`n@N$F`T#L0NA&wPGOUbJ?(`1!-!JV&=VmH`;Y$R{P$}g;*89z#LBX^I56f}0mua?LL zR4;@BL0fn+mL^#yNAZQ{1Q)CP#vsg;m!7>pO0$PmRaOJ>j)61TR5ay@^QMxUC;T?YHhT5}xR!umMwv(9(;ntDrh)GikPHu2k40qv+h zr5x$&b-?oMh~^A4cT^i?G-9Lw$%p7|NbX@dEU1uoSO*%%1rmvOs-G<{^(teMO^(XK zMC_~FzO^IR8v>5_at})!Z>g43Q~ zM4NNNqs3pKzEQvdJ^Ead!KoZMhM(EYgkP50POZ@qcc=T|HT&+fOFu7*{rTN+p15#g zOc5eV5e=O!QWK(e!wkmOqJ*o0Z9UZ1 zmsP~YFJs|7)4Z!P8N+%lf&RWboj%YGXu@>MQA|IL;GW+?3N1#3eD(c4?XCNuj0CzFJv7k})htM+@|VpVTdKk4K1m51@;{d#clD1$VYOTRpXn6!ZbRfPVsyd1~7L diff --git a/PythonHome/Lib/lib-tk/FileDialog.py b/PythonHome/Lib/lib-tk/FileDialog.py new file mode 100644 index 0000000000..06ce2b9229 --- /dev/null +++ b/PythonHome/Lib/lib-tk/FileDialog.py @@ -0,0 +1,274 @@ +"""File selection dialog classes. + +Classes: + +- FileDialog +- LoadFileDialog +- SaveFileDialog + +""" + +from Tkinter import * +from Dialog import Dialog + +import os +import fnmatch + + +dialogstates = {} + + +class FileDialog: + + """Standard file selection dialog -- no checks on selected file. + + Usage: + + d = FileDialog(master) + fname = d.go(dir_or_file, pattern, default, key) + if fname is None: ...canceled... + else: ...open file... + + All arguments to go() are optional. + + The 'key' argument specifies a key in the global dictionary + 'dialogstates', which keeps track of the values for the directory + and pattern arguments, overriding the values passed in (it does + not keep track of the default argument!). If no key is specified, + the dialog keeps no memory of previous state. Note that memory is + kept even when the dialog is canceled. (All this emulates the + behavior of the Macintosh file selection dialogs.) + + """ + + title = "File Selection Dialog" + + def __init__(self, master, title=None): + if title is None: title = self.title + self.master = master + self.directory = None + + self.top = Toplevel(master) + self.top.title(title) + self.top.iconname(title) + + self.botframe = Frame(self.top) + self.botframe.pack(side=BOTTOM, fill=X) + + self.selection = Entry(self.top) + self.selection.pack(side=BOTTOM, fill=X) + self.selection.bind('', self.ok_event) + + self.filter = Entry(self.top) + self.filter.pack(side=TOP, fill=X) + self.filter.bind('', self.filter_command) + + self.midframe = Frame(self.top) + self.midframe.pack(expand=YES, fill=BOTH) + + self.filesbar = Scrollbar(self.midframe) + self.filesbar.pack(side=RIGHT, fill=Y) + self.files = Listbox(self.midframe, exportselection=0, + yscrollcommand=(self.filesbar, 'set')) + self.files.pack(side=RIGHT, expand=YES, fill=BOTH) + btags = self.files.bindtags() + self.files.bindtags(btags[1:] + btags[:1]) + self.files.bind('', self.files_select_event) + self.files.bind('', self.files_double_event) + self.filesbar.config(command=(self.files, 'yview')) + + self.dirsbar = Scrollbar(self.midframe) + self.dirsbar.pack(side=LEFT, fill=Y) + self.dirs = Listbox(self.midframe, exportselection=0, + yscrollcommand=(self.dirsbar, 'set')) + self.dirs.pack(side=LEFT, expand=YES, fill=BOTH) + self.dirsbar.config(command=(self.dirs, 'yview')) + btags = self.dirs.bindtags() + self.dirs.bindtags(btags[1:] + btags[:1]) + self.dirs.bind('', self.dirs_select_event) + self.dirs.bind('', self.dirs_double_event) + + self.ok_button = Button(self.botframe, + text="OK", + command=self.ok_command) + self.ok_button.pack(side=LEFT) + self.filter_button = Button(self.botframe, + text="Filter", + command=self.filter_command) + self.filter_button.pack(side=LEFT, expand=YES) + self.cancel_button = Button(self.botframe, + text="Cancel", + command=self.cancel_command) + self.cancel_button.pack(side=RIGHT) + + self.top.protocol('WM_DELETE_WINDOW', self.cancel_command) + # XXX Are the following okay for a general audience? + self.top.bind('', self.cancel_command) + self.top.bind('', self.cancel_command) + + def go(self, dir_or_file=os.curdir, pattern="*", default="", key=None): + if key and key in dialogstates: + self.directory, pattern = dialogstates[key] + else: + dir_or_file = os.path.expanduser(dir_or_file) + if os.path.isdir(dir_or_file): + self.directory = dir_or_file + else: + self.directory, default = os.path.split(dir_or_file) + self.set_filter(self.directory, pattern) + self.set_selection(default) + self.filter_command() + self.selection.focus_set() + self.top.wait_visibility() # window needs to be visible for the grab + self.top.grab_set() + self.how = None + self.master.mainloop() # Exited by self.quit(how) + if key: + directory, pattern = self.get_filter() + if self.how: + directory = os.path.dirname(self.how) + dialogstates[key] = directory, pattern + self.top.destroy() + return self.how + + def quit(self, how=None): + self.how = how + self.master.quit() # Exit mainloop() + + def dirs_double_event(self, event): + self.filter_command() + + def dirs_select_event(self, event): + dir, pat = self.get_filter() + subdir = self.dirs.get('active') + dir = os.path.normpath(os.path.join(self.directory, subdir)) + self.set_filter(dir, pat) + + def files_double_event(self, event): + self.ok_command() + + def files_select_event(self, event): + file = self.files.get('active') + self.set_selection(file) + + def ok_event(self, event): + self.ok_command() + + def ok_command(self): + self.quit(self.get_selection()) + + def filter_command(self, event=None): + dir, pat = self.get_filter() + try: + names = os.listdir(dir) + except os.error: + self.master.bell() + return + self.directory = dir + self.set_filter(dir, pat) + names.sort() + subdirs = [os.pardir] + matchingfiles = [] + for name in names: + fullname = os.path.join(dir, name) + if os.path.isdir(fullname): + subdirs.append(name) + elif fnmatch.fnmatch(name, pat): + matchingfiles.append(name) + self.dirs.delete(0, END) + for name in subdirs: + self.dirs.insert(END, name) + self.files.delete(0, END) + for name in matchingfiles: + self.files.insert(END, name) + head, tail = os.path.split(self.get_selection()) + if tail == os.curdir: tail = '' + self.set_selection(tail) + + def get_filter(self): + filter = self.filter.get() + filter = os.path.expanduser(filter) + if filter[-1:] == os.sep or os.path.isdir(filter): + filter = os.path.join(filter, "*") + return os.path.split(filter) + + def get_selection(self): + file = self.selection.get() + file = os.path.expanduser(file) + return file + + def cancel_command(self, event=None): + self.quit() + + def set_filter(self, dir, pat): + if not os.path.isabs(dir): + try: + pwd = os.getcwd() + except os.error: + pwd = None + if pwd: + dir = os.path.join(pwd, dir) + dir = os.path.normpath(dir) + self.filter.delete(0, END) + self.filter.insert(END, os.path.join(dir or os.curdir, pat or "*")) + + def set_selection(self, file): + self.selection.delete(0, END) + self.selection.insert(END, os.path.join(self.directory, file)) + + +class LoadFileDialog(FileDialog): + + """File selection dialog which checks that the file exists.""" + + title = "Load File Selection Dialog" + + def ok_command(self): + file = self.get_selection() + if not os.path.isfile(file): + self.master.bell() + else: + self.quit(file) + + +class SaveFileDialog(FileDialog): + + """File selection dialog which checks that the file may be created.""" + + title = "Save File Selection Dialog" + + def ok_command(self): + file = self.get_selection() + if os.path.exists(file): + if os.path.isdir(file): + self.master.bell() + return + d = Dialog(self.top, + title="Overwrite Existing File Question", + text="Overwrite existing file %r?" % (file,), + bitmap='questhead', + default=1, + strings=("Yes", "Cancel")) + if d.num != 0: + return + else: + head, tail = os.path.split(file) + if not os.path.isdir(head): + self.master.bell() + return + self.quit(file) + + +def test(): + """Simple test program.""" + root = Tk() + root.withdraw() + fd = LoadFileDialog(root) + loadfile = fd.go(key="test") + fd = SaveFileDialog(root) + savefile = fd.go(key="test") + print loadfile, savefile + + +if __name__ == '__main__': + test() diff --git a/PythonHome/Lib/lib-tk/FileDialog.pyc b/PythonHome/Lib/lib-tk/FileDialog.pyc deleted file mode 100644 index b38b60f3abc83411bcfb48025838fd3b8abc8c50..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 9394 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 V(sid^u9m0&IJ0-=SZz<;`7d0S30D9B diff --git a/PythonHome/Lib/lib-tk/FixTk.py b/PythonHome/Lib/lib-tk/FixTk.py new file mode 100644 index 0000000000..49960c74ca --- /dev/null +++ b/PythonHome/Lib/lib-tk/FixTk.py @@ -0,0 +1,78 @@ +import sys, os + +# Delay import _tkinter until we have set TCL_LIBRARY, +# so that Tcl_FindExecutable has a chance to locate its +# encoding directory. + +# Unfortunately, we cannot know the TCL_LIBRARY directory +# if we don't know the tcl version, which we cannot find out +# without import Tcl. Fortunately, Tcl will itself look in +# \..\tcl, so anything close to +# the real Tcl library will do. + +# Expand symbolic links on Vista +try: + import ctypes + ctypes.windll.kernel32.GetFinalPathNameByHandleW +except (ImportError, AttributeError): + def convert_path(s): + return s +else: + def convert_path(s): + assert isinstance(s, str) # sys.prefix contains only bytes + udir = s.decode("mbcs") + hdir = ctypes.windll.kernel32.\ + CreateFileW(udir, 0x80, # FILE_READ_ATTRIBUTES + 1, # FILE_SHARE_READ + None, 3, # OPEN_EXISTING + 0x02000000, # FILE_FLAG_BACKUP_SEMANTICS + None) + if hdir == -1: + # Cannot open directory, give up + return s + buf = ctypes.create_unicode_buffer(u"", 32768) + res = ctypes.windll.kernel32.\ + GetFinalPathNameByHandleW(hdir, buf, len(buf), + 0) # VOLUME_NAME_DOS + ctypes.windll.kernel32.CloseHandle(hdir) + if res == 0: + # Conversion failed (e.g. network location) + return s + s = buf[:res].encode("mbcs") + # Ignore leading \\?\ + if s.startswith("\\\\?\\"): + s = s[4:] + if s.startswith("UNC"): + s = "\\" + s[3:] + return s + +prefix = os.path.join(sys.prefix,"tcl") +if not os.path.exists(prefix): + # devdir/../tcltk/lib + prefix = os.path.join(sys.prefix, os.path.pardir, "tcltk", "lib") + prefix = os.path.abspath(prefix) +# if this does not exist, no further search is needed +if os.path.exists(prefix): + prefix = convert_path(prefix) + if "TCL_LIBRARY" not in os.environ: + for name in os.listdir(prefix): + if name.startswith("tcl"): + tcldir = os.path.join(prefix,name) + if os.path.isdir(tcldir): + os.environ["TCL_LIBRARY"] = tcldir + # Compute TK_LIBRARY, knowing that it has the same version + # as Tcl + import _tkinter + ver = str(_tkinter.TCL_VERSION) + if "TK_LIBRARY" not in os.environ: + v = os.path.join(prefix, 'tk'+ver) + if os.path.exists(os.path.join(v, "tclIndex")): + os.environ['TK_LIBRARY'] = v + # We don't know the Tix version, so we must search the entire + # directory + if "TIX_LIBRARY" not in os.environ: + for name in os.listdir(prefix): + if name.startswith("tix"): + tixdir = os.path.join(prefix,name) + if os.path.isdir(tixdir): + os.environ["TIX_LIBRARY"] = tixdir diff --git a/PythonHome/Lib/lib-tk/FixTk.pyc b/PythonHome/Lib/lib-tk/FixTk.pyc deleted file mode 100644 index af52d8cdbff8d249f1eae2ffb72e25650d1dde2f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1956 zcma)6&2k$>5boKPB}s({2qU~nle*`OelGLm*&p4ECK?~EL| z%C1Ub9*F}Fz&S6$IVT9RsUmnk|vF!IA zQGmaqh^TifE9xn_{5ZSvsOORPDD)}JQMg2^8$YI;&XX?CiAUoSC0$ZV1s?s5ILj25 z=tbZ!4q8!Iq_9MqC|sc+M>mMLLJNJF^a|Z5vVUco%yMB+p{)Kzf}s zP7V|VwyY8`n&$`VT=Bn)looBRQ?E|?A?Z4W8|>8EqyV{z6X)~h9jKs4dXqM|L0cId zs=Dpq76m0vhSA}f+5mkS=x-FmrhQFoZF%plwJc%YzLUVB*6j=vwQh@9(}S?6bp>cm z@BFR8zkA;D7+29@qk@?-|KiskDTvwH!U$t|l0oCIWQ=g_NHH51|JXrsmt-$i5YvRf0 zYH*iQ>8qe3*ExE$aeIH*SVdFX$e8GCII`w71jB7NK5tl_ur`B)cZ2wH5J| ziGwI|%-dKev5vm@9DM_ci5@uJGLh~|=Iu$W9nZ!{E{W z;AnuAXQKbt>~^?ooW0$_Myjr=s;u(LmsM0{FQ?X^sj8w{m(#jeRTZ3TN^smLa-0)C z$7wxgDD@oe?jP^(J?%W{{49hV{cwBacLUbkTlnq8fu5%>doONnxEN>VjSu`E-}NI)1s1ErCa=xiV#jrEX|%K`ozrBzR!(y z=?qK<3HP;t_=BMpFP3$DVUkHK`Uu7u2{E|s@XIf8P#IrvbBtw)vp#lXAnK$eJ>z-e zHvROhbGY}sEoJgogh{zbgP1v78#vS5_MT4>V>Hhu!7S2WaunOdwpsB(VGRUU{NhKO fYR&sp)xDI~hoG_!ino0xxvI9*Cu-fVs!abM-UV^P diff --git a/PythonHome/Lib/lib-tk/ScrolledText.py b/PythonHome/Lib/lib-tk/ScrolledText.py new file mode 100644 index 0000000000..a1ef79ca74 --- /dev/null +++ b/PythonHome/Lib/lib-tk/ScrolledText.py @@ -0,0 +1,55 @@ +"""A ScrolledText widget feels like a text widget but also has a +vertical scroll bar on its right. (Later, options may be added to +add a horizontal bar as well, to make the bars disappear +automatically when not needed, to move them to the other side of the +window, etc.) + +Configuration options are passed to the Text widget. +A Frame widget is inserted between the master and the text, to hold +the Scrollbar widget. +Most methods calls are inherited from the Text widget; Pack, Grid and +Place methods are redirected to the Frame widget however. +""" + +__all__ = ['ScrolledText'] + +from Tkinter import Frame, Text, Scrollbar, Pack, Grid, Place +from Tkconstants import RIGHT, LEFT, Y, BOTH + +class ScrolledText(Text): + def __init__(self, master=None, **kw): + self.frame = Frame(master) + self.vbar = Scrollbar(self.frame) + self.vbar.pack(side=RIGHT, fill=Y) + + kw.update({'yscrollcommand': self.vbar.set}) + Text.__init__(self, self.frame, **kw) + self.pack(side=LEFT, fill=BOTH, expand=True) + self.vbar['command'] = self.yview + + # Copy geometry methods of self.frame without overriding Text + # methods -- hack! + text_meths = vars(Text).keys() + methods = vars(Pack).keys() + vars(Grid).keys() + vars(Place).keys() + methods = set(methods).difference(text_meths) + + for m in methods: + if m[0] != '_' and m != 'config' and m != 'configure': + setattr(self, m, getattr(self.frame, m)) + + def __str__(self): + return str(self.frame) + + +def example(): + import __main__ + from Tkconstants import END + + stext = ScrolledText(bg='white', height=10) + stext.insert(END, __main__.__doc__) + stext.pack(fill=BOTH, side=LEFT, expand=True) + stext.focus_set() + stext.mainloop() + +if __name__ == "__main__": + example() diff --git a/PythonHome/Lib/lib-tk/ScrolledText.pyc b/PythonHome/Lib/lib-tk/ScrolledText.pyc deleted file mode 100644 index 37f29e7599ff3c5bdac8a3859ad4c5f26eed936a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2589 zcma)7OHUj}5U!qG78tk~Q~hDulMeNXG|i^Q9HQ&(eetJ3KrInuj;%`%f|Uxg5G$FQpHZ&m35#TWpe znmpfx0S>?mKQ#Qp>CC!hJT^%kCKF#3iCmu_>FLmvx~#k|jRA6VvO18H1;a2xg{9Wc zW)KIg38%Kqs_CXSKJ9%Th7YT9VD~09U=hZd%SmnYIB`xK7N85c>V^09lR7EPS?;XU zwsc4g%y*5S8aT$67l}h6bW$R0Y&omq<*>@LkTp#qIQ*sxz3^q_ye^C%R+-aCGit)V z*b-q_#vjxbg2UMh4t=A4Ow!S&ep*{(w#>pG^CZRfGZ+S_O=fG8GQun~|A}B&O${pB z3;iH9? zE9hU#_Q4N3&r{o!*l6RM8SAn(n{3-ziSo>>C(32Li=JL6Qw^z=$H+X;b!u|x% z3v}ET)ipY9u>j@aPpo|O^GiCJqho~Ap$(n}Evnzie&K?=IFtRl1T#ne`dLVGbQ;iU zi`1|02!F3K)VLcWsasMfCX)yQo9F%#^heDsNUNei_aTKS+2NQ)F2_u5A(E6k7K>Df zCmqy?liGA|z$W6BkX9Km$s(?=+;;$?h%iQvMGPHr{|VY;oMGsAwspow+z!YQ${yR& z`Z$hw6LAoNuv1TrTyb<@&9p(stPx>kj$Fj;8gau%()xTbvx9-DO_>@A3)dvx*CJzp zvfR*wk2;eN#II%qp!0}EQ!n>}H!)Mw$k^ z_QpriCos5%$KAw2YE@lP8^KL=UENY^?JMezS`SuKSEZaye%OVFc-#sWX2uy6w!8d# zt1CH^1o}F<3YF+1%@UrE^h<(@W9REQ=3|awNo{pGnX{6VC~F)`HsZLbvPsTc&f8X1 z8i_3W47>AdKQbpcL+rU@td3f~ma>Lp;%<@X4BPlQ=bOcHx|QX^)Fa&HAw&f diff --git a/PythonHome/Lib/lib-tk/SimpleDialog.py b/PythonHome/Lib/lib-tk/SimpleDialog.py new file mode 100644 index 0000000000..cb08318dbd --- /dev/null +++ b/PythonHome/Lib/lib-tk/SimpleDialog.py @@ -0,0 +1,112 @@ +"""A simple but flexible modal dialog box.""" + + +from Tkinter import * + + +class SimpleDialog: + + def __init__(self, master, + text='', buttons=[], default=None, cancel=None, + title=None, class_=None): + if class_: + self.root = Toplevel(master, class_=class_) + else: + self.root = Toplevel(master) + if title: + self.root.title(title) + self.root.iconname(title) + self.message = Message(self.root, text=text, aspect=400) + self.message.pack(expand=1, fill=BOTH) + self.frame = Frame(self.root) + self.frame.pack() + self.num = default + self.cancel = cancel + self.default = default + self.root.bind('', self.return_event) + for num in range(len(buttons)): + s = buttons[num] + b = Button(self.frame, text=s, + command=(lambda self=self, num=num: self.done(num))) + if num == default: + b.config(relief=RIDGE, borderwidth=8) + b.pack(side=LEFT, fill=BOTH, expand=1) + self.root.protocol('WM_DELETE_WINDOW', self.wm_delete_window) + self._set_transient(master) + + def _set_transient(self, master, relx=0.5, rely=0.3): + widget = self.root + widget.withdraw() # Remain invisible while we figure out the geometry + widget.transient(master) + widget.update_idletasks() # Actualize geometry information + if master.winfo_ismapped(): + m_width = master.winfo_width() + m_height = master.winfo_height() + m_x = master.winfo_rootx() + m_y = master.winfo_rooty() + else: + m_width = master.winfo_screenwidth() + m_height = master.winfo_screenheight() + m_x = m_y = 0 + w_width = widget.winfo_reqwidth() + w_height = widget.winfo_reqheight() + x = m_x + (m_width - w_width) * relx + y = m_y + (m_height - w_height) * rely + if x+w_width > master.winfo_screenwidth(): + x = master.winfo_screenwidth() - w_width + elif x < 0: + x = 0 + if y+w_height > master.winfo_screenheight(): + y = master.winfo_screenheight() - w_height + elif y < 0: + y = 0 + widget.geometry("+%d+%d" % (x, y)) + widget.deiconify() # Become visible at the desired location + + def go(self): + self.root.wait_visibility() + self.root.grab_set() + self.root.mainloop() + self.root.destroy() + return self.num + + def return_event(self, event): + if self.default is None: + self.root.bell() + else: + self.done(self.default) + + def wm_delete_window(self): + if self.cancel is None: + self.root.bell() + else: + self.done(self.cancel) + + def done(self, num): + self.num = num + self.root.quit() + + +if __name__ == '__main__': + + def test(): + root = Tk() + def doit(root=root): + d = SimpleDialog(root, + text="This is a test dialog. " + "Would this have been an actual dialog, " + "the buttons below would have been glowing " + "in soft pink light.\n" + "Do you believe this?", + buttons=["Yes", "No", "Cancel"], + default=0, + cancel=2, + title="Test Dialog") + print d.go() + t = Button(root, text='Test', command=doit) + t.pack() + q = Button(root, text='Quit', command=t.quit) + q.pack() + t.mainloop() + + test() diff --git a/PythonHome/Lib/lib-tk/SimpleDialog.pyc b/PythonHome/Lib/lib-tk/SimpleDialog.pyc deleted file mode 100644 index f712ac77b8e64912c8ab8d54bb72ebe3ba295f24..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4174 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 diff --git a/PythonHome/Lib/lib-tk/Tix.py b/PythonHome/Lib/lib-tk/Tix.py new file mode 100644 index 0000000000..1f28e56f74 --- /dev/null +++ b/PythonHome/Lib/lib-tk/Tix.py @@ -0,0 +1,1945 @@ +# -*-mode: python; fill-column: 75; tab-width: 8; coding: iso-latin-1-unix -*- +# +# $Id$ +# +# Tix.py -- Tix widget wrappers. +# +# For Tix, see http://tix.sourceforge.net +# +# - Sudhir Shenoy (sshenoy@gol.com), Dec. 1995. +# based on an idea of Jean-Marc Lugrin (lugrin@ms.com) +# +# NOTE: In order to minimize changes to Tkinter.py, some of the code here +# (TixWidget.__init__) has been taken from Tkinter (Widget.__init__) +# and will break if there are major changes in Tkinter. +# +# The Tix widgets are represented by a class hierarchy in python with proper +# inheritance of base classes. +# +# As a result after creating a 'w = StdButtonBox', I can write +# w.ok['text'] = 'Who Cares' +# or w.ok['bg'] = w['bg'] +# or even w.ok.invoke() +# etc. +# +# Compare the demo tixwidgets.py to the original Tcl program and you will +# appreciate the advantages. +# + +from Tkinter import * +from Tkinter import _flatten, _cnfmerge, _default_root + +# WARNING - TkVersion is a limited precision floating point number +if TkVersion < 3.999: + raise ImportError, "This version of Tix.py requires Tk 4.0 or higher" + +import _tkinter # If this fails your Python may not be configured for Tk + +# Some more constants (for consistency with Tkinter) +WINDOW = 'window' +TEXT = 'text' +STATUS = 'status' +IMMEDIATE = 'immediate' +IMAGE = 'image' +IMAGETEXT = 'imagetext' +BALLOON = 'balloon' +AUTO = 'auto' +ACROSSTOP = 'acrosstop' + +# A few useful constants for the Grid widget +ASCII = 'ascii' +CELL = 'cell' +COLUMN = 'column' +DECREASING = 'decreasing' +INCREASING = 'increasing' +INTEGER = 'integer' +MAIN = 'main' +MAX = 'max' +REAL = 'real' +ROW = 'row' +S_REGION = 's-region' +X_REGION = 'x-region' +Y_REGION = 'y-region' + +# Some constants used by Tkinter dooneevent() +TCL_DONT_WAIT = 1 << 1 +TCL_WINDOW_EVENTS = 1 << 2 +TCL_FILE_EVENTS = 1 << 3 +TCL_TIMER_EVENTS = 1 << 4 +TCL_IDLE_EVENTS = 1 << 5 +TCL_ALL_EVENTS = 0 + +# BEWARE - this is implemented by copying some code from the Widget class +# in Tkinter (to override Widget initialization) and is therefore +# liable to break. +import Tkinter, os + +# Could probably add this to Tkinter.Misc +class tixCommand: + """The tix commands provide access to miscellaneous elements + of Tix's internal state and the Tix application context. + Most of the information manipulated by these commands pertains + to the application as a whole, or to a screen or + display, rather than to a particular window. + + This is a mixin class, assumed to be mixed to Tkinter.Tk + that supports the self.tk.call method. + """ + + def tix_addbitmapdir(self, directory): + """Tix maintains a list of directories under which + the tix_getimage and tix_getbitmap commands will + search for image files. The standard bitmap directory + is $TIX_LIBRARY/bitmaps. The addbitmapdir command + adds directory into this list. By using this + command, the image files of an applications can + also be located using the tix_getimage or tix_getbitmap + command. + """ + return self.tk.call('tix', 'addbitmapdir', directory) + + def tix_cget(self, option): + """Returns the current value of the configuration + option given by option. Option may be any of the + options described in the CONFIGURATION OPTIONS section. + """ + return self.tk.call('tix', 'cget', option) + + def tix_configure(self, cnf=None, **kw): + """Query or modify the configuration options of the Tix application + context. If no option is specified, returns a dictionary all of the + available options. If option is specified with no value, then the + command returns a list describing the one named option (this list + will be identical to the corresponding sublist of the value + returned if no option is specified). If one or more option-value + pairs are specified, then the command modifies the given option(s) + to have the given value(s); in this case the command returns an + empty string. Option may be any of the configuration options. + """ + # Copied from Tkinter.py + if kw: + cnf = _cnfmerge((cnf, kw)) + elif cnf: + cnf = _cnfmerge(cnf) + if cnf is None: + return self._getconfigure('tix', 'configure') + if isinstance(cnf, StringType): + return self._getconfigure1('tix', 'configure', '-'+cnf) + return self.tk.call(('tix', 'configure') + self._options(cnf)) + + def tix_filedialog(self, dlgclass=None): + """Returns the file selection dialog that may be shared among + different calls from this application. This command will create a + file selection dialog widget when it is called the first time. This + dialog will be returned by all subsequent calls to tix_filedialog. + An optional dlgclass parameter can be passed to specified what type + of file selection dialog widget is desired. Possible options are + tix FileSelectDialog or tixExFileSelectDialog. + """ + if dlgclass is not None: + return self.tk.call('tix', 'filedialog', dlgclass) + else: + return self.tk.call('tix', 'filedialog') + + def tix_getbitmap(self, name): + """Locates a bitmap file of the name name.xpm or name in one of the + bitmap directories (see the tix_addbitmapdir command above). By + using tix_getbitmap, you can avoid hard coding the pathnames of the + bitmap files in your application. When successful, it returns the + complete pathname of the bitmap file, prefixed with the character + '@'. The returned value can be used to configure the -bitmap + option of the TK and Tix widgets. + """ + return self.tk.call('tix', 'getbitmap', name) + + def tix_getimage(self, name): + """Locates an image file of the name name.xpm, name.xbm or name.ppm + in one of the bitmap directories (see the addbitmapdir command + above). If more than one file with the same name (but different + extensions) exist, then the image type is chosen according to the + depth of the X display: xbm images are chosen on monochrome + displays and color images are chosen on color displays. By using + tix_ getimage, you can avoid hard coding the pathnames of the + image files in your application. When successful, this command + returns the name of the newly created image, which can be used to + configure the -image option of the Tk and Tix widgets. + """ + return self.tk.call('tix', 'getimage', name) + + def tix_option_get(self, name): + """Gets the options maintained by the Tix + scheme mechanism. Available options include: + + active_bg active_fg bg + bold_font dark1_bg dark1_fg + dark2_bg dark2_fg disabled_fg + fg fixed_font font + inactive_bg inactive_fg input1_bg + input2_bg italic_font light1_bg + light1_fg light2_bg light2_fg + menu_font output1_bg output2_bg + select_bg select_fg selector + """ + # could use self.tk.globalgetvar('tixOption', name) + return self.tk.call('tix', 'option', 'get', name) + + def tix_resetoptions(self, newScheme, newFontSet, newScmPrio=None): + """Resets the scheme and fontset of the Tix application to + newScheme and newFontSet, respectively. This affects only those + widgets created after this call. Therefore, it is best to call the + resetoptions command before the creation of any widgets in a Tix + application. + + The optional parameter newScmPrio can be given to reset the + priority level of the Tk options set by the Tix schemes. + + Because of the way Tk handles the X option database, after Tix has + been has imported and inited, it is not possible to reset the color + schemes and font sets using the tix config command. Instead, the + tix_resetoptions command must be used. + """ + if newScmPrio is not None: + return self.tk.call('tix', 'resetoptions', newScheme, newFontSet, newScmPrio) + else: + return self.tk.call('tix', 'resetoptions', newScheme, newFontSet) + +class Tk(Tkinter.Tk, tixCommand): + """Toplevel widget of Tix which represents mostly the main window + of an application. It has an associated Tcl interpreter.""" + def __init__(self, screenName=None, baseName=None, className='Tix'): + Tkinter.Tk.__init__(self, screenName, baseName, className) + tixlib = os.environ.get('TIX_LIBRARY') + self.tk.eval('global auto_path; lappend auto_path [file dir [info nameof]]') + if tixlib is not None: + self.tk.eval('global auto_path; lappend auto_path {%s}' % tixlib) + self.tk.eval('global tcl_pkgPath; lappend tcl_pkgPath {%s}' % tixlib) + # Load Tix - this should work dynamically or statically + # If it's static, tcl/tix8.1/pkgIndex.tcl should have + # 'load {} Tix' + # If it's dynamic under Unix, tcl/tix8.1/pkgIndex.tcl should have + # 'load libtix8.1.8.3.so Tix' + self.tk.eval('package require Tix') + + def destroy(self): + # For safety, remove an delete_window binding before destroy + self.protocol("WM_DELETE_WINDOW", "") + Tkinter.Tk.destroy(self) + +# The Tix 'tixForm' geometry manager +class Form: + """The Tix Form geometry manager + + Widgets can be arranged by specifying attachments to other widgets. + See Tix documentation for complete details""" + + def config(self, cnf={}, **kw): + self.tk.call('tixForm', self._w, *self._options(cnf, kw)) + + form = config + + def __setitem__(self, key, value): + Form.form(self, {key: value}) + + def check(self): + return self.tk.call('tixForm', 'check', self._w) + + def forget(self): + self.tk.call('tixForm', 'forget', self._w) + + def grid(self, xsize=0, ysize=0): + if (not xsize) and (not ysize): + x = self.tk.call('tixForm', 'grid', self._w) + y = self.tk.splitlist(x) + z = () + for x in y: + z = z + (self.tk.getint(x),) + return z + return self.tk.call('tixForm', 'grid', self._w, xsize, ysize) + + def info(self, option=None): + if not option: + return self.tk.call('tixForm', 'info', self._w) + if option[0] != '-': + option = '-' + option + return self.tk.call('tixForm', 'info', self._w, option) + + def slaves(self): + return map(self._nametowidget, + self.tk.splitlist( + self.tk.call( + 'tixForm', 'slaves', self._w))) + + + +Tkinter.Widget.__bases__ = Tkinter.Widget.__bases__ + (Form,) + +class TixWidget(Tkinter.Widget): + """A TixWidget class is used to package all (or most) Tix widgets. + + Widget initialization is extended in two ways: + 1) It is possible to give a list of options which must be part of + the creation command (so called Tix 'static' options). These cannot be + given as a 'config' command later. + 2) It is possible to give the name of an existing TK widget. These are + child widgets created automatically by a Tix mega-widget. The Tk call + to create these widgets is therefore bypassed in TixWidget.__init__ + + Both options are for use by subclasses only. + """ + def __init__ (self, master=None, widgetName=None, + static_options=None, cnf={}, kw={}): + # Merge keywords and dictionary arguments + if kw: + cnf = _cnfmerge((cnf, kw)) + else: + cnf = _cnfmerge(cnf) + + # Move static options into extra. static_options must be + # a list of keywords (or None). + extra=() + + # 'options' is always a static option + if static_options: + static_options.append('options') + else: + static_options = ['options'] + + for k,v in cnf.items()[:]: + if k in static_options: + extra = extra + ('-' + k, v) + del cnf[k] + + self.widgetName = widgetName + Widget._setup(self, master, cnf) + + # If widgetName is None, this is a dummy creation call where the + # corresponding Tk widget has already been created by Tix + if widgetName: + self.tk.call(widgetName, self._w, *extra) + + # Non-static options - to be done via a 'config' command + if cnf: + Widget.config(self, cnf) + + # Dictionary to hold subwidget names for easier access. We can't + # use the children list because the public Tix names may not be the + # same as the pathname component + self.subwidget_list = {} + + # We set up an attribute access function so that it is possible to + # do w.ok['text'] = 'Hello' rather than w.subwidget('ok')['text'] = 'Hello' + # when w is a StdButtonBox. + # We can even do w.ok.invoke() because w.ok is subclassed from the + # Button class if you go through the proper constructors + def __getattr__(self, name): + if name in self.subwidget_list: + return self.subwidget_list[name] + raise AttributeError, name + + def set_silent(self, value): + """Set a variable without calling its action routine""" + self.tk.call('tixSetSilent', self._w, value) + + def subwidget(self, name): + """Return the named subwidget (which must have been created by + the sub-class).""" + n = self._subwidget_name(name) + if not n: + raise TclError, "Subwidget " + name + " not child of " + self._name + # Remove header of name and leading dot + n = n[len(self._w)+1:] + return self._nametowidget(n) + + def subwidgets_all(self): + """Return all subwidgets.""" + names = self._subwidget_names() + if not names: + return [] + retlist = [] + for name in names: + name = name[len(self._w)+1:] + try: + retlist.append(self._nametowidget(name)) + except: + # some of the widgets are unknown e.g. border in LabelFrame + pass + return retlist + + def _subwidget_name(self,name): + """Get a subwidget name (returns a String, not a Widget !)""" + try: + return self.tk.call(self._w, 'subwidget', name) + except TclError: + return None + + def _subwidget_names(self): + """Return the name of all subwidgets.""" + try: + x = self.tk.call(self._w, 'subwidgets', '-all') + return self.tk.splitlist(x) + except TclError: + return None + + def config_all(self, option, value): + """Set configuration options for all subwidgets (and self).""" + if option == '': + return + elif not isinstance(option, StringType): + option = repr(option) + if not isinstance(value, StringType): + value = repr(value) + names = self._subwidget_names() + for name in names: + self.tk.call(name, 'configure', '-' + option, value) + # These are missing from Tkinter + def image_create(self, imgtype, cnf={}, master=None, **kw): + if not master: + master = Tkinter._default_root + if not master: + raise RuntimeError, 'Too early to create image' + if kw and cnf: cnf = _cnfmerge((cnf, kw)) + elif kw: cnf = kw + options = () + for k, v in cnf.items(): + if hasattr(v, '__call__'): + v = self._register(v) + options = options + ('-'+k, v) + return master.tk.call(('image', 'create', imgtype,) + options) + def image_delete(self, imgname): + try: + self.tk.call('image', 'delete', imgname) + except TclError: + # May happen if the root was destroyed + pass + +# Subwidgets are child widgets created automatically by mega-widgets. +# In python, we have to create these subwidgets manually to mirror their +# existence in Tk/Tix. +class TixSubWidget(TixWidget): + """Subwidget class. + + This is used to mirror child widgets automatically created + by Tix/Tk as part of a mega-widget in Python (which is not informed + of this)""" + + def __init__(self, master, name, + destroy_physically=1, check_intermediate=1): + if check_intermediate: + path = master._subwidget_name(name) + try: + path = path[len(master._w)+1:] + plist = path.split('.') + except: + plist = [] + + if not check_intermediate: + # immediate descendant + TixWidget.__init__(self, master, None, None, {'name' : name}) + else: + # Ensure that the intermediate widgets exist + parent = master + for i in range(len(plist) - 1): + n = '.'.join(plist[:i+1]) + try: + w = master._nametowidget(n) + parent = w + except KeyError: + # Create the intermediate widget + parent = TixSubWidget(parent, plist[i], + destroy_physically=0, + check_intermediate=0) + # The Tk widget name is in plist, not in name + if plist: + name = plist[-1] + TixWidget.__init__(self, parent, None, None, {'name' : name}) + self.destroy_physically = destroy_physically + + def destroy(self): + # For some widgets e.g., a NoteBook, when we call destructors, + # we must be careful not to destroy the frame widget since this + # also destroys the parent NoteBook thus leading to an exception + # in Tkinter when it finally calls Tcl to destroy the NoteBook + for c in self.children.values(): c.destroy() + if self._name in self.master.children: + del self.master.children[self._name] + if self._name in self.master.subwidget_list: + del self.master.subwidget_list[self._name] + if self.destroy_physically: + # This is bypassed only for a few widgets + self.tk.call('destroy', self._w) + + +# Useful class to create a display style - later shared by many items. +# Contributed by Steffen Kremser +class DisplayStyle: + """DisplayStyle - handle configuration options shared by + (multiple) Display Items""" + + def __init__(self, itemtype, cnf={}, **kw): + master = _default_root # global from Tkinter + if not master and 'refwindow' in cnf: master=cnf['refwindow'] + elif not master and 'refwindow' in kw: master= kw['refwindow'] + elif not master: raise RuntimeError, "Too early to create display style: no root window" + self.tk = master.tk + self.stylename = self.tk.call('tixDisplayStyle', itemtype, + *self._options(cnf,kw) ) + + def __str__(self): + return self.stylename + + def _options(self, cnf, kw): + if kw and cnf: + cnf = _cnfmerge((cnf, kw)) + elif kw: + cnf = kw + opts = () + for k, v in cnf.items(): + opts = opts + ('-'+k, v) + return opts + + def delete(self): + self.tk.call(self.stylename, 'delete') + + def __setitem__(self,key,value): + self.tk.call(self.stylename, 'configure', '-%s'%key, value) + + def config(self, cnf={}, **kw): + return self._getconfigure( + self.stylename, 'configure', *self._options(cnf,kw)) + + def __getitem__(self,key): + return self.tk.call(self.stylename, 'cget', '-%s'%key) + + +###################################################### +### The Tix Widget classes - in alphabetical order ### +###################################################### + +class Balloon(TixWidget): + """Balloon help widget. + + Subwidget Class + --------- ----- + label Label + message Message""" + + # FIXME: It should inherit -superclass tixShell + def __init__(self, master=None, cnf={}, **kw): + # static seem to be -installcolormap -initwait -statusbar -cursor + static = ['options', 'installcolormap', 'initwait', 'statusbar', + 'cursor'] + TixWidget.__init__(self, master, 'tixBalloon', static, cnf, kw) + self.subwidget_list['label'] = _dummyLabel(self, 'label', + destroy_physically=0) + self.subwidget_list['message'] = _dummyLabel(self, 'message', + destroy_physically=0) + + def bind_widget(self, widget, cnf={}, **kw): + """Bind balloon widget to another. + One balloon widget may be bound to several widgets at the same time""" + self.tk.call(self._w, 'bind', widget._w, *self._options(cnf, kw)) + + def unbind_widget(self, widget): + self.tk.call(self._w, 'unbind', widget._w) + +class ButtonBox(TixWidget): + """ButtonBox - A container for pushbuttons. + Subwidgets are the buttons added with the add method. + """ + def __init__(self, master=None, cnf={}, **kw): + TixWidget.__init__(self, master, 'tixButtonBox', + ['orientation', 'options'], cnf, kw) + + def add(self, name, cnf={}, **kw): + """Add a button with given name to box.""" + + btn = self.tk.call(self._w, 'add', name, *self._options(cnf, kw)) + self.subwidget_list[name] = _dummyButton(self, name) + return btn + + def invoke(self, name): + if name in self.subwidget_list: + self.tk.call(self._w, 'invoke', name) + +class ComboBox(TixWidget): + """ComboBox - an Entry field with a dropdown menu. The user can select a + choice by either typing in the entry subwidget or selecting from the + listbox subwidget. + + Subwidget Class + --------- ----- + entry Entry + arrow Button + slistbox ScrolledListBox + tick Button + cross Button : present if created with the fancy option""" + + # FIXME: It should inherit -superclass tixLabelWidget + def __init__ (self, master=None, cnf={}, **kw): + TixWidget.__init__(self, master, 'tixComboBox', + ['editable', 'dropdown', 'fancy', 'options'], + cnf, kw) + self.subwidget_list['label'] = _dummyLabel(self, 'label') + self.subwidget_list['entry'] = _dummyEntry(self, 'entry') + self.subwidget_list['arrow'] = _dummyButton(self, 'arrow') + self.subwidget_list['slistbox'] = _dummyScrolledListBox(self, + 'slistbox') + try: + self.subwidget_list['tick'] = _dummyButton(self, 'tick') + self.subwidget_list['cross'] = _dummyButton(self, 'cross') + except TypeError: + # unavailable when -fancy not specified + pass + + # align + + def add_history(self, str): + self.tk.call(self._w, 'addhistory', str) + + def append_history(self, str): + self.tk.call(self._w, 'appendhistory', str) + + def insert(self, index, str): + self.tk.call(self._w, 'insert', index, str) + + def pick(self, index): + self.tk.call(self._w, 'pick', index) + +class Control(TixWidget): + """Control - An entry field with value change arrows. The user can + adjust the value by pressing the two arrow buttons or by entering + the value directly into the entry. The new value will be checked + against the user-defined upper and lower limits. + + Subwidget Class + --------- ----- + incr Button + decr Button + entry Entry + label Label""" + + # FIXME: It should inherit -superclass tixLabelWidget + def __init__ (self, master=None, cnf={}, **kw): + TixWidget.__init__(self, master, 'tixControl', ['options'], cnf, kw) + self.subwidget_list['incr'] = _dummyButton(self, 'incr') + self.subwidget_list['decr'] = _dummyButton(self, 'decr') + self.subwidget_list['label'] = _dummyLabel(self, 'label') + self.subwidget_list['entry'] = _dummyEntry(self, 'entry') + + def decrement(self): + self.tk.call(self._w, 'decr') + + def increment(self): + self.tk.call(self._w, 'incr') + + def invoke(self): + self.tk.call(self._w, 'invoke') + + def update(self): + self.tk.call(self._w, 'update') + +class DirList(TixWidget): + """DirList - displays a list view of a directory, its previous + directories and its sub-directories. The user can choose one of + the directories displayed in the list or change to another directory. + + Subwidget Class + --------- ----- + hlist HList + hsb Scrollbar + vsb Scrollbar""" + + # FIXME: It should inherit -superclass tixScrolledHList + def __init__(self, master, cnf={}, **kw): + TixWidget.__init__(self, master, 'tixDirList', ['options'], cnf, kw) + self.subwidget_list['hlist'] = _dummyHList(self, 'hlist') + self.subwidget_list['vsb'] = _dummyScrollbar(self, 'vsb') + self.subwidget_list['hsb'] = _dummyScrollbar(self, 'hsb') + + def chdir(self, dir): + self.tk.call(self._w, 'chdir', dir) + +class DirTree(TixWidget): + """DirTree - Directory Listing in a hierarchical view. + Displays a tree view of a directory, its previous directories and its + sub-directories. The user can choose one of the directories displayed + in the list or change to another directory. + + Subwidget Class + --------- ----- + hlist HList + hsb Scrollbar + vsb Scrollbar""" + + # FIXME: It should inherit -superclass tixScrolledHList + def __init__(self, master, cnf={}, **kw): + TixWidget.__init__(self, master, 'tixDirTree', ['options'], cnf, kw) + self.subwidget_list['hlist'] = _dummyHList(self, 'hlist') + self.subwidget_list['vsb'] = _dummyScrollbar(self, 'vsb') + self.subwidget_list['hsb'] = _dummyScrollbar(self, 'hsb') + + def chdir(self, dir): + self.tk.call(self._w, 'chdir', dir) + +class DirSelectBox(TixWidget): + """DirSelectBox - Motif style file select box. + It is generally used for + the user to choose a file. FileSelectBox stores the files mostly + recently selected into a ComboBox widget so that they can be quickly + selected again. + + Subwidget Class + --------- ----- + selection ComboBox + filter ComboBox + dirlist ScrolledListBox + filelist ScrolledListBox""" + + def __init__(self, master, cnf={}, **kw): + TixWidget.__init__(self, master, 'tixDirSelectBox', ['options'], cnf, kw) + self.subwidget_list['dirlist'] = _dummyDirList(self, 'dirlist') + self.subwidget_list['dircbx'] = _dummyFileComboBox(self, 'dircbx') + +class ExFileSelectBox(TixWidget): + """ExFileSelectBox - MS Windows style file select box. + It provides an convenient method for the user to select files. + + Subwidget Class + --------- ----- + cancel Button + ok Button + hidden Checkbutton + types ComboBox + dir ComboBox + file ComboBox + dirlist ScrolledListBox + filelist ScrolledListBox""" + + def __init__(self, master, cnf={}, **kw): + TixWidget.__init__(self, master, 'tixExFileSelectBox', ['options'], cnf, kw) + self.subwidget_list['cancel'] = _dummyButton(self, 'cancel') + self.subwidget_list['ok'] = _dummyButton(self, 'ok') + self.subwidget_list['hidden'] = _dummyCheckbutton(self, 'hidden') + self.subwidget_list['types'] = _dummyComboBox(self, 'types') + self.subwidget_list['dir'] = _dummyComboBox(self, 'dir') + self.subwidget_list['dirlist'] = _dummyDirList(self, 'dirlist') + self.subwidget_list['file'] = _dummyComboBox(self, 'file') + self.subwidget_list['filelist'] = _dummyScrolledListBox(self, 'filelist') + + def filter(self): + self.tk.call(self._w, 'filter') + + def invoke(self): + self.tk.call(self._w, 'invoke') + + +# Should inherit from a Dialog class +class DirSelectDialog(TixWidget): + """The DirSelectDialog widget presents the directories in the file + system in a dialog window. The user can use this dialog window to + navigate through the file system to select the desired directory. + + Subwidgets Class + ---------- ----- + dirbox DirSelectDialog""" + + # FIXME: It should inherit -superclass tixDialogShell + def __init__(self, master, cnf={}, **kw): + TixWidget.__init__(self, master, 'tixDirSelectDialog', + ['options'], cnf, kw) + self.subwidget_list['dirbox'] = _dummyDirSelectBox(self, 'dirbox') + # cancel and ok buttons are missing + + def popup(self): + self.tk.call(self._w, 'popup') + + def popdown(self): + self.tk.call(self._w, 'popdown') + + +# Should inherit from a Dialog class +class ExFileSelectDialog(TixWidget): + """ExFileSelectDialog - MS Windows style file select dialog. + It provides an convenient method for the user to select files. + + Subwidgets Class + ---------- ----- + fsbox ExFileSelectBox""" + + # FIXME: It should inherit -superclass tixDialogShell + def __init__(self, master, cnf={}, **kw): + TixWidget.__init__(self, master, 'tixExFileSelectDialog', + ['options'], cnf, kw) + self.subwidget_list['fsbox'] = _dummyExFileSelectBox(self, 'fsbox') + + def popup(self): + self.tk.call(self._w, 'popup') + + def popdown(self): + self.tk.call(self._w, 'popdown') + +class FileSelectBox(TixWidget): + """ExFileSelectBox - Motif style file select box. + It is generally used for + the user to choose a file. FileSelectBox stores the files mostly + recently selected into a ComboBox widget so that they can be quickly + selected again. + + Subwidget Class + --------- ----- + selection ComboBox + filter ComboBox + dirlist ScrolledListBox + filelist ScrolledListBox""" + + def __init__(self, master, cnf={}, **kw): + TixWidget.__init__(self, master, 'tixFileSelectBox', ['options'], cnf, kw) + self.subwidget_list['dirlist'] = _dummyScrolledListBox(self, 'dirlist') + self.subwidget_list['filelist'] = _dummyScrolledListBox(self, 'filelist') + self.subwidget_list['filter'] = _dummyComboBox(self, 'filter') + self.subwidget_list['selection'] = _dummyComboBox(self, 'selection') + + def apply_filter(self): # name of subwidget is same as command + self.tk.call(self._w, 'filter') + + def invoke(self): + self.tk.call(self._w, 'invoke') + +# Should inherit from a Dialog class +class FileSelectDialog(TixWidget): + """FileSelectDialog - Motif style file select dialog. + + Subwidgets Class + ---------- ----- + btns StdButtonBox + fsbox FileSelectBox""" + + # FIXME: It should inherit -superclass tixStdDialogShell + def __init__(self, master, cnf={}, **kw): + TixWidget.__init__(self, master, 'tixFileSelectDialog', + ['options'], cnf, kw) + self.subwidget_list['btns'] = _dummyStdButtonBox(self, 'btns') + self.subwidget_list['fsbox'] = _dummyFileSelectBox(self, 'fsbox') + + def popup(self): + self.tk.call(self._w, 'popup') + + def popdown(self): + self.tk.call(self._w, 'popdown') + +class FileEntry(TixWidget): + """FileEntry - Entry field with button that invokes a FileSelectDialog. + The user can type in the filename manually. Alternatively, the user can + press the button widget that sits next to the entry, which will bring + up a file selection dialog. + + Subwidgets Class + ---------- ----- + button Button + entry Entry""" + + # FIXME: It should inherit -superclass tixLabelWidget + def __init__(self, master, cnf={}, **kw): + TixWidget.__init__(self, master, 'tixFileEntry', + ['dialogtype', 'options'], cnf, kw) + self.subwidget_list['button'] = _dummyButton(self, 'button') + self.subwidget_list['entry'] = _dummyEntry(self, 'entry') + + def invoke(self): + self.tk.call(self._w, 'invoke') + + def file_dialog(self): + # FIXME: return python object + pass + +class HList(TixWidget, XView, YView): + """HList - Hierarchy display widget can be used to display any data + that have a hierarchical structure, for example, file system directory + trees. The list entries are indented and connected by branch lines + according to their places in the hierarchy. + + Subwidgets - None""" + + def __init__ (self,master=None,cnf={}, **kw): + TixWidget.__init__(self, master, 'tixHList', + ['columns', 'options'], cnf, kw) + + def add(self, entry, cnf={}, **kw): + return self.tk.call(self._w, 'add', entry, *self._options(cnf, kw)) + + def add_child(self, parent=None, cnf={}, **kw): + if not parent: + parent = '' + return self.tk.call( + self._w, 'addchild', parent, *self._options(cnf, kw)) + + def anchor_set(self, entry): + self.tk.call(self._w, 'anchor', 'set', entry) + + def anchor_clear(self): + self.tk.call(self._w, 'anchor', 'clear') + + def column_width(self, col=0, width=None, chars=None): + if not chars: + return self.tk.call(self._w, 'column', 'width', col, width) + else: + return self.tk.call(self._w, 'column', 'width', col, + '-char', chars) + + def delete_all(self): + self.tk.call(self._w, 'delete', 'all') + + def delete_entry(self, entry): + self.tk.call(self._w, 'delete', 'entry', entry) + + def delete_offsprings(self, entry): + self.tk.call(self._w, 'delete', 'offsprings', entry) + + def delete_siblings(self, entry): + self.tk.call(self._w, 'delete', 'siblings', entry) + + def dragsite_set(self, index): + self.tk.call(self._w, 'dragsite', 'set', index) + + def dragsite_clear(self): + self.tk.call(self._w, 'dragsite', 'clear') + + def dropsite_set(self, index): + self.tk.call(self._w, 'dropsite', 'set', index) + + def dropsite_clear(self): + self.tk.call(self._w, 'dropsite', 'clear') + + def header_create(self, col, cnf={}, **kw): + self.tk.call(self._w, 'header', 'create', col, *self._options(cnf, kw)) + + def header_configure(self, col, cnf={}, **kw): + if cnf is None: + return self._getconfigure(self._w, 'header', 'configure', col) + self.tk.call(self._w, 'header', 'configure', col, + *self._options(cnf, kw)) + + def header_cget(self, col, opt): + return self.tk.call(self._w, 'header', 'cget', col, opt) + + def header_exists(self, col): + return self.tk.call(self._w, 'header', 'exists', col) + + def header_delete(self, col): + self.tk.call(self._w, 'header', 'delete', col) + + def header_size(self, col): + return self.tk.call(self._w, 'header', 'size', col) + + def hide_entry(self, entry): + self.tk.call(self._w, 'hide', 'entry', entry) + + def indicator_create(self, entry, cnf={}, **kw): + self.tk.call( + self._w, 'indicator', 'create', entry, *self._options(cnf, kw)) + + def indicator_configure(self, entry, cnf={}, **kw): + if cnf is None: + return self._getconfigure( + self._w, 'indicator', 'configure', entry) + self.tk.call( + self._w, 'indicator', 'configure', entry, *self._options(cnf, kw)) + + def indicator_cget(self, entry, opt): + return self.tk.call(self._w, 'indicator', 'cget', entry, opt) + + def indicator_exists(self, entry): + return self.tk.call (self._w, 'indicator', 'exists', entry) + + def indicator_delete(self, entry): + self.tk.call(self._w, 'indicator', 'delete', entry) + + def indicator_size(self, entry): + return self.tk.call(self._w, 'indicator', 'size', entry) + + def info_anchor(self): + return self.tk.call(self._w, 'info', 'anchor') + + def info_bbox(self, entry): + return self._getints( + self.tk.call(self._w, 'info', 'bbox', entry)) or None + + def info_children(self, entry=None): + c = self.tk.call(self._w, 'info', 'children', entry) + return self.tk.splitlist(c) + + def info_data(self, entry): + return self.tk.call(self._w, 'info', 'data', entry) + + def info_dragsite(self): + return self.tk.call(self._w, 'info', 'dragsite') + + def info_dropsite(self): + return self.tk.call(self._w, 'info', 'dropsite') + + def info_exists(self, entry): + return self.tk.call(self._w, 'info', 'exists', entry) + + def info_hidden(self, entry): + return self.tk.call(self._w, 'info', 'hidden', entry) + + def info_next(self, entry): + return self.tk.call(self._w, 'info', 'next', entry) + + def info_parent(self, entry): + return self.tk.call(self._w, 'info', 'parent', entry) + + def info_prev(self, entry): + return self.tk.call(self._w, 'info', 'prev', entry) + + def info_selection(self): + c = self.tk.call(self._w, 'info', 'selection') + return self.tk.splitlist(c) + + def item_cget(self, entry, col, opt): + return self.tk.call(self._w, 'item', 'cget', entry, col, opt) + + def item_configure(self, entry, col, cnf={}, **kw): + if cnf is None: + return self._getconfigure(self._w, 'item', 'configure', entry, col) + self.tk.call(self._w, 'item', 'configure', entry, col, + *self._options(cnf, kw)) + + def item_create(self, entry, col, cnf={}, **kw): + self.tk.call( + self._w, 'item', 'create', entry, col, *self._options(cnf, kw)) + + def item_exists(self, entry, col): + return self.tk.call(self._w, 'item', 'exists', entry, col) + + def item_delete(self, entry, col): + self.tk.call(self._w, 'item', 'delete', entry, col) + + def entrycget(self, entry, opt): + return self.tk.call(self._w, 'entrycget', entry, opt) + + def entryconfigure(self, entry, cnf={}, **kw): + if cnf is None: + return self._getconfigure(self._w, 'entryconfigure', entry) + self.tk.call(self._w, 'entryconfigure', entry, + *self._options(cnf, kw)) + + def nearest(self, y): + return self.tk.call(self._w, 'nearest', y) + + def see(self, entry): + self.tk.call(self._w, 'see', entry) + + def selection_clear(self, cnf={}, **kw): + self.tk.call(self._w, 'selection', 'clear', *self._options(cnf, kw)) + + def selection_includes(self, entry): + return self.tk.call(self._w, 'selection', 'includes', entry) + + def selection_set(self, first, last=None): + self.tk.call(self._w, 'selection', 'set', first, last) + + def show_entry(self, entry): + return self.tk.call(self._w, 'show', 'entry', entry) + +class InputOnly(TixWidget): + """InputOnly - Invisible widget. Unix only. + + Subwidgets - None""" + + def __init__ (self,master=None,cnf={}, **kw): + TixWidget.__init__(self, master, 'tixInputOnly', None, cnf, kw) + +class LabelEntry(TixWidget): + """LabelEntry - Entry field with label. Packages an entry widget + and a label into one mega widget. It can beused be used to simplify + the creation of ``entry-form'' type of interface. + + Subwidgets Class + ---------- ----- + label Label + entry Entry""" + + def __init__ (self,master=None,cnf={}, **kw): + TixWidget.__init__(self, master, 'tixLabelEntry', + ['labelside','options'], cnf, kw) + self.subwidget_list['label'] = _dummyLabel(self, 'label') + self.subwidget_list['entry'] = _dummyEntry(self, 'entry') + +class LabelFrame(TixWidget): + """LabelFrame - Labelled Frame container. Packages a frame widget + and a label into one mega widget. To create widgets inside a + LabelFrame widget, one creates the new widgets relative to the + frame subwidget and manage them inside the frame subwidget. + + Subwidgets Class + ---------- ----- + label Label + frame Frame""" + + def __init__ (self,master=None,cnf={}, **kw): + TixWidget.__init__(self, master, 'tixLabelFrame', + ['labelside','options'], cnf, kw) + self.subwidget_list['label'] = _dummyLabel(self, 'label') + self.subwidget_list['frame'] = _dummyFrame(self, 'frame') + + +class ListNoteBook(TixWidget): + """A ListNoteBook widget is very similar to the TixNoteBook widget: + it can be used to display many windows in a limited space using a + notebook metaphor. The notebook is divided into a stack of pages + (windows). At one time only one of these pages can be shown. + The user can navigate through these pages by + choosing the name of the desired page in the hlist subwidget.""" + + def __init__(self, master, cnf={}, **kw): + TixWidget.__init__(self, master, 'tixListNoteBook', ['options'], cnf, kw) + # Is this necessary? It's not an exposed subwidget in Tix. + self.subwidget_list['pane'] = _dummyPanedWindow(self, 'pane', + destroy_physically=0) + self.subwidget_list['hlist'] = _dummyHList(self, 'hlist') + self.subwidget_list['shlist'] = _dummyScrolledHList(self, 'shlist') + + def add(self, name, cnf={}, **kw): + self.tk.call(self._w, 'add', name, *self._options(cnf, kw)) + self.subwidget_list[name] = TixSubWidget(self, name) + return self.subwidget_list[name] + + def page(self, name): + return self.subwidget(name) + + def pages(self): + # Can't call subwidgets_all directly because we don't want .nbframe + names = self.tk.split(self.tk.call(self._w, 'pages')) + ret = [] + for x in names: + ret.append(self.subwidget(x)) + return ret + + def raise_page(self, name): # raise is a python keyword + self.tk.call(self._w, 'raise', name) + +class Meter(TixWidget): + """The Meter widget can be used to show the progress of a background + job which may take a long time to execute. + """ + + def __init__(self, master=None, cnf={}, **kw): + TixWidget.__init__(self, master, 'tixMeter', + ['options'], cnf, kw) + +class NoteBook(TixWidget): + """NoteBook - Multi-page container widget (tabbed notebook metaphor). + + Subwidgets Class + ---------- ----- + nbframe NoteBookFrame + page widgets added dynamically with the add method""" + + def __init__ (self,master=None,cnf={}, **kw): + TixWidget.__init__(self,master,'tixNoteBook', ['options'], cnf, kw) + self.subwidget_list['nbframe'] = TixSubWidget(self, 'nbframe', + destroy_physically=0) + + def add(self, name, cnf={}, **kw): + self.tk.call(self._w, 'add', name, *self._options(cnf, kw)) + self.subwidget_list[name] = TixSubWidget(self, name) + return self.subwidget_list[name] + + def delete(self, name): + self.tk.call(self._w, 'delete', name) + self.subwidget_list[name].destroy() + del self.subwidget_list[name] + + def page(self, name): + return self.subwidget(name) + + def pages(self): + # Can't call subwidgets_all directly because we don't want .nbframe + names = self.tk.split(self.tk.call(self._w, 'pages')) + ret = [] + for x in names: + ret.append(self.subwidget(x)) + return ret + + def raise_page(self, name): # raise is a python keyword + self.tk.call(self._w, 'raise', name) + + def raised(self): + return self.tk.call(self._w, 'raised') + +class NoteBookFrame(TixWidget): + # FIXME: This is dangerous to expose to be called on its own. + pass + +class OptionMenu(TixWidget): + """OptionMenu - creates a menu button of options. + + Subwidget Class + --------- ----- + menubutton Menubutton + menu Menu""" + + def __init__(self, master, cnf={}, **kw): + TixWidget.__init__(self, master, 'tixOptionMenu', + ['labelside', 'options'], cnf, kw) + self.subwidget_list['menubutton'] = _dummyMenubutton(self, 'menubutton') + self.subwidget_list['menu'] = _dummyMenu(self, 'menu') + + def add_command(self, name, cnf={}, **kw): + self.tk.call(self._w, 'add', 'command', name, *self._options(cnf, kw)) + + def add_separator(self, name, cnf={}, **kw): + self.tk.call(self._w, 'add', 'separator', name, *self._options(cnf, kw)) + + def delete(self, name): + self.tk.call(self._w, 'delete', name) + + def disable(self, name): + self.tk.call(self._w, 'disable', name) + + def enable(self, name): + self.tk.call(self._w, 'enable', name) + +class PanedWindow(TixWidget): + """PanedWindow - Multi-pane container widget + allows the user to interactively manipulate the sizes of several + panes. The panes can be arranged either vertically or horizontally.The + user changes the sizes of the panes by dragging the resize handle + between two panes. + + Subwidgets Class + ---------- ----- + g/p widgets added dynamically with the add method.""" + + def __init__(self, master, cnf={}, **kw): + TixWidget.__init__(self, master, 'tixPanedWindow', ['orientation', 'options'], cnf, kw) + + # add delete forget panecget paneconfigure panes setsize + def add(self, name, cnf={}, **kw): + self.tk.call(self._w, 'add', name, *self._options(cnf, kw)) + self.subwidget_list[name] = TixSubWidget(self, name, + check_intermediate=0) + return self.subwidget_list[name] + + def delete(self, name): + self.tk.call(self._w, 'delete', name) + self.subwidget_list[name].destroy() + del self.subwidget_list[name] + + def forget(self, name): + self.tk.call(self._w, 'forget', name) + + def panecget(self, entry, opt): + return self.tk.call(self._w, 'panecget', entry, opt) + + def paneconfigure(self, entry, cnf={}, **kw): + if cnf is None: + return self._getconfigure(self._w, 'paneconfigure', entry) + self.tk.call(self._w, 'paneconfigure', entry, *self._options(cnf, kw)) + + def panes(self): + names = self.tk.splitlist(self.tk.call(self._w, 'panes')) + return [self.subwidget(x) for x in names] + +class PopupMenu(TixWidget): + """PopupMenu widget can be used as a replacement of the tk_popup command. + The advantage of the Tix PopupMenu widget is it requires less application + code to manipulate. + + + Subwidgets Class + ---------- ----- + menubutton Menubutton + menu Menu""" + + # FIXME: It should inherit -superclass tixShell + def __init__(self, master, cnf={}, **kw): + TixWidget.__init__(self, master, 'tixPopupMenu', ['options'], cnf, kw) + self.subwidget_list['menubutton'] = _dummyMenubutton(self, 'menubutton') + self.subwidget_list['menu'] = _dummyMenu(self, 'menu') + + def bind_widget(self, widget): + self.tk.call(self._w, 'bind', widget._w) + + def unbind_widget(self, widget): + self.tk.call(self._w, 'unbind', widget._w) + + def post_widget(self, widget, x, y): + self.tk.call(self._w, 'post', widget._w, x, y) + +class ResizeHandle(TixWidget): + """Internal widget to draw resize handles on Scrolled widgets.""" + def __init__(self, master, cnf={}, **kw): + # There seems to be a Tix bug rejecting the configure method + # Let's try making the flags -static + flags = ['options', 'command', 'cursorfg', 'cursorbg', + 'handlesize', 'hintcolor', 'hintwidth', + 'x', 'y'] + # In fact, x y height width are configurable + TixWidget.__init__(self, master, 'tixResizeHandle', + flags, cnf, kw) + + def attach_widget(self, widget): + self.tk.call(self._w, 'attachwidget', widget._w) + + def detach_widget(self, widget): + self.tk.call(self._w, 'detachwidget', widget._w) + + def hide(self, widget): + self.tk.call(self._w, 'hide', widget._w) + + def show(self, widget): + self.tk.call(self._w, 'show', widget._w) + +class ScrolledHList(TixWidget): + """ScrolledHList - HList with automatic scrollbars.""" + + # FIXME: It should inherit -superclass tixScrolledWidget + def __init__(self, master, cnf={}, **kw): + TixWidget.__init__(self, master, 'tixScrolledHList', ['options'], + cnf, kw) + self.subwidget_list['hlist'] = _dummyHList(self, 'hlist') + self.subwidget_list['vsb'] = _dummyScrollbar(self, 'vsb') + self.subwidget_list['hsb'] = _dummyScrollbar(self, 'hsb') + +class ScrolledListBox(TixWidget): + """ScrolledListBox - Listbox with automatic scrollbars.""" + + # FIXME: It should inherit -superclass tixScrolledWidget + def __init__(self, master, cnf={}, **kw): + TixWidget.__init__(self, master, 'tixScrolledListBox', ['options'], cnf, kw) + self.subwidget_list['listbox'] = _dummyListbox(self, 'listbox') + self.subwidget_list['vsb'] = _dummyScrollbar(self, 'vsb') + self.subwidget_list['hsb'] = _dummyScrollbar(self, 'hsb') + +class ScrolledText(TixWidget): + """ScrolledText - Text with automatic scrollbars.""" + + # FIXME: It should inherit -superclass tixScrolledWidget + def __init__(self, master, cnf={}, **kw): + TixWidget.__init__(self, master, 'tixScrolledText', ['options'], cnf, kw) + self.subwidget_list['text'] = _dummyText(self, 'text') + self.subwidget_list['vsb'] = _dummyScrollbar(self, 'vsb') + self.subwidget_list['hsb'] = _dummyScrollbar(self, 'hsb') + +class ScrolledTList(TixWidget): + """ScrolledTList - TList with automatic scrollbars.""" + + # FIXME: It should inherit -superclass tixScrolledWidget + def __init__(self, master, cnf={}, **kw): + TixWidget.__init__(self, master, 'tixScrolledTList', ['options'], + cnf, kw) + self.subwidget_list['tlist'] = _dummyTList(self, 'tlist') + self.subwidget_list['vsb'] = _dummyScrollbar(self, 'vsb') + self.subwidget_list['hsb'] = _dummyScrollbar(self, 'hsb') + +class ScrolledWindow(TixWidget): + """ScrolledWindow - Window with automatic scrollbars.""" + + # FIXME: It should inherit -superclass tixScrolledWidget + def __init__(self, master, cnf={}, **kw): + TixWidget.__init__(self, master, 'tixScrolledWindow', ['options'], cnf, kw) + self.subwidget_list['window'] = _dummyFrame(self, 'window') + self.subwidget_list['vsb'] = _dummyScrollbar(self, 'vsb') + self.subwidget_list['hsb'] = _dummyScrollbar(self, 'hsb') + +class Select(TixWidget): + """Select - Container of button subwidgets. It can be used to provide + radio-box or check-box style of selection options for the user. + + Subwidgets are buttons added dynamically using the add method.""" + + # FIXME: It should inherit -superclass tixLabelWidget + def __init__(self, master, cnf={}, **kw): + TixWidget.__init__(self, master, 'tixSelect', + ['allowzero', 'radio', 'orientation', 'labelside', + 'options'], + cnf, kw) + self.subwidget_list['label'] = _dummyLabel(self, 'label') + + def add(self, name, cnf={}, **kw): + self.tk.call(self._w, 'add', name, *self._options(cnf, kw)) + self.subwidget_list[name] = _dummyButton(self, name) + return self.subwidget_list[name] + + def invoke(self, name): + self.tk.call(self._w, 'invoke', name) + +class Shell(TixWidget): + """Toplevel window. + + Subwidgets - None""" + + def __init__ (self,master=None,cnf={}, **kw): + TixWidget.__init__(self, master, 'tixShell', ['options', 'title'], cnf, kw) + +class DialogShell(TixWidget): + """Toplevel window, with popup popdown and center methods. + It tells the window manager that it is a dialog window and should be + treated specially. The exact treatment depends on the treatment of + the window manager. + + Subwidgets - None""" + + # FIXME: It should inherit from Shell + def __init__ (self,master=None,cnf={}, **kw): + TixWidget.__init__(self, master, + 'tixDialogShell', + ['options', 'title', 'mapped', + 'minheight', 'minwidth', + 'parent', 'transient'], cnf, kw) + + def popdown(self): + self.tk.call(self._w, 'popdown') + + def popup(self): + self.tk.call(self._w, 'popup') + + def center(self): + self.tk.call(self._w, 'center') + +class StdButtonBox(TixWidget): + """StdButtonBox - Standard Button Box (OK, Apply, Cancel and Help) """ + + def __init__(self, master=None, cnf={}, **kw): + TixWidget.__init__(self, master, 'tixStdButtonBox', + ['orientation', 'options'], cnf, kw) + self.subwidget_list['ok'] = _dummyButton(self, 'ok') + self.subwidget_list['apply'] = _dummyButton(self, 'apply') + self.subwidget_list['cancel'] = _dummyButton(self, 'cancel') + self.subwidget_list['help'] = _dummyButton(self, 'help') + + def invoke(self, name): + if name in self.subwidget_list: + self.tk.call(self._w, 'invoke', name) + +class TList(TixWidget, XView, YView): + """TList - Hierarchy display widget which can be + used to display data in a tabular format. The list entries of a TList + widget are similar to the entries in the Tk listbox widget. The main + differences are (1) the TList widget can display the list entries in a + two dimensional format and (2) you can use graphical images as well as + multiple colors and fonts for the list entries. + + Subwidgets - None""" + + def __init__ (self,master=None,cnf={}, **kw): + TixWidget.__init__(self, master, 'tixTList', ['options'], cnf, kw) + + def active_set(self, index): + self.tk.call(self._w, 'active', 'set', index) + + def active_clear(self): + self.tk.call(self._w, 'active', 'clear') + + def anchor_set(self, index): + self.tk.call(self._w, 'anchor', 'set', index) + + def anchor_clear(self): + self.tk.call(self._w, 'anchor', 'clear') + + def delete(self, from_, to=None): + self.tk.call(self._w, 'delete', from_, to) + + def dragsite_set(self, index): + self.tk.call(self._w, 'dragsite', 'set', index) + + def dragsite_clear(self): + self.tk.call(self._w, 'dragsite', 'clear') + + def dropsite_set(self, index): + self.tk.call(self._w, 'dropsite', 'set', index) + + def dropsite_clear(self): + self.tk.call(self._w, 'dropsite', 'clear') + + def insert(self, index, cnf={}, **kw): + self.tk.call(self._w, 'insert', index, *self._options(cnf, kw)) + + def info_active(self): + return self.tk.call(self._w, 'info', 'active') + + def info_anchor(self): + return self.tk.call(self._w, 'info', 'anchor') + + def info_down(self, index): + return self.tk.call(self._w, 'info', 'down', index) + + def info_left(self, index): + return self.tk.call(self._w, 'info', 'left', index) + + def info_right(self, index): + return self.tk.call(self._w, 'info', 'right', index) + + def info_selection(self): + c = self.tk.call(self._w, 'info', 'selection') + return self.tk.splitlist(c) + + def info_size(self): + return self.tk.call(self._w, 'info', 'size') + + def info_up(self, index): + return self.tk.call(self._w, 'info', 'up', index) + + def nearest(self, x, y): + return self.tk.call(self._w, 'nearest', x, y) + + def see(self, index): + self.tk.call(self._w, 'see', index) + + def selection_clear(self, cnf={}, **kw): + self.tk.call(self._w, 'selection', 'clear', *self._options(cnf, kw)) + + def selection_includes(self, index): + return self.tk.call(self._w, 'selection', 'includes', index) + + def selection_set(self, first, last=None): + self.tk.call(self._w, 'selection', 'set', first, last) + +class Tree(TixWidget): + """Tree - The tixTree widget can be used to display hierarchical + data in a tree form. The user can adjust + the view of the tree by opening or closing parts of the tree.""" + + # FIXME: It should inherit -superclass tixScrolledWidget + def __init__(self, master=None, cnf={}, **kw): + TixWidget.__init__(self, master, 'tixTree', + ['options'], cnf, kw) + self.subwidget_list['hlist'] = _dummyHList(self, 'hlist') + self.subwidget_list['vsb'] = _dummyScrollbar(self, 'vsb') + self.subwidget_list['hsb'] = _dummyScrollbar(self, 'hsb') + + def autosetmode(self): + '''This command calls the setmode method for all the entries in this + Tree widget: if an entry has no child entries, its mode is set to + none. Otherwise, if the entry has any hidden child entries, its mode is + set to open; otherwise its mode is set to close.''' + self.tk.call(self._w, 'autosetmode') + + def close(self, entrypath): + '''Close the entry given by entryPath if its mode is close.''' + self.tk.call(self._w, 'close', entrypath) + + def getmode(self, entrypath): + '''Returns the current mode of the entry given by entryPath.''' + return self.tk.call(self._w, 'getmode', entrypath) + + def open(self, entrypath): + '''Open the entry given by entryPath if its mode is open.''' + self.tk.call(self._w, 'open', entrypath) + + def setmode(self, entrypath, mode='none'): + '''This command is used to indicate whether the entry given by + entryPath has children entries and whether the children are visible. mode + must be one of open, close or none. If mode is set to open, a (+) + indicator is drawn next to the entry. If mode is set to close, a (-) + indicator is drawn next to the entry. If mode is set to none, no + indicators will be drawn for this entry. The default mode is none. The + open mode indicates the entry has hidden children and this entry can be + opened by the user. The close mode indicates that all the children of the + entry are now visible and the entry can be closed by the user.''' + self.tk.call(self._w, 'setmode', entrypath, mode) + + +# Could try subclassing Tree for CheckList - would need another arg to init +class CheckList(TixWidget): + """The CheckList widget + displays a list of items to be selected by the user. CheckList acts + similarly to the Tk checkbutton or radiobutton widgets, except it is + capable of handling many more items than checkbuttons or radiobuttons. + """ + # FIXME: It should inherit -superclass tixTree + def __init__(self, master=None, cnf={}, **kw): + TixWidget.__init__(self, master, 'tixCheckList', + ['options', 'radio'], cnf, kw) + self.subwidget_list['hlist'] = _dummyHList(self, 'hlist') + self.subwidget_list['vsb'] = _dummyScrollbar(self, 'vsb') + self.subwidget_list['hsb'] = _dummyScrollbar(self, 'hsb') + + def autosetmode(self): + '''This command calls the setmode method for all the entries in this + Tree widget: if an entry has no child entries, its mode is set to + none. Otherwise, if the entry has any hidden child entries, its mode is + set to open; otherwise its mode is set to close.''' + self.tk.call(self._w, 'autosetmode') + + def close(self, entrypath): + '''Close the entry given by entryPath if its mode is close.''' + self.tk.call(self._w, 'close', entrypath) + + def getmode(self, entrypath): + '''Returns the current mode of the entry given by entryPath.''' + return self.tk.call(self._w, 'getmode', entrypath) + + def open(self, entrypath): + '''Open the entry given by entryPath if its mode is open.''' + self.tk.call(self._w, 'open', entrypath) + + def getselection(self, mode='on'): + '''Returns a list of items whose status matches status. If status is + not specified, the list of items in the "on" status will be returned. + Mode can be on, off, default''' + c = self.tk.split(self.tk.call(self._w, 'getselection', mode)) + return self.tk.splitlist(c) + + def getstatus(self, entrypath): + '''Returns the current status of entryPath.''' + return self.tk.call(self._w, 'getstatus', entrypath) + + def setstatus(self, entrypath, mode='on'): + '''Sets the status of entryPath to be status. A bitmap will be + displayed next to the entry its status is on, off or default.''' + self.tk.call(self._w, 'setstatus', entrypath, mode) + + +########################################################################### +### The subclassing below is used to instantiate the subwidgets in each ### +### mega widget. This allows us to access their methods directly. ### +########################################################################### + +class _dummyButton(Button, TixSubWidget): + def __init__(self, master, name, destroy_physically=1): + TixSubWidget.__init__(self, master, name, destroy_physically) + +class _dummyCheckbutton(Checkbutton, TixSubWidget): + def __init__(self, master, name, destroy_physically=1): + TixSubWidget.__init__(self, master, name, destroy_physically) + +class _dummyEntry(Entry, TixSubWidget): + def __init__(self, master, name, destroy_physically=1): + TixSubWidget.__init__(self, master, name, destroy_physically) + +class _dummyFrame(Frame, TixSubWidget): + def __init__(self, master, name, destroy_physically=1): + TixSubWidget.__init__(self, master, name, destroy_physically) + +class _dummyLabel(Label, TixSubWidget): + def __init__(self, master, name, destroy_physically=1): + TixSubWidget.__init__(self, master, name, destroy_physically) + +class _dummyListbox(Listbox, TixSubWidget): + def __init__(self, master, name, destroy_physically=1): + TixSubWidget.__init__(self, master, name, destroy_physically) + +class _dummyMenu(Menu, TixSubWidget): + def __init__(self, master, name, destroy_physically=1): + TixSubWidget.__init__(self, master, name, destroy_physically) + +class _dummyMenubutton(Menubutton, TixSubWidget): + def __init__(self, master, name, destroy_physically=1): + TixSubWidget.__init__(self, master, name, destroy_physically) + +class _dummyScrollbar(Scrollbar, TixSubWidget): + def __init__(self, master, name, destroy_physically=1): + TixSubWidget.__init__(self, master, name, destroy_physically) + +class _dummyText(Text, TixSubWidget): + def __init__(self, master, name, destroy_physically=1): + TixSubWidget.__init__(self, master, name, destroy_physically) + +class _dummyScrolledListBox(ScrolledListBox, TixSubWidget): + def __init__(self, master, name, destroy_physically=1): + TixSubWidget.__init__(self, master, name, destroy_physically) + self.subwidget_list['listbox'] = _dummyListbox(self, 'listbox') + self.subwidget_list['vsb'] = _dummyScrollbar(self, 'vsb') + self.subwidget_list['hsb'] = _dummyScrollbar(self, 'hsb') + +class _dummyHList(HList, TixSubWidget): + def __init__(self, master, name, destroy_physically=1): + TixSubWidget.__init__(self, master, name, destroy_physically) + +class _dummyScrolledHList(ScrolledHList, TixSubWidget): + def __init__(self, master, name, destroy_physically=1): + TixSubWidget.__init__(self, master, name, destroy_physically) + self.subwidget_list['hlist'] = _dummyHList(self, 'hlist') + self.subwidget_list['vsb'] = _dummyScrollbar(self, 'vsb') + self.subwidget_list['hsb'] = _dummyScrollbar(self, 'hsb') + +class _dummyTList(TList, TixSubWidget): + def __init__(self, master, name, destroy_physically=1): + TixSubWidget.__init__(self, master, name, destroy_physically) + +class _dummyComboBox(ComboBox, TixSubWidget): + def __init__(self, master, name, destroy_physically=1): + TixSubWidget.__init__(self, master, name, ['fancy',destroy_physically]) + self.subwidget_list['label'] = _dummyLabel(self, 'label') + self.subwidget_list['entry'] = _dummyEntry(self, 'entry') + self.subwidget_list['arrow'] = _dummyButton(self, 'arrow') + + self.subwidget_list['slistbox'] = _dummyScrolledListBox(self, + 'slistbox') + try: + self.subwidget_list['tick'] = _dummyButton(self, 'tick') + #cross Button : present if created with the fancy option + self.subwidget_list['cross'] = _dummyButton(self, 'cross') + except TypeError: + # unavailable when -fancy not specified + pass + +class _dummyDirList(DirList, TixSubWidget): + def __init__(self, master, name, destroy_physically=1): + TixSubWidget.__init__(self, master, name, destroy_physically) + self.subwidget_list['hlist'] = _dummyHList(self, 'hlist') + self.subwidget_list['vsb'] = _dummyScrollbar(self, 'vsb') + self.subwidget_list['hsb'] = _dummyScrollbar(self, 'hsb') + +class _dummyDirSelectBox(DirSelectBox, TixSubWidget): + def __init__(self, master, name, destroy_physically=1): + TixSubWidget.__init__(self, master, name, destroy_physically) + self.subwidget_list['dirlist'] = _dummyDirList(self, 'dirlist') + self.subwidget_list['dircbx'] = _dummyFileComboBox(self, 'dircbx') + +class _dummyExFileSelectBox(ExFileSelectBox, TixSubWidget): + def __init__(self, master, name, destroy_physically=1): + TixSubWidget.__init__(self, master, name, destroy_physically) + self.subwidget_list['cancel'] = _dummyButton(self, 'cancel') + self.subwidget_list['ok'] = _dummyButton(self, 'ok') + self.subwidget_list['hidden'] = _dummyCheckbutton(self, 'hidden') + self.subwidget_list['types'] = _dummyComboBox(self, 'types') + self.subwidget_list['dir'] = _dummyComboBox(self, 'dir') + self.subwidget_list['dirlist'] = _dummyScrolledListBox(self, 'dirlist') + self.subwidget_list['file'] = _dummyComboBox(self, 'file') + self.subwidget_list['filelist'] = _dummyScrolledListBox(self, 'filelist') + +class _dummyFileSelectBox(FileSelectBox, TixSubWidget): + def __init__(self, master, name, destroy_physically=1): + TixSubWidget.__init__(self, master, name, destroy_physically) + self.subwidget_list['dirlist'] = _dummyScrolledListBox(self, 'dirlist') + self.subwidget_list['filelist'] = _dummyScrolledListBox(self, 'filelist') + self.subwidget_list['filter'] = _dummyComboBox(self, 'filter') + self.subwidget_list['selection'] = _dummyComboBox(self, 'selection') + +class _dummyFileComboBox(ComboBox, TixSubWidget): + def __init__(self, master, name, destroy_physically=1): + TixSubWidget.__init__(self, master, name, destroy_physically) + self.subwidget_list['dircbx'] = _dummyComboBox(self, 'dircbx') + +class _dummyStdButtonBox(StdButtonBox, TixSubWidget): + def __init__(self, master, name, destroy_physically=1): + TixSubWidget.__init__(self, master, name, destroy_physically) + self.subwidget_list['ok'] = _dummyButton(self, 'ok') + self.subwidget_list['apply'] = _dummyButton(self, 'apply') + self.subwidget_list['cancel'] = _dummyButton(self, 'cancel') + self.subwidget_list['help'] = _dummyButton(self, 'help') + +class _dummyNoteBookFrame(NoteBookFrame, TixSubWidget): + def __init__(self, master, name, destroy_physically=0): + TixSubWidget.__init__(self, master, name, destroy_physically) + +class _dummyPanedWindow(PanedWindow, TixSubWidget): + def __init__(self, master, name, destroy_physically=1): + TixSubWidget.__init__(self, master, name, destroy_physically) + +######################## +### Utility Routines ### +######################## + +#mike Should tixDestroy be exposed as a wrapper? - but not for widgets. + +def OptionName(widget): + '''Returns the qualified path name for the widget. Normally used to set + default options for subwidgets. See tixwidgets.py''' + return widget.tk.call('tixOptionName', widget._w) + +# Called with a dictionary argument of the form +# {'*.c':'C source files', '*.txt':'Text Files', '*':'All files'} +# returns a string which can be used to configure the fsbox file types +# in an ExFileSelectBox. i.e., +# '{{*} {* - All files}} {{*.c} {*.c - C source files}} {{*.txt} {*.txt - Text Files}}' +def FileTypeList(dict): + s = '' + for type in dict.keys(): + s = s + '{{' + type + '} {' + type + ' - ' + dict[type] + '}} ' + return s + +# Still to be done: +# tixIconView +class CObjView(TixWidget): + """This file implements the Canvas Object View widget. This is a base + class of IconView. It implements automatic placement/adjustment of the + scrollbars according to the canvas objects inside the canvas subwidget. + The scrollbars are adjusted so that the canvas is just large enough + to see all the objects. + """ + # FIXME: It should inherit -superclass tixScrolledWidget + pass + + +class Grid(TixWidget, XView, YView): + '''The Tix Grid command creates a new window and makes it into a + tixGrid widget. Additional options, may be specified on the command + line or in the option database to configure aspects such as its cursor + and relief. + + A Grid widget displays its contents in a two dimensional grid of cells. + Each cell may contain one Tix display item, which may be in text, + graphics or other formats. See the DisplayStyle class for more information + about Tix display items. Individual cells, or groups of cells, can be + formatted with a wide range of attributes, such as its color, relief and + border. + + Subwidgets - None''' + # valid specific resources as of Tk 8.4 + # editdonecmd, editnotifycmd, floatingcols, floatingrows, formatcmd, + # highlightbackground, highlightcolor, leftmargin, itemtype, selectmode, + # selectunit, topmargin, + def __init__(self, master=None, cnf={}, **kw): + static= [] + self.cnf= cnf + TixWidget.__init__(self, master, 'tixGrid', static, cnf, kw) + + # valid options as of Tk 8.4 + # anchor, bdtype, cget, configure, delete, dragsite, dropsite, entrycget, + # edit, entryconfigure, format, geometryinfo, info, index, move, nearest, + # selection, set, size, unset, xview, yview + def anchor_clear(self): + """Removes the selection anchor.""" + self.tk.call(self, 'anchor', 'clear') + + def anchor_get(self): + "Get the (x,y) coordinate of the current anchor cell" + return self._getints(self.tk.call(self, 'anchor', 'get')) + + def anchor_set(self, x, y): + """Set the selection anchor to the cell at (x, y).""" + self.tk.call(self, 'anchor', 'set', x, y) + + def delete_row(self, from_, to=None): + """Delete rows between from_ and to inclusive. + If to is not provided, delete only row at from_""" + if to is None: + self.tk.call(self, 'delete', 'row', from_) + else: + self.tk.call(self, 'delete', 'row', from_, to) + + def delete_column(self, from_, to=None): + """Delete columns between from_ and to inclusive. + If to is not provided, delete only column at from_""" + if to is None: + self.tk.call(self, 'delete', 'column', from_) + else: + self.tk.call(self, 'delete', 'column', from_, to) + + def edit_apply(self): + """If any cell is being edited, de-highlight the cell and applies + the changes.""" + self.tk.call(self, 'edit', 'apply') + + def edit_set(self, x, y): + """Highlights the cell at (x, y) for editing, if the -editnotify + command returns True for this cell.""" + self.tk.call(self, 'edit', 'set', x, y) + + def entrycget(self, x, y, option): + "Get the option value for cell at (x,y)" + if option and option[0] != '-': + option = '-' + option + return self.tk.call(self, 'entrycget', x, y, option) + + def entryconfigure(self, x, y, cnf=None, **kw): + return self._configure(('entryconfigure', x, y), cnf, kw) + + # def format + # def index + + def info_exists(self, x, y): + "Return True if display item exists at (x,y)" + return self._getboolean(self.tk.call(self, 'info', 'exists', x, y)) + + def info_bbox(self, x, y): + # This seems to always return '', at least for 'text' displayitems + return self.tk.call(self, 'info', 'bbox', x, y) + + def move_column(self, from_, to, offset): + """Moves the range of columns from position FROM through TO by + the distance indicated by OFFSET. For example, move_column(2, 4, 1) + moves the columns 2,3,4 to columns 3,4,5.""" + self.tk.call(self, 'move', 'column', from_, to, offset) + + def move_row(self, from_, to, offset): + """Moves the range of rows from position FROM through TO by + the distance indicated by OFFSET. + For example, move_row(2, 4, 1) moves the rows 2,3,4 to rows 3,4,5.""" + self.tk.call(self, 'move', 'row', from_, to, offset) + + def nearest(self, x, y): + "Return coordinate of cell nearest pixel coordinate (x,y)" + return self._getints(self.tk.call(self, 'nearest', x, y)) + + # def selection adjust + # def selection clear + # def selection includes + # def selection set + # def selection toggle + + def set(self, x, y, itemtype=None, **kw): + args= self._options(self.cnf, kw) + if itemtype is not None: + args= ('-itemtype', itemtype) + args + self.tk.call(self, 'set', x, y, *args) + + def size_column(self, index, **kw): + """Queries or sets the size of the column given by + INDEX. INDEX may be any non-negative + integer that gives the position of a given column. + INDEX can also be the string "default"; in this case, this command + queries or sets the default size of all columns. + When no option-value pair is given, this command returns a tuple + containing the current size setting of the given column. When + option-value pairs are given, the corresponding options of the + size setting of the given column are changed. Options may be one + of the follwing: + pad0 pixels + Specifies the paddings to the left of a column. + pad1 pixels + Specifies the paddings to the right of a column. + size val + Specifies the width of a column. Val may be: + "auto" -- the width of the column is set to the + width of the widest cell in the column; + a valid Tk screen distance unit; + or a real number following by the word chars + (e.g. 3.4chars) that sets the width of the column to the + given number of characters.""" + return self.tk.split(self.tk.call(self._w, 'size', 'column', index, + *self._options({}, kw))) + + def size_row(self, index, **kw): + """Queries or sets the size of the row given by + INDEX. INDEX may be any non-negative + integer that gives the position of a given row . + INDEX can also be the string "default"; in this case, this command + queries or sets the default size of all rows. + When no option-value pair is given, this command returns a list con- + taining the current size setting of the given row . When option-value + pairs are given, the corresponding options of the size setting of the + given row are changed. Options may be one of the follwing: + pad0 pixels + Specifies the paddings to the top of a row. + pad1 pixels + Specifies the paddings to the bottom of a row. + size val + Specifies the height of a row. Val may be: + "auto" -- the height of the row is set to the + height of the highest cell in the row; + a valid Tk screen distance unit; + or a real number following by the word chars + (e.g. 3.4chars) that sets the height of the row to the + given number of characters.""" + return self.tk.split(self.tk.call( + self, 'size', 'row', index, *self._options({}, kw))) + + def unset(self, x, y): + """Clears the cell at (x, y) by removing its display item.""" + self.tk.call(self._w, 'unset', x, y) + + +class ScrolledGrid(Grid): + '''Scrolled Grid widgets''' + + # FIXME: It should inherit -superclass tixScrolledWidget + def __init__(self, master=None, cnf={}, **kw): + static= [] + self.cnf= cnf + TixWidget.__init__(self, master, 'tixScrolledGrid', static, cnf, kw) diff --git a/PythonHome/Lib/lib-tk/Tix.pyc b/PythonHome/Lib/lib-tk/Tix.pyc deleted file mode 100644 index 2642bd6c400fdff68d41e5c9a7416c8cc76ce0e3..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 91067 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 to a callback function that you write. The function +should call Tkdnd.dnd_start(source, event), where 'source' is the +object to be dragged, and 'event' is the event that invoked the call +(the argument to your callback function). Even though this is a class +instantiation, the returned instance should not be stored -- it will +be kept alive automatically for the duration of the drag-and-drop. + +When a drag-and-drop is already in process for the Tk interpreter, the +call is *ignored*; this normally averts starting multiple simultaneous +dnd processes, e.g. because different button callbacks all +dnd_start(). + +The object is *not* necessarily a widget -- it can be any +application-specific object that is meaningful to potential +drag-and-drop targets. + +Potential drag-and-drop targets are discovered as follows. Whenever +the mouse moves, and at the start and end of a drag-and-drop move, the +Tk widget directly under the mouse is inspected. This is the target +widget (not to be confused with the target object, yet to be +determined). If there is no target widget, there is no dnd target +object. If there is a target widget, and it has an attribute +dnd_accept, this should be a function (or any callable object). The +function is called as dnd_accept(source, event), where 'source' is the +object being dragged (the object passed to dnd_start() above), and +'event' is the most recent event object (generally a event; +it can also be or ). If the dnd_accept() +function returns something other than None, this is the new dnd target +object. If dnd_accept() returns None, or if the target widget has no +dnd_accept attribute, the target widget's parent is considered as the +target widget, and the search for a target object is repeated from +there. If necessary, the search is repeated all the way up to the +root widget. If none of the target widgets can produce a target +object, there is no target object (the target object is None). + +The target object thus produced, if any, is called the new target +object. It is compared with the old target object (or None, if there +was no old target widget). There are several cases ('source' is the +source object, and 'event' is the most recent event object): + +- Both the old and new target objects are None. Nothing happens. + +- The old and new target objects are the same object. Its method +dnd_motion(source, event) is called. + +- The old target object was None, and the new target object is not +None. The new target object's method dnd_enter(source, event) is +called. + +- The new target object is None, and the old target object is not +None. The old target object's method dnd_leave(source, event) is +called. + +- The old and new target objects differ and neither is None. The old +target object's method dnd_leave(source, event), and then the new +target object's method dnd_enter(source, event) is called. + +Once this is done, the new target object replaces the old one, and the +Tk mainloop proceeds. The return value of the methods mentioned above +is ignored; if they raise an exception, the normal exception handling +mechanisms take over. + +The drag-and-drop processes can end in two ways: a final target object +is selected, or no final target object is selected. When a final +target object is selected, it will always have been notified of the +potential drop by a call to its dnd_enter() method, as described +above, and possibly one or more calls to its dnd_motion() method; its +dnd_leave() method has not been called since the last call to +dnd_enter(). The target is notified of the drop by a call to its +method dnd_commit(source, event). + +If no final target object is selected, and there was an old target +object, its dnd_leave(source, event) method is called to complete the +dnd sequence. + +Finally, the source object is notified that the drag-and-drop process +is over, by a call to source.dnd_end(target, event), specifying either +the selected target object, or None if no target object was selected. +The source object can use this to implement the commit action; this is +sometimes simpler than to do it in the target's dnd_commit(). The +target's dnd_commit() method could then simply be aliased to +dnd_leave(). + +At any time during a dnd sequence, the application can cancel the +sequence by calling the cancel() method on the object returned by +dnd_start(). This will call dnd_leave() if a target is currently +active; it will never call dnd_commit(). + +""" + + +import Tkinter + + +# The factory function + +def dnd_start(source, event): + h = DndHandler(source, event) + if h.root: + return h + else: + return None + + +# The class that does the work + +class DndHandler: + + root = None + + def __init__(self, source, event): + if event.num > 5: + return + root = event.widget._root() + try: + root.__dnd + return # Don't start recursive dnd + except AttributeError: + root.__dnd = self + self.root = root + self.source = source + self.target = None + self.initial_button = button = event.num + self.initial_widget = widget = event.widget + self.release_pattern = "" % (button, button) + self.save_cursor = widget['cursor'] or "" + widget.bind(self.release_pattern, self.on_release) + widget.bind("", self.on_motion) + widget['cursor'] = "hand2" + + def __del__(self): + root = self.root + self.root = None + if root: + try: + del root.__dnd + except AttributeError: + pass + + def on_motion(self, event): + x, y = event.x_root, event.y_root + target_widget = self.initial_widget.winfo_containing(x, y) + source = self.source + new_target = None + while target_widget: + try: + attr = target_widget.dnd_accept + except AttributeError: + pass + else: + new_target = attr(source, event) + if new_target: + break + target_widget = target_widget.master + old_target = self.target + if old_target is new_target: + if old_target: + old_target.dnd_motion(source, event) + else: + if old_target: + self.target = None + old_target.dnd_leave(source, event) + if new_target: + new_target.dnd_enter(source, event) + self.target = new_target + + def on_release(self, event): + self.finish(event, 1) + + def cancel(self, event=None): + self.finish(event, 0) + + def finish(self, event, commit=0): + target = self.target + source = self.source + widget = self.initial_widget + root = self.root + try: + del root.__dnd + self.initial_widget.unbind(self.release_pattern) + self.initial_widget.unbind("") + widget['cursor'] = self.save_cursor + self.target = self.source = self.initial_widget = self.root = None + if target: + if commit: + target.dnd_commit(source, event) + else: + target.dnd_leave(source, event) + finally: + source.dnd_end(target, event) + + + +# ---------------------------------------------------------------------- +# The rest is here for testing and demonstration purposes only! + +class Icon: + + def __init__(self, name): + self.name = name + self.canvas = self.label = self.id = None + + def attach(self, canvas, x=10, y=10): + if canvas is self.canvas: + self.canvas.coords(self.id, x, y) + return + if self.canvas: + self.detach() + if not canvas: + return + label = Tkinter.Label(canvas, text=self.name, + borderwidth=2, relief="raised") + id = canvas.create_window(x, y, window=label, anchor="nw") + self.canvas = canvas + self.label = label + self.id = id + label.bind("", self.press) + + def detach(self): + canvas = self.canvas + if not canvas: + return + id = self.id + label = self.label + self.canvas = self.label = self.id = None + canvas.delete(id) + label.destroy() + + def press(self, event): + if dnd_start(self, event): + # where the pointer is relative to the label widget: + self.x_off = event.x + self.y_off = event.y + # where the widget is relative to the canvas: + self.x_orig, self.y_orig = self.canvas.coords(self.id) + + def move(self, event): + x, y = self.where(self.canvas, event) + self.canvas.coords(self.id, x, y) + + def putback(self): + self.canvas.coords(self.id, self.x_orig, self.y_orig) + + def where(self, canvas, event): + # where the corner of the canvas is relative to the screen: + x_org = canvas.winfo_rootx() + y_org = canvas.winfo_rooty() + # where the pointer is relative to the canvas widget: + x = event.x_root - x_org + y = event.y_root - y_org + # compensate for initial pointer offset + return x - self.x_off, y - self.y_off + + def dnd_end(self, target, event): + pass + +class Tester: + + def __init__(self, root): + self.top = Tkinter.Toplevel(root) + self.canvas = Tkinter.Canvas(self.top, width=100, height=100) + self.canvas.pack(fill="both", expand=1) + self.canvas.dnd_accept = self.dnd_accept + + def dnd_accept(self, source, event): + return self + + def dnd_enter(self, source, event): + self.canvas.focus_set() # Show highlight border + x, y = source.where(self.canvas, event) + x1, y1, x2, y2 = source.canvas.bbox(source.id) + dx, dy = x2-x1, y2-y1 + self.dndid = self.canvas.create_rectangle(x, y, x+dx, y+dy) + self.dnd_motion(source, event) + + def dnd_motion(self, source, event): + x, y = source.where(self.canvas, event) + x1, y1, x2, y2 = self.canvas.bbox(self.dndid) + self.canvas.move(self.dndid, x-x1, y-y1) + + def dnd_leave(self, source, event): + self.top.focus_set() # Hide highlight border + self.canvas.delete(self.dndid) + self.dndid = None + + def dnd_commit(self, source, event): + self.dnd_leave(source, event) + x, y = source.where(self.canvas, event) + source.attach(self.canvas, x, y) + +def test(): + root = Tkinter.Tk() + root.geometry("+1+1") + Tkinter.Button(command=root.quit, text="Quit").pack() + t1 = Tester(root) + t1.top.geometry("+1+60") + t2 = Tester(root) + t2.top.geometry("+120+60") + t3 = Tester(root) + t3.top.geometry("+240+60") + i1 = Icon("ICON1") + i2 = Icon("ICON2") + i3 = Icon("ICON3") + i1.attach(t1.canvas) + i2.attach(t2.canvas) + i3.attach(t3.canvas) + root.mainloop() + +if __name__ == '__main__': + test() diff --git a/PythonHome/Lib/lib-tk/Tkdnd.pyc b/PythonHome/Lib/lib-tk/Tkdnd.pyc deleted file mode 100644 index c50d19a10d1164b5802faa98c98a25db86f1fc6d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 12435 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 J@4U3$_&>(VdA9%n diff --git a/PythonHome/Lib/lib-tk/Tkinter.py b/PythonHome/Lib/lib-tk/Tkinter.py new file mode 100644 index 0000000000..d3d7d83959 --- /dev/null +++ b/PythonHome/Lib/lib-tk/Tkinter.py @@ -0,0 +1,3809 @@ +"""Wrapper functions for Tcl/Tk. + +Tkinter provides classes which allow the display, positioning and +control of widgets. Toplevel widgets are Tk and Toplevel. Other +widgets are Frame, Label, Entry, Text, Canvas, Button, Radiobutton, +Checkbutton, Scale, Listbox, Scrollbar, OptionMenu, Spinbox +LabelFrame and PanedWindow. + +Properties of the widgets are specified with keyword arguments. +Keyword arguments have the same name as the corresponding resource +under Tk. + +Widgets are positioned with one of the geometry managers Place, Pack +or Grid. These managers can be called with methods place, pack, grid +available in every Widget. + +Actions are bound to events by resources (e.g. keyword argument +command) or with the method bind. + +Example (Hello, World): +import Tkinter +from Tkconstants import * +tk = Tkinter.Tk() +frame = Tkinter.Frame(tk, relief=RIDGE, borderwidth=2) +frame.pack(fill=BOTH,expand=1) +label = Tkinter.Label(frame, text="Hello, World") +label.pack(fill=X, expand=1) +button = Tkinter.Button(frame,text="Exit",command=tk.destroy) +button.pack(side=BOTTOM) +tk.mainloop() +""" + +__version__ = "$Revision: 81008 $" + +import sys +if sys.platform == "win32": + # Attempt to configure Tcl/Tk without requiring PATH + import FixTk +import _tkinter # If this fails your Python may not be configured for Tk +tkinter = _tkinter # b/w compat for export +TclError = _tkinter.TclError +from types import * +from Tkconstants import * +import re + +wantobjects = 1 + +TkVersion = float(_tkinter.TK_VERSION) +TclVersion = float(_tkinter.TCL_VERSION) + +READABLE = _tkinter.READABLE +WRITABLE = _tkinter.WRITABLE +EXCEPTION = _tkinter.EXCEPTION + +# These are not always defined, e.g. not on Win32 with Tk 8.0 :-( +try: _tkinter.createfilehandler +except AttributeError: _tkinter.createfilehandler = None +try: _tkinter.deletefilehandler +except AttributeError: _tkinter.deletefilehandler = None + + +_magic_re = re.compile(r'([\\{}])') +_space_re = re.compile(r'([\s])') + +def _join(value): + """Internal function.""" + return ' '.join(map(_stringify, value)) + +def _stringify(value): + """Internal function.""" + if isinstance(value, (list, tuple)): + if len(value) == 1: + value = _stringify(value[0]) + if value[0] == '{': + value = '{%s}' % value + else: + value = '{%s}' % _join(value) + else: + if isinstance(value, str): + value = unicode(value, 'utf-8') + elif not isinstance(value, unicode): + value = str(value) + if not value: + value = '{}' + elif _magic_re.search(value): + # add '\' before special characters and spaces + value = _magic_re.sub(r'\\\1', value) + value = _space_re.sub(r'\\\1', value) + elif value[0] == '"' or _space_re.search(value): + value = '{%s}' % value + return value + +def _flatten(tuple): + """Internal function.""" + res = () + for item in tuple: + if type(item) in (TupleType, ListType): + res = res + _flatten(item) + elif item is not None: + res = res + (item,) + return res + +try: _flatten = _tkinter._flatten +except AttributeError: pass + +def _cnfmerge(cnfs): + """Internal function.""" + if type(cnfs) is DictionaryType: + return cnfs + elif type(cnfs) in (NoneType, StringType): + return cnfs + else: + cnf = {} + for c in _flatten(cnfs): + try: + cnf.update(c) + except (AttributeError, TypeError), msg: + print "_cnfmerge: fallback due to:", msg + for k, v in c.items(): + cnf[k] = v + return cnf + +try: _cnfmerge = _tkinter._cnfmerge +except AttributeError: pass + +class Event: + """Container for the properties of an event. + + Instances of this type are generated if one of the following events occurs: + + KeyPress, KeyRelease - for keyboard events + ButtonPress, ButtonRelease, Motion, Enter, Leave, MouseWheel - for mouse events + Visibility, Unmap, Map, Expose, FocusIn, FocusOut, Circulate, + Colormap, Gravity, Reparent, Property, Destroy, Activate, + Deactivate - for window events. + + If a callback function for one of these events is registered + using bind, bind_all, bind_class, or tag_bind, the callback is + called with an Event as first argument. It will have the + following attributes (in braces are the event types for which + the attribute is valid): + + serial - serial number of event + num - mouse button pressed (ButtonPress, ButtonRelease) + focus - whether the window has the focus (Enter, Leave) + height - height of the exposed window (Configure, Expose) + width - width of the exposed window (Configure, Expose) + keycode - keycode of the pressed key (KeyPress, KeyRelease) + state - state of the event as a number (ButtonPress, ButtonRelease, + Enter, KeyPress, KeyRelease, + Leave, Motion) + state - state as a string (Visibility) + time - when the event occurred + x - x-position of the mouse + y - y-position of the mouse + x_root - x-position of the mouse on the screen + (ButtonPress, ButtonRelease, KeyPress, KeyRelease, Motion) + y_root - y-position of the mouse on the screen + (ButtonPress, ButtonRelease, KeyPress, KeyRelease, Motion) + char - pressed character (KeyPress, KeyRelease) + send_event - see X/Windows documentation + keysym - keysym of the event as a string (KeyPress, KeyRelease) + keysym_num - keysym of the event as a number (KeyPress, KeyRelease) + type - type of the event as a number + widget - widget in which the event occurred + delta - delta of wheel movement (MouseWheel) + """ + pass + +_support_default_root = 1 +_default_root = None + +def NoDefaultRoot(): + """Inhibit setting of default root window. + + Call this function to inhibit that the first instance of + Tk is used for windows without an explicit parent window. + """ + global _support_default_root + _support_default_root = 0 + global _default_root + _default_root = None + del _default_root + +def _tkerror(err): + """Internal function.""" + pass + +def _exit(code=0): + """Internal function. Calling it will raise the exception SystemExit.""" + try: + code = int(code) + except ValueError: + pass + raise SystemExit, code + +_varnum = 0 +class Variable: + """Class to define value holders for e.g. buttons. + + Subclasses StringVar, IntVar, DoubleVar, BooleanVar are specializations + that constrain the type of the value returned from get().""" + _default = "" + def __init__(self, master=None, value=None, name=None): + """Construct a variable + + MASTER can be given as master widget. + VALUE is an optional value (defaults to "") + NAME is an optional Tcl name (defaults to PY_VARnum). + + If NAME matches an existing variable and VALUE is omitted + then the existing value is retained. + """ + global _varnum + if not master: + master = _default_root + self._master = master + self._tk = master.tk + if name: + self._name = name + else: + self._name = 'PY_VAR' + repr(_varnum) + _varnum += 1 + if value is not None: + self.set(value) + elif not self._tk.getboolean(self._tk.call("info", "exists", self._name)): + self.set(self._default) + def __del__(self): + """Unset the variable in Tcl.""" + if (self._tk is not None and + self._tk.getboolean(self._tk.call("info", "exists", self._name))): + self._tk.globalunsetvar(self._name) + def __str__(self): + """Return the name of the variable in Tcl.""" + return self._name + def set(self, value): + """Set the variable to VALUE.""" + return self._tk.globalsetvar(self._name, value) + def get(self): + """Return value of variable.""" + return self._tk.globalgetvar(self._name) + def trace_variable(self, mode, callback): + """Define a trace callback for the variable. + + MODE is one of "r", "w", "u" for read, write, undefine. + CALLBACK must be a function which is called when + the variable is read, written or undefined. + + Return the name of the callback. + """ + cbname = self._master._register(callback) + self._tk.call("trace", "variable", self._name, mode, cbname) + return cbname + trace = trace_variable + def trace_vdelete(self, mode, cbname): + """Delete the trace callback for a variable. + + MODE is one of "r", "w", "u" for read, write, undefine. + CBNAME is the name of the callback returned from trace_variable or trace. + """ + self._tk.call("trace", "vdelete", self._name, mode, cbname) + self._master.deletecommand(cbname) + def trace_vinfo(self): + """Return all trace callback information.""" + return map(self._tk.split, self._tk.splitlist( + self._tk.call("trace", "vinfo", self._name))) + def __eq__(self, other): + """Comparison for equality (==). + + Note: if the Variable's master matters to behavior + also compare self._master == other._master + """ + return self.__class__.__name__ == other.__class__.__name__ \ + and self._name == other._name + +class StringVar(Variable): + """Value holder for strings variables.""" + _default = "" + def __init__(self, master=None, value=None, name=None): + """Construct a string variable. + + MASTER can be given as master widget. + VALUE is an optional value (defaults to "") + NAME is an optional Tcl name (defaults to PY_VARnum). + + If NAME matches an existing variable and VALUE is omitted + then the existing value is retained. + """ + Variable.__init__(self, master, value, name) + + def get(self): + """Return value of variable as string.""" + value = self._tk.globalgetvar(self._name) + if isinstance(value, basestring): + return value + return str(value) + +class IntVar(Variable): + """Value holder for integer variables.""" + _default = 0 + def __init__(self, master=None, value=None, name=None): + """Construct an integer variable. + + MASTER can be given as master widget. + VALUE is an optional value (defaults to 0) + NAME is an optional Tcl name (defaults to PY_VARnum). + + If NAME matches an existing variable and VALUE is omitted + then the existing value is retained. + """ + Variable.__init__(self, master, value, name) + + def set(self, value): + """Set the variable to value, converting booleans to integers.""" + if isinstance(value, bool): + value = int(value) + return Variable.set(self, value) + + def get(self): + """Return the value of the variable as an integer.""" + return getint(self._tk.globalgetvar(self._name)) + +class DoubleVar(Variable): + """Value holder for float variables.""" + _default = 0.0 + def __init__(self, master=None, value=None, name=None): + """Construct a float variable. + + MASTER can be given as master widget. + VALUE is an optional value (defaults to 0.0) + NAME is an optional Tcl name (defaults to PY_VARnum). + + If NAME matches an existing variable and VALUE is omitted + then the existing value is retained. + """ + Variable.__init__(self, master, value, name) + + def get(self): + """Return the value of the variable as a float.""" + return getdouble(self._tk.globalgetvar(self._name)) + +class BooleanVar(Variable): + """Value holder for boolean variables.""" + _default = False + def __init__(self, master=None, value=None, name=None): + """Construct a boolean variable. + + MASTER can be given as master widget. + VALUE is an optional value (defaults to False) + NAME is an optional Tcl name (defaults to PY_VARnum). + + If NAME matches an existing variable and VALUE is omitted + then the existing value is retained. + """ + Variable.__init__(self, master, value, name) + + def get(self): + """Return the value of the variable as a bool.""" + return self._tk.getboolean(self._tk.globalgetvar(self._name)) + +def mainloop(n=0): + """Run the main loop of Tcl.""" + _default_root.tk.mainloop(n) + +getint = int + +getdouble = float + +def getboolean(s): + """Convert true and false to integer values 1 and 0.""" + return _default_root.tk.getboolean(s) + +# Methods defined on both toplevel and interior widgets +class Misc: + """Internal class. + + Base class which defines methods common for interior widgets.""" + + # XXX font command? + _tclCommands = None + def destroy(self): + """Internal function. + + Delete all Tcl commands created for + this widget in the Tcl interpreter.""" + if self._tclCommands is not None: + for name in self._tclCommands: + #print '- Tkinter: deleted command', name + self.tk.deletecommand(name) + self._tclCommands = None + def deletecommand(self, name): + """Internal function. + + Delete the Tcl command provided in NAME.""" + #print '- Tkinter: deleted command', name + self.tk.deletecommand(name) + try: + self._tclCommands.remove(name) + except ValueError: + pass + def tk_strictMotif(self, boolean=None): + """Set Tcl internal variable, whether the look and feel + should adhere to Motif. + + A parameter of 1 means adhere to Motif (e.g. no color + change if mouse passes over slider). + Returns the set value.""" + return self.tk.getboolean(self.tk.call( + 'set', 'tk_strictMotif', boolean)) + def tk_bisque(self): + """Change the color scheme to light brown as used in Tk 3.6 and before.""" + self.tk.call('tk_bisque') + def tk_setPalette(self, *args, **kw): + """Set a new color scheme for all widget elements. + + A single color as argument will cause that all colors of Tk + widget elements are derived from this. + Alternatively several keyword parameters and its associated + colors can be given. The following keywords are valid: + activeBackground, foreground, selectColor, + activeForeground, highlightBackground, selectBackground, + background, highlightColor, selectForeground, + disabledForeground, insertBackground, troughColor.""" + self.tk.call(('tk_setPalette',) + + _flatten(args) + _flatten(kw.items())) + def tk_menuBar(self, *args): + """Do not use. Needed in Tk 3.6 and earlier.""" + pass # obsolete since Tk 4.0 + def wait_variable(self, name='PY_VAR'): + """Wait until the variable is modified. + + A parameter of type IntVar, StringVar, DoubleVar or + BooleanVar must be given.""" + self.tk.call('tkwait', 'variable', name) + waitvar = wait_variable # XXX b/w compat + def wait_window(self, window=None): + """Wait until a WIDGET is destroyed. + + If no parameter is given self is used.""" + if window is None: + window = self + self.tk.call('tkwait', 'window', window._w) + def wait_visibility(self, window=None): + """Wait until the visibility of a WIDGET changes + (e.g. it appears). + + If no parameter is given self is used.""" + if window is None: + window = self + self.tk.call('tkwait', 'visibility', window._w) + def setvar(self, name='PY_VAR', value='1'): + """Set Tcl variable NAME to VALUE.""" + self.tk.setvar(name, value) + def getvar(self, name='PY_VAR'): + """Return value of Tcl variable NAME.""" + return self.tk.getvar(name) + getint = int + getdouble = float + def getboolean(self, s): + """Return a boolean value for Tcl boolean values true and false given as parameter.""" + return self.tk.getboolean(s) + def focus_set(self): + """Direct input focus to this widget. + + If the application currently does not have the focus + this widget will get the focus if the application gets + the focus through the window manager.""" + self.tk.call('focus', self._w) + focus = focus_set # XXX b/w compat? + def focus_force(self): + """Direct input focus to this widget even if the + application does not have the focus. Use with + caution!""" + self.tk.call('focus', '-force', self._w) + def focus_get(self): + """Return the widget which has currently the focus in the + application. + + Use focus_displayof to allow working with several + displays. Return None if application does not have + the focus.""" + name = self.tk.call('focus') + if name == 'none' or not name: return None + return self._nametowidget(name) + def focus_displayof(self): + """Return the widget which has currently the focus on the + display where this widget is located. + + Return None if the application does not have the focus.""" + name = self.tk.call('focus', '-displayof', self._w) + if name == 'none' or not name: return None + return self._nametowidget(name) + def focus_lastfor(self): + """Return the widget which would have the focus if top level + for this widget gets the focus from the window manager.""" + name = self.tk.call('focus', '-lastfor', self._w) + if name == 'none' or not name: return None + return self._nametowidget(name) + def tk_focusFollowsMouse(self): + """The widget under mouse will get automatically focus. Can not + be disabled easily.""" + self.tk.call('tk_focusFollowsMouse') + def tk_focusNext(self): + """Return the next widget in the focus order which follows + widget which has currently the focus. + + The focus order first goes to the next child, then to + the children of the child recursively and then to the + next sibling which is higher in the stacking order. A + widget is omitted if it has the takefocus resource set + to 0.""" + name = self.tk.call('tk_focusNext', self._w) + if not name: return None + return self._nametowidget(name) + def tk_focusPrev(self): + """Return previous widget in the focus order. See tk_focusNext for details.""" + name = self.tk.call('tk_focusPrev', self._w) + if not name: return None + return self._nametowidget(name) + def after(self, ms, func=None, *args): + """Call function once after given time. + + MS specifies the time in milliseconds. FUNC gives the + function which shall be called. Additional parameters + are given as parameters to the function call. Return + identifier to cancel scheduling with after_cancel.""" + if not func: + # I'd rather use time.sleep(ms*0.001) + self.tk.call('after', ms) + else: + def callit(): + try: + func(*args) + finally: + try: + self.deletecommand(name) + except TclError: + pass + name = self._register(callit) + return self.tk.call('after', ms, name) + def after_idle(self, func, *args): + """Call FUNC once if the Tcl main loop has no event to + process. + + Return an identifier to cancel the scheduling with + after_cancel.""" + return self.after('idle', func, *args) + def after_cancel(self, id): + """Cancel scheduling of function identified with ID. + + Identifier returned by after or after_idle must be + given as first parameter.""" + try: + data = self.tk.call('after', 'info', id) + # In Tk 8.3, splitlist returns: (script, type) + # In Tk 8.4, splitlist may return (script, type) or (script,) + script = self.tk.splitlist(data)[0] + self.deletecommand(script) + except TclError: + pass + self.tk.call('after', 'cancel', id) + def bell(self, displayof=0): + """Ring a display's bell.""" + self.tk.call(('bell',) + self._displayof(displayof)) + + # Clipboard handling: + def clipboard_get(self, **kw): + """Retrieve data from the clipboard on window's display. + + The window keyword defaults to the root window of the Tkinter + application. + + The type keyword specifies the form in which the data is + to be returned and should be an atom name such as STRING + or FILE_NAME. Type defaults to STRING, except on X11, where the default + is to try UTF8_STRING and fall back to STRING. + + This command is equivalent to: + + selection_get(CLIPBOARD) + """ + if 'type' not in kw and self._windowingsystem == 'x11': + try: + kw['type'] = 'UTF8_STRING' + return self.tk.call(('clipboard', 'get') + self._options(kw)) + except TclError: + del kw['type'] + return self.tk.call(('clipboard', 'get') + self._options(kw)) + + def clipboard_clear(self, **kw): + """Clear the data in the Tk clipboard. + + A widget specified for the optional displayof keyword + argument specifies the target display.""" + if 'displayof' not in kw: kw['displayof'] = self._w + self.tk.call(('clipboard', 'clear') + self._options(kw)) + def clipboard_append(self, string, **kw): + """Append STRING to the Tk clipboard. + + A widget specified at the optional displayof keyword + argument specifies the target display. The clipboard + can be retrieved with selection_get.""" + if 'displayof' not in kw: kw['displayof'] = self._w + self.tk.call(('clipboard', 'append') + self._options(kw) + + ('--', string)) + # XXX grab current w/o window argument + def grab_current(self): + """Return widget which has currently the grab in this application + or None.""" + name = self.tk.call('grab', 'current', self._w) + if not name: return None + return self._nametowidget(name) + def grab_release(self): + """Release grab for this widget if currently set.""" + self.tk.call('grab', 'release', self._w) + def grab_set(self): + """Set grab for this widget. + + A grab directs all events to this and descendant + widgets in the application.""" + self.tk.call('grab', 'set', self._w) + def grab_set_global(self): + """Set global grab for this widget. + + A global grab directs all events to this and + descendant widgets on the display. Use with caution - + other applications do not get events anymore.""" + self.tk.call('grab', 'set', '-global', self._w) + def grab_status(self): + """Return None, "local" or "global" if this widget has + no, a local or a global grab.""" + status = self.tk.call('grab', 'status', self._w) + if status == 'none': status = None + return status + def option_add(self, pattern, value, priority = None): + """Set a VALUE (second parameter) for an option + PATTERN (first parameter). + + An optional third parameter gives the numeric priority + (defaults to 80).""" + self.tk.call('option', 'add', pattern, value, priority) + def option_clear(self): + """Clear the option database. + + It will be reloaded if option_add is called.""" + self.tk.call('option', 'clear') + def option_get(self, name, className): + """Return the value for an option NAME for this widget + with CLASSNAME. + + Values with higher priority override lower values.""" + return self.tk.call('option', 'get', self._w, name, className) + def option_readfile(self, fileName, priority = None): + """Read file FILENAME into the option database. + + An optional second parameter gives the numeric + priority.""" + self.tk.call('option', 'readfile', fileName, priority) + def selection_clear(self, **kw): + """Clear the current X selection.""" + if 'displayof' not in kw: kw['displayof'] = self._w + self.tk.call(('selection', 'clear') + self._options(kw)) + def selection_get(self, **kw): + """Return the contents of the current X selection. + + A keyword parameter selection specifies the name of + the selection and defaults to PRIMARY. A keyword + parameter displayof specifies a widget on the display + to use. A keyword parameter type specifies the form of data to be + fetched, defaulting to STRING except on X11, where UTF8_STRING is tried + before STRING.""" + if 'displayof' not in kw: kw['displayof'] = self._w + if 'type' not in kw and self._windowingsystem == 'x11': + try: + kw['type'] = 'UTF8_STRING' + return self.tk.call(('selection', 'get') + self._options(kw)) + except TclError: + del kw['type'] + return self.tk.call(('selection', 'get') + self._options(kw)) + def selection_handle(self, command, **kw): + """Specify a function COMMAND to call if the X + selection owned by this widget is queried by another + application. + + This function must return the contents of the + selection. The function will be called with the + arguments OFFSET and LENGTH which allows the chunking + of very long selections. The following keyword + parameters can be provided: + selection - name of the selection (default PRIMARY), + type - type of the selection (e.g. STRING, FILE_NAME).""" + name = self._register(command) + self.tk.call(('selection', 'handle') + self._options(kw) + + (self._w, name)) + def selection_own(self, **kw): + """Become owner of X selection. + + A keyword parameter selection specifies the name of + the selection (default PRIMARY).""" + self.tk.call(('selection', 'own') + + self._options(kw) + (self._w,)) + def selection_own_get(self, **kw): + """Return owner of X selection. + + The following keyword parameter can + be provided: + selection - name of the selection (default PRIMARY), + type - type of the selection (e.g. STRING, FILE_NAME).""" + if 'displayof' not in kw: kw['displayof'] = self._w + name = self.tk.call(('selection', 'own') + self._options(kw)) + if not name: return None + return self._nametowidget(name) + def send(self, interp, cmd, *args): + """Send Tcl command CMD to different interpreter INTERP to be executed.""" + return self.tk.call(('send', interp, cmd) + args) + def lower(self, belowThis=None): + """Lower this widget in the stacking order.""" + self.tk.call('lower', self._w, belowThis) + def tkraise(self, aboveThis=None): + """Raise this widget in the stacking order.""" + self.tk.call('raise', self._w, aboveThis) + lift = tkraise + def colormodel(self, value=None): + """Useless. Not implemented in Tk.""" + return self.tk.call('tk', 'colormodel', self._w, value) + def winfo_atom(self, name, displayof=0): + """Return integer which represents atom NAME.""" + args = ('winfo', 'atom') + self._displayof(displayof) + (name,) + return getint(self.tk.call(args)) + def winfo_atomname(self, id, displayof=0): + """Return name of atom with identifier ID.""" + args = ('winfo', 'atomname') \ + + self._displayof(displayof) + (id,) + return self.tk.call(args) + def winfo_cells(self): + """Return number of cells in the colormap for this widget.""" + return getint( + self.tk.call('winfo', 'cells', self._w)) + def winfo_children(self): + """Return a list of all widgets which are children of this widget.""" + result = [] + for child in self.tk.splitlist( + self.tk.call('winfo', 'children', self._w)): + try: + # Tcl sometimes returns extra windows, e.g. for + # menus; those need to be skipped + result.append(self._nametowidget(child)) + except KeyError: + pass + return result + + def winfo_class(self): + """Return window class name of this widget.""" + return self.tk.call('winfo', 'class', self._w) + def winfo_colormapfull(self): + """Return true if at the last color request the colormap was full.""" + return self.tk.getboolean( + self.tk.call('winfo', 'colormapfull', self._w)) + def winfo_containing(self, rootX, rootY, displayof=0): + """Return the widget which is at the root coordinates ROOTX, ROOTY.""" + args = ('winfo', 'containing') \ + + self._displayof(displayof) + (rootX, rootY) + name = self.tk.call(args) + if not name: return None + return self._nametowidget(name) + def winfo_depth(self): + """Return the number of bits per pixel.""" + return getint(self.tk.call('winfo', 'depth', self._w)) + def winfo_exists(self): + """Return true if this widget exists.""" + return getint( + self.tk.call('winfo', 'exists', self._w)) + def winfo_fpixels(self, number): + """Return the number of pixels for the given distance NUMBER + (e.g. "3c") as float.""" + return getdouble(self.tk.call( + 'winfo', 'fpixels', self._w, number)) + def winfo_geometry(self): + """Return geometry string for this widget in the form "widthxheight+X+Y".""" + return self.tk.call('winfo', 'geometry', self._w) + def winfo_height(self): + """Return height of this widget.""" + return getint( + self.tk.call('winfo', 'height', self._w)) + def winfo_id(self): + """Return identifier ID for this widget.""" + return self.tk.getint( + self.tk.call('winfo', 'id', self._w)) + def winfo_interps(self, displayof=0): + """Return the name of all Tcl interpreters for this display.""" + args = ('winfo', 'interps') + self._displayof(displayof) + return self.tk.splitlist(self.tk.call(args)) + def winfo_ismapped(self): + """Return true if this widget is mapped.""" + return getint( + self.tk.call('winfo', 'ismapped', self._w)) + def winfo_manager(self): + """Return the window mananger name for this widget.""" + return self.tk.call('winfo', 'manager', self._w) + def winfo_name(self): + """Return the name of this widget.""" + return self.tk.call('winfo', 'name', self._w) + def winfo_parent(self): + """Return the name of the parent of this widget.""" + return self.tk.call('winfo', 'parent', self._w) + def winfo_pathname(self, id, displayof=0): + """Return the pathname of the widget given by ID.""" + args = ('winfo', 'pathname') \ + + self._displayof(displayof) + (id,) + return self.tk.call(args) + def winfo_pixels(self, number): + """Rounded integer value of winfo_fpixels.""" + return getint( + self.tk.call('winfo', 'pixels', self._w, number)) + def winfo_pointerx(self): + """Return the x coordinate of the pointer on the root window.""" + return getint( + self.tk.call('winfo', 'pointerx', self._w)) + def winfo_pointerxy(self): + """Return a tuple of x and y coordinates of the pointer on the root window.""" + return self._getints( + self.tk.call('winfo', 'pointerxy', self._w)) + def winfo_pointery(self): + """Return the y coordinate of the pointer on the root window.""" + return getint( + self.tk.call('winfo', 'pointery', self._w)) + def winfo_reqheight(self): + """Return requested height of this widget.""" + return getint( + self.tk.call('winfo', 'reqheight', self._w)) + def winfo_reqwidth(self): + """Return requested width of this widget.""" + return getint( + self.tk.call('winfo', 'reqwidth', self._w)) + def winfo_rgb(self, color): + """Return tuple of decimal values for red, green, blue for + COLOR in this widget.""" + return self._getints( + self.tk.call('winfo', 'rgb', self._w, color)) + def winfo_rootx(self): + """Return x coordinate of upper left corner of this widget on the + root window.""" + return getint( + self.tk.call('winfo', 'rootx', self._w)) + def winfo_rooty(self): + """Return y coordinate of upper left corner of this widget on the + root window.""" + return getint( + self.tk.call('winfo', 'rooty', self._w)) + def winfo_screen(self): + """Return the screen name of this widget.""" + return self.tk.call('winfo', 'screen', self._w) + def winfo_screencells(self): + """Return the number of the cells in the colormap of the screen + of this widget.""" + return getint( + self.tk.call('winfo', 'screencells', self._w)) + def winfo_screendepth(self): + """Return the number of bits per pixel of the root window of the + screen of this widget.""" + return getint( + self.tk.call('winfo', 'screendepth', self._w)) + def winfo_screenheight(self): + """Return the number of pixels of the height of the screen of this widget + in pixel.""" + return getint( + self.tk.call('winfo', 'screenheight', self._w)) + def winfo_screenmmheight(self): + """Return the number of pixels of the height of the screen of + this widget in mm.""" + return getint( + self.tk.call('winfo', 'screenmmheight', self._w)) + def winfo_screenmmwidth(self): + """Return the number of pixels of the width of the screen of + this widget in mm.""" + return getint( + self.tk.call('winfo', 'screenmmwidth', self._w)) + def winfo_screenvisual(self): + """Return one of the strings directcolor, grayscale, pseudocolor, + staticcolor, staticgray, or truecolor for the default + colormodel of this screen.""" + return self.tk.call('winfo', 'screenvisual', self._w) + def winfo_screenwidth(self): + """Return the number of pixels of the width of the screen of + this widget in pixel.""" + return getint( + self.tk.call('winfo', 'screenwidth', self._w)) + def winfo_server(self): + """Return information of the X-Server of the screen of this widget in + the form "XmajorRminor vendor vendorVersion".""" + return self.tk.call('winfo', 'server', self._w) + def winfo_toplevel(self): + """Return the toplevel widget of this widget.""" + return self._nametowidget(self.tk.call( + 'winfo', 'toplevel', self._w)) + def winfo_viewable(self): + """Return true if the widget and all its higher ancestors are mapped.""" + return getint( + self.tk.call('winfo', 'viewable', self._w)) + def winfo_visual(self): + """Return one of the strings directcolor, grayscale, pseudocolor, + staticcolor, staticgray, or truecolor for the + colormodel of this widget.""" + return self.tk.call('winfo', 'visual', self._w) + def winfo_visualid(self): + """Return the X identifier for the visual for this widget.""" + return self.tk.call('winfo', 'visualid', self._w) + def winfo_visualsavailable(self, includeids=0): + """Return a list of all visuals available for the screen + of this widget. + + Each item in the list consists of a visual name (see winfo_visual), a + depth and if INCLUDEIDS=1 is given also the X identifier.""" + data = self.tk.split( + self.tk.call('winfo', 'visualsavailable', self._w, + includeids and 'includeids' or None)) + if type(data) is StringType: + data = [self.tk.split(data)] + return map(self.__winfo_parseitem, data) + def __winfo_parseitem(self, t): + """Internal function.""" + return t[:1] + tuple(map(self.__winfo_getint, t[1:])) + def __winfo_getint(self, x): + """Internal function.""" + return int(x, 0) + def winfo_vrootheight(self): + """Return the height of the virtual root window associated with this + widget in pixels. If there is no virtual root window return the + height of the screen.""" + return getint( + self.tk.call('winfo', 'vrootheight', self._w)) + def winfo_vrootwidth(self): + """Return the width of the virtual root window associated with this + widget in pixel. If there is no virtual root window return the + width of the screen.""" + return getint( + self.tk.call('winfo', 'vrootwidth', self._w)) + def winfo_vrootx(self): + """Return the x offset of the virtual root relative to the root + window of the screen of this widget.""" + return getint( + self.tk.call('winfo', 'vrootx', self._w)) + def winfo_vrooty(self): + """Return the y offset of the virtual root relative to the root + window of the screen of this widget.""" + return getint( + self.tk.call('winfo', 'vrooty', self._w)) + def winfo_width(self): + """Return the width of this widget.""" + return getint( + self.tk.call('winfo', 'width', self._w)) + def winfo_x(self): + """Return the x coordinate of the upper left corner of this widget + in the parent.""" + return getint( + self.tk.call('winfo', 'x', self._w)) + def winfo_y(self): + """Return the y coordinate of the upper left corner of this widget + in the parent.""" + return getint( + self.tk.call('winfo', 'y', self._w)) + def update(self): + """Enter event loop until all pending events have been processed by Tcl.""" + self.tk.call('update') + def update_idletasks(self): + """Enter event loop until all idle callbacks have been called. This + will update the display of windows but not process events caused by + the user.""" + self.tk.call('update', 'idletasks') + def bindtags(self, tagList=None): + """Set or get the list of bindtags for this widget. + + With no argument return the list of all bindtags associated with + this widget. With a list of strings as argument the bindtags are + set to this list. The bindtags determine in which order events are + processed (see bind).""" + if tagList is None: + return self.tk.splitlist( + self.tk.call('bindtags', self._w)) + else: + self.tk.call('bindtags', self._w, tagList) + def _bind(self, what, sequence, func, add, needcleanup=1): + """Internal function.""" + if type(func) is StringType: + self.tk.call(what + (sequence, func)) + elif func: + funcid = self._register(func, self._substitute, + needcleanup) + cmd = ('%sif {"[%s %s]" == "break"} break\n' + % + (add and '+' or '', + funcid, self._subst_format_str)) + self.tk.call(what + (sequence, cmd)) + return funcid + elif sequence: + return self.tk.call(what + (sequence,)) + else: + return self.tk.splitlist(self.tk.call(what)) + def bind(self, sequence=None, func=None, add=None): + """Bind to this widget at event SEQUENCE a call to function FUNC. + + SEQUENCE is a string of concatenated event + patterns. An event pattern is of the form + where MODIFIER is one + of Control, Mod2, M2, Shift, Mod3, M3, Lock, Mod4, M4, + Button1, B1, Mod5, M5 Button2, B2, Meta, M, Button3, + B3, Alt, Button4, B4, Double, Button5, B5 Triple, + Mod1, M1. TYPE is one of Activate, Enter, Map, + ButtonPress, Button, Expose, Motion, ButtonRelease + FocusIn, MouseWheel, Circulate, FocusOut, Property, + Colormap, Gravity Reparent, Configure, KeyPress, Key, + Unmap, Deactivate, KeyRelease Visibility, Destroy, + Leave and DETAIL is the button number for ButtonPress, + ButtonRelease and DETAIL is the Keysym for KeyPress and + KeyRelease. Examples are + for pressing Control and mouse button 1 or + for pressing A and the Alt key (KeyPress can be omitted). + An event pattern can also be a virtual event of the form + <> where AString can be arbitrary. This + event can be generated by event_generate. + If events are concatenated they must appear shortly + after each other. + + FUNC will be called if the event sequence occurs with an + instance of Event as argument. If the return value of FUNC is + "break" no further bound function is invoked. + + An additional boolean parameter ADD specifies whether FUNC will + be called additionally to the other bound function or whether + it will replace the previous function. + + Bind will return an identifier to allow deletion of the bound function with + unbind without memory leak. + + If FUNC or SEQUENCE is omitted the bound function or list + of bound events are returned.""" + + return self._bind(('bind', self._w), sequence, func, add) + def unbind(self, sequence, funcid=None): + """Unbind for this widget for event SEQUENCE the + function identified with FUNCID.""" + self.tk.call('bind', self._w, sequence, '') + if funcid: + self.deletecommand(funcid) + def bind_all(self, sequence=None, func=None, add=None): + """Bind to all widgets at an event SEQUENCE a call to function FUNC. + An additional boolean parameter ADD specifies whether FUNC will + be called additionally to the other bound function or whether + it will replace the previous function. See bind for the return value.""" + return self._bind(('bind', 'all'), sequence, func, add, 0) + def unbind_all(self, sequence): + """Unbind for all widgets for event SEQUENCE all functions.""" + self.tk.call('bind', 'all' , sequence, '') + def bind_class(self, className, sequence=None, func=None, add=None): + + """Bind to widgets with bindtag CLASSNAME at event + SEQUENCE a call of function FUNC. An additional + boolean parameter ADD specifies whether FUNC will be + called additionally to the other bound function or + whether it will replace the previous function. See bind for + the return value.""" + + return self._bind(('bind', className), sequence, func, add, 0) + def unbind_class(self, className, sequence): + """Unbind for a all widgets with bindtag CLASSNAME for event SEQUENCE + all functions.""" + self.tk.call('bind', className , sequence, '') + def mainloop(self, n=0): + """Call the mainloop of Tk.""" + self.tk.mainloop(n) + def quit(self): + """Quit the Tcl interpreter. All widgets will be destroyed.""" + self.tk.quit() + def _getints(self, string): + """Internal function.""" + if string: + return tuple(map(getint, self.tk.splitlist(string))) + def _getdoubles(self, string): + """Internal function.""" + if string: + return tuple(map(getdouble, self.tk.splitlist(string))) + def _getboolean(self, string): + """Internal function.""" + if string: + return self.tk.getboolean(string) + def _displayof(self, displayof): + """Internal function.""" + if displayof: + return ('-displayof', displayof) + if displayof is None: + return ('-displayof', self._w) + return () + @property + def _windowingsystem(self): + """Internal function.""" + try: + return self._root()._windowingsystem_cached + except AttributeError: + ws = self._root()._windowingsystem_cached = \ + self.tk.call('tk', 'windowingsystem') + return ws + def _options(self, cnf, kw = None): + """Internal function.""" + if kw: + cnf = _cnfmerge((cnf, kw)) + else: + cnf = _cnfmerge(cnf) + res = () + for k, v in cnf.items(): + if v is not None: + if k[-1] == '_': k = k[:-1] + if hasattr(v, '__call__'): + v = self._register(v) + elif isinstance(v, (tuple, list)): + nv = [] + for item in v: + if not isinstance(item, (basestring, int)): + break + elif isinstance(item, int): + nv.append('%d' % item) + else: + # format it to proper Tcl code if it contains space + nv.append(_stringify(item)) + else: + v = ' '.join(nv) + res = res + ('-'+k, v) + return res + def nametowidget(self, name): + """Return the Tkinter instance of a widget identified by + its Tcl name NAME.""" + name = str(name).split('.') + w = self + + if not name[0]: + w = w._root() + name = name[1:] + + for n in name: + if not n: + break + w = w.children[n] + + return w + _nametowidget = nametowidget + def _register(self, func, subst=None, needcleanup=1): + """Return a newly created Tcl function. If this + function is called, the Python function FUNC will + be executed. An optional function SUBST can + be given which will be executed before FUNC.""" + f = CallWrapper(func, subst, self).__call__ + name = repr(id(f)) + try: + func = func.im_func + except AttributeError: + pass + try: + name = name + func.__name__ + except AttributeError: + pass + self.tk.createcommand(name, f) + if needcleanup: + if self._tclCommands is None: + self._tclCommands = [] + self._tclCommands.append(name) + return name + register = _register + def _root(self): + """Internal function.""" + w = self + while w.master: w = w.master + return w + _subst_format = ('%#', '%b', '%f', '%h', '%k', + '%s', '%t', '%w', '%x', '%y', + '%A', '%E', '%K', '%N', '%W', '%T', '%X', '%Y', '%D') + _subst_format_str = " ".join(_subst_format) + def _substitute(self, *args): + """Internal function.""" + if len(args) != len(self._subst_format): return args + getboolean = self.tk.getboolean + + getint = int + def getint_event(s): + """Tk changed behavior in 8.4.2, returning "??" rather more often.""" + try: + return int(s) + except ValueError: + return s + + nsign, b, f, h, k, s, t, w, x, y, A, E, K, N, W, T, X, Y, D = args + # Missing: (a, c, d, m, o, v, B, R) + e = Event() + # serial field: valid vor all events + # number of button: ButtonPress and ButtonRelease events only + # height field: Configure, ConfigureRequest, Create, + # ResizeRequest, and Expose events only + # keycode field: KeyPress and KeyRelease events only + # time field: "valid for events that contain a time field" + # width field: Configure, ConfigureRequest, Create, ResizeRequest, + # and Expose events only + # x field: "valid for events that contain a x field" + # y field: "valid for events that contain a y field" + # keysym as decimal: KeyPress and KeyRelease events only + # x_root, y_root fields: ButtonPress, ButtonRelease, KeyPress, + # KeyRelease,and Motion events + e.serial = getint(nsign) + e.num = getint_event(b) + try: e.focus = getboolean(f) + except TclError: pass + e.height = getint_event(h) + e.keycode = getint_event(k) + e.state = getint_event(s) + e.time = getint_event(t) + e.width = getint_event(w) + e.x = getint_event(x) + e.y = getint_event(y) + e.char = A + try: e.send_event = getboolean(E) + except TclError: pass + e.keysym = K + e.keysym_num = getint_event(N) + e.type = T + try: + e.widget = self._nametowidget(W) + except KeyError: + e.widget = W + e.x_root = getint_event(X) + e.y_root = getint_event(Y) + try: + e.delta = getint(D) + except ValueError: + e.delta = 0 + return (e,) + def _report_exception(self): + """Internal function.""" + import sys + exc, val, tb = sys.exc_type, sys.exc_value, sys.exc_traceback + root = self._root() + root.report_callback_exception(exc, val, tb) + + def _getconfigure(self, *args): + """Call Tcl configure command and return the result as a dict.""" + cnf = {} + for x in self.tk.splitlist(self.tk.call(*args)): + x = self.tk.splitlist(x) + cnf[x[0][1:]] = (x[0][1:],) + x[1:] + return cnf + + def _getconfigure1(self, *args): + x = self.tk.splitlist(self.tk.call(*args)) + return (x[0][1:],) + x[1:] + + def _configure(self, cmd, cnf, kw): + """Internal function.""" + if kw: + cnf = _cnfmerge((cnf, kw)) + elif cnf: + cnf = _cnfmerge(cnf) + if cnf is None: + return self._getconfigure(_flatten((self._w, cmd))) + if type(cnf) is StringType: + return self._getconfigure1(_flatten((self._w, cmd, '-'+cnf))) + self.tk.call(_flatten((self._w, cmd)) + self._options(cnf)) + # These used to be defined in Widget: + def configure(self, cnf=None, **kw): + """Configure resources of a widget. + + The values for resources are specified as keyword + arguments. To get an overview about + the allowed keyword arguments call the method keys. + """ + return self._configure('configure', cnf, kw) + config = configure + def cget(self, key): + """Return the resource value for a KEY given as string.""" + return self.tk.call(self._w, 'cget', '-' + key) + __getitem__ = cget + def __setitem__(self, key, value): + self.configure({key: value}) + def __contains__(self, key): + raise TypeError("Tkinter objects don't support 'in' tests.") + def keys(self): + """Return a list of all resource names of this widget.""" + return [x[0][1:] for x in + self.tk.splitlist(self.tk.call(self._w, 'configure'))] + def __str__(self): + """Return the window path name of this widget.""" + return self._w + # Pack methods that apply to the master + _noarg_ = ['_noarg_'] + def pack_propagate(self, flag=_noarg_): + """Set or get the status for propagation of geometry information. + + A boolean argument specifies whether the geometry information + of the slaves will determine the size of this widget. If no argument + is given the current setting will be returned. + """ + if flag is Misc._noarg_: + return self._getboolean(self.tk.call( + 'pack', 'propagate', self._w)) + else: + self.tk.call('pack', 'propagate', self._w, flag) + propagate = pack_propagate + def pack_slaves(self): + """Return a list of all slaves of this widget + in its packing order.""" + return map(self._nametowidget, + self.tk.splitlist( + self.tk.call('pack', 'slaves', self._w))) + slaves = pack_slaves + # Place method that applies to the master + def place_slaves(self): + """Return a list of all slaves of this widget + in its packing order.""" + return map(self._nametowidget, + self.tk.splitlist( + self.tk.call( + 'place', 'slaves', self._w))) + # Grid methods that apply to the master + def grid_bbox(self, column=None, row=None, col2=None, row2=None): + """Return a tuple of integer coordinates for the bounding + box of this widget controlled by the geometry manager grid. + + If COLUMN, ROW is given the bounding box applies from + the cell with row and column 0 to the specified + cell. If COL2 and ROW2 are given the bounding box + starts at that cell. + + The returned integers specify the offset of the upper left + corner in the master widget and the width and height. + """ + args = ('grid', 'bbox', self._w) + if column is not None and row is not None: + args = args + (column, row) + if col2 is not None and row2 is not None: + args = args + (col2, row2) + return self._getints(self.tk.call(*args)) or None + + bbox = grid_bbox + + def _gridconvvalue(self, value): + if isinstance(value, (str, _tkinter.Tcl_Obj)): + try: + svalue = str(value) + if not svalue: + return None + elif '.' in svalue: + return getdouble(svalue) + else: + return getint(svalue) + except ValueError: + pass + return value + + def _grid_configure(self, command, index, cnf, kw): + """Internal function.""" + if type(cnf) is StringType and not kw: + if cnf[-1:] == '_': + cnf = cnf[:-1] + if cnf[:1] != '-': + cnf = '-'+cnf + options = (cnf,) + else: + options = self._options(cnf, kw) + if not options: + res = self.tk.call('grid', + command, self._w, index) + words = self.tk.splitlist(res) + dict = {} + for i in range(0, len(words), 2): + key = words[i][1:] + value = words[i+1] + dict[key] = self._gridconvvalue(value) + return dict + res = self.tk.call( + ('grid', command, self._w, index) + + options) + if len(options) == 1: + return self._gridconvvalue(res) + + def grid_columnconfigure(self, index, cnf={}, **kw): + """Configure column INDEX of a grid. + + Valid resources are minsize (minimum size of the column), + weight (how much does additional space propagate to this column) + and pad (how much space to let additionally).""" + return self._grid_configure('columnconfigure', index, cnf, kw) + columnconfigure = grid_columnconfigure + def grid_location(self, x, y): + """Return a tuple of column and row which identify the cell + at which the pixel at position X and Y inside the master + widget is located.""" + return self._getints( + self.tk.call( + 'grid', 'location', self._w, x, y)) or None + def grid_propagate(self, flag=_noarg_): + """Set or get the status for propagation of geometry information. + + A boolean argument specifies whether the geometry information + of the slaves will determine the size of this widget. If no argument + is given, the current setting will be returned. + """ + if flag is Misc._noarg_: + return self._getboolean(self.tk.call( + 'grid', 'propagate', self._w)) + else: + self.tk.call('grid', 'propagate', self._w, flag) + def grid_rowconfigure(self, index, cnf={}, **kw): + """Configure row INDEX of a grid. + + Valid resources are minsize (minimum size of the row), + weight (how much does additional space propagate to this row) + and pad (how much space to let additionally).""" + return self._grid_configure('rowconfigure', index, cnf, kw) + rowconfigure = grid_rowconfigure + def grid_size(self): + """Return a tuple of the number of column and rows in the grid.""" + return self._getints( + self.tk.call('grid', 'size', self._w)) or None + size = grid_size + def grid_slaves(self, row=None, column=None): + """Return a list of all slaves of this widget + in its packing order.""" + args = () + if row is not None: + args = args + ('-row', row) + if column is not None: + args = args + ('-column', column) + return map(self._nametowidget, + self.tk.splitlist(self.tk.call( + ('grid', 'slaves', self._w) + args))) + + # Support for the "event" command, new in Tk 4.2. + # By Case Roole. + + def event_add(self, virtual, *sequences): + """Bind a virtual event VIRTUAL (of the form <>) + to an event SEQUENCE such that the virtual event is triggered + whenever SEQUENCE occurs.""" + args = ('event', 'add', virtual) + sequences + self.tk.call(args) + + def event_delete(self, virtual, *sequences): + """Unbind a virtual event VIRTUAL from SEQUENCE.""" + args = ('event', 'delete', virtual) + sequences + self.tk.call(args) + + def event_generate(self, sequence, **kw): + """Generate an event SEQUENCE. Additional + keyword arguments specify parameter of the event + (e.g. x, y, rootx, rooty).""" + args = ('event', 'generate', self._w, sequence) + for k, v in kw.items(): + args = args + ('-%s' % k, str(v)) + self.tk.call(args) + + def event_info(self, virtual=None): + """Return a list of all virtual events or the information + about the SEQUENCE bound to the virtual event VIRTUAL.""" + return self.tk.splitlist( + self.tk.call('event', 'info', virtual)) + + # Image related commands + + def image_names(self): + """Return a list of all existing image names.""" + return self.tk.splitlist(self.tk.call('image', 'names')) + + def image_types(self): + """Return a list of all available image types (e.g. phote bitmap).""" + return self.tk.splitlist(self.tk.call('image', 'types')) + + +class CallWrapper: + """Internal class. Stores function to call when some user + defined Tcl function is called e.g. after an event occurred.""" + def __init__(self, func, subst, widget): + """Store FUNC, SUBST and WIDGET as members.""" + self.func = func + self.subst = subst + self.widget = widget + def __call__(self, *args): + """Apply first function SUBST to arguments, than FUNC.""" + try: + if self.subst: + args = self.subst(*args) + return self.func(*args) + except SystemExit, msg: + raise SystemExit, msg + except: + self.widget._report_exception() + + +class XView: + """Mix-in class for querying and changing the horizontal position + of a widget's window.""" + + def xview(self, *args): + """Query and change the horizontal position of the view.""" + res = self.tk.call(self._w, 'xview', *args) + if not args: + return self._getdoubles(res) + + def xview_moveto(self, fraction): + """Adjusts the view in the window so that FRACTION of the + total width of the canvas is off-screen to the left.""" + self.tk.call(self._w, 'xview', 'moveto', fraction) + + def xview_scroll(self, number, what): + """Shift the x-view according to NUMBER which is measured in "units" + or "pages" (WHAT).""" + self.tk.call(self._w, 'xview', 'scroll', number, what) + + +class YView: + """Mix-in class for querying and changing the vertical position + of a widget's window.""" + + def yview(self, *args): + """Query and change the vertical position of the view.""" + res = self.tk.call(self._w, 'yview', *args) + if not args: + return self._getdoubles(res) + + def yview_moveto(self, fraction): + """Adjusts the view in the window so that FRACTION of the + total height of the canvas is off-screen to the top.""" + self.tk.call(self._w, 'yview', 'moveto', fraction) + + def yview_scroll(self, number, what): + """Shift the y-view according to NUMBER which is measured in + "units" or "pages" (WHAT).""" + self.tk.call(self._w, 'yview', 'scroll', number, what) + + +class Wm: + """Provides functions for the communication with the window manager.""" + + def wm_aspect(self, + minNumer=None, minDenom=None, + maxNumer=None, maxDenom=None): + """Instruct the window manager to set the aspect ratio (width/height) + of this widget to be between MINNUMER/MINDENOM and MAXNUMER/MAXDENOM. Return a tuple + of the actual values if no argument is given.""" + return self._getints( + self.tk.call('wm', 'aspect', self._w, + minNumer, minDenom, + maxNumer, maxDenom)) + aspect = wm_aspect + + def wm_attributes(self, *args): + """This subcommand returns or sets platform specific attributes + + The first form returns a list of the platform specific flags and + their values. The second form returns the value for the specific + option. The third form sets one or more of the values. The values + are as follows: + + On Windows, -disabled gets or sets whether the window is in a + disabled state. -toolwindow gets or sets the style of the window + to toolwindow (as defined in the MSDN). -topmost gets or sets + whether this is a topmost window (displays above all other + windows). + + On Macintosh, XXXXX + + On Unix, there are currently no special attribute values. + """ + args = ('wm', 'attributes', self._w) + args + return self.tk.call(args) + attributes=wm_attributes + + def wm_client(self, name=None): + """Store NAME in WM_CLIENT_MACHINE property of this widget. Return + current value.""" + return self.tk.call('wm', 'client', self._w, name) + client = wm_client + def wm_colormapwindows(self, *wlist): + """Store list of window names (WLIST) into WM_COLORMAPWINDOWS property + of this widget. This list contains windows whose colormaps differ from their + parents. Return current list of widgets if WLIST is empty.""" + if len(wlist) > 1: + wlist = (wlist,) # Tk needs a list of windows here + args = ('wm', 'colormapwindows', self._w) + wlist + if wlist: + self.tk.call(args) + else: + return map(self._nametowidget, self.tk.splitlist(self.tk.call(args))) + colormapwindows = wm_colormapwindows + def wm_command(self, value=None): + """Store VALUE in WM_COMMAND property. It is the command + which shall be used to invoke the application. Return current + command if VALUE is None.""" + return self.tk.call('wm', 'command', self._w, value) + command = wm_command + def wm_deiconify(self): + """Deiconify this widget. If it was never mapped it will not be mapped. + On Windows it will raise this widget and give it the focus.""" + return self.tk.call('wm', 'deiconify', self._w) + deiconify = wm_deiconify + def wm_focusmodel(self, model=None): + """Set focus model to MODEL. "active" means that this widget will claim + the focus itself, "passive" means that the window manager shall give + the focus. Return current focus model if MODEL is None.""" + return self.tk.call('wm', 'focusmodel', self._w, model) + focusmodel = wm_focusmodel + def wm_frame(self): + """Return identifier for decorative frame of this widget if present.""" + return self.tk.call('wm', 'frame', self._w) + frame = wm_frame + def wm_geometry(self, newGeometry=None): + """Set geometry to NEWGEOMETRY of the form =widthxheight+x+y. Return + current value if None is given.""" + return self.tk.call('wm', 'geometry', self._w, newGeometry) + geometry = wm_geometry + def wm_grid(self, + baseWidth=None, baseHeight=None, + widthInc=None, heightInc=None): + """Instruct the window manager that this widget shall only be + resized on grid boundaries. WIDTHINC and HEIGHTINC are the width and + height of a grid unit in pixels. BASEWIDTH and BASEHEIGHT are the + number of grid units requested in Tk_GeometryRequest.""" + return self._getints(self.tk.call( + 'wm', 'grid', self._w, + baseWidth, baseHeight, widthInc, heightInc)) + grid = wm_grid + def wm_group(self, pathName=None): + """Set the group leader widgets for related widgets to PATHNAME. Return + the group leader of this widget if None is given.""" + return self.tk.call('wm', 'group', self._w, pathName) + group = wm_group + def wm_iconbitmap(self, bitmap=None, default=None): + """Set bitmap for the iconified widget to BITMAP. Return + the bitmap if None is given. + + Under Windows, the DEFAULT parameter can be used to set the icon + for the widget and any descendents that don't have an icon set + explicitly. DEFAULT can be the relative path to a .ico file + (example: root.iconbitmap(default='myicon.ico') ). See Tk + documentation for more information.""" + if default: + return self.tk.call('wm', 'iconbitmap', self._w, '-default', default) + else: + return self.tk.call('wm', 'iconbitmap', self._w, bitmap) + iconbitmap = wm_iconbitmap + def wm_iconify(self): + """Display widget as icon.""" + return self.tk.call('wm', 'iconify', self._w) + iconify = wm_iconify + def wm_iconmask(self, bitmap=None): + """Set mask for the icon bitmap of this widget. Return the + mask if None is given.""" + return self.tk.call('wm', 'iconmask', self._w, bitmap) + iconmask = wm_iconmask + def wm_iconname(self, newName=None): + """Set the name of the icon for this widget. Return the name if + None is given.""" + return self.tk.call('wm', 'iconname', self._w, newName) + iconname = wm_iconname + def wm_iconposition(self, x=None, y=None): + """Set the position of the icon of this widget to X and Y. Return + a tuple of the current values of X and X if None is given.""" + return self._getints(self.tk.call( + 'wm', 'iconposition', self._w, x, y)) + iconposition = wm_iconposition + def wm_iconwindow(self, pathName=None): + """Set widget PATHNAME to be displayed instead of icon. Return the current + value if None is given.""" + return self.tk.call('wm', 'iconwindow', self._w, pathName) + iconwindow = wm_iconwindow + def wm_maxsize(self, width=None, height=None): + """Set max WIDTH and HEIGHT for this widget. If the window is gridded + the values are given in grid units. Return the current values if None + is given.""" + return self._getints(self.tk.call( + 'wm', 'maxsize', self._w, width, height)) + maxsize = wm_maxsize + def wm_minsize(self, width=None, height=None): + """Set min WIDTH and HEIGHT for this widget. If the window is gridded + the values are given in grid units. Return the current values if None + is given.""" + return self._getints(self.tk.call( + 'wm', 'minsize', self._w, width, height)) + minsize = wm_minsize + def wm_overrideredirect(self, boolean=None): + """Instruct the window manager to ignore this widget + if BOOLEAN is given with 1. Return the current value if None + is given.""" + return self._getboolean(self.tk.call( + 'wm', 'overrideredirect', self._w, boolean)) + overrideredirect = wm_overrideredirect + def wm_positionfrom(self, who=None): + """Instruct the window manager that the position of this widget shall + be defined by the user if WHO is "user", and by its own policy if WHO is + "program".""" + return self.tk.call('wm', 'positionfrom', self._w, who) + positionfrom = wm_positionfrom + def wm_protocol(self, name=None, func=None): + """Bind function FUNC to command NAME for this widget. + Return the function bound to NAME if None is given. NAME could be + e.g. "WM_SAVE_YOURSELF" or "WM_DELETE_WINDOW".""" + if hasattr(func, '__call__'): + command = self._register(func) + else: + command = func + return self.tk.call( + 'wm', 'protocol', self._w, name, command) + protocol = wm_protocol + def wm_resizable(self, width=None, height=None): + """Instruct the window manager whether this width can be resized + in WIDTH or HEIGHT. Both values are boolean values.""" + return self.tk.call('wm', 'resizable', self._w, width, height) + resizable = wm_resizable + def wm_sizefrom(self, who=None): + """Instruct the window manager that the size of this widget shall + be defined by the user if WHO is "user", and by its own policy if WHO is + "program".""" + return self.tk.call('wm', 'sizefrom', self._w, who) + sizefrom = wm_sizefrom + def wm_state(self, newstate=None): + """Query or set the state of this widget as one of normal, icon, + iconic (see wm_iconwindow), withdrawn, or zoomed (Windows only).""" + return self.tk.call('wm', 'state', self._w, newstate) + state = wm_state + def wm_title(self, string=None): + """Set the title of this widget.""" + return self.tk.call('wm', 'title', self._w, string) + title = wm_title + def wm_transient(self, master=None): + """Instruct the window manager that this widget is transient + with regard to widget MASTER.""" + return self.tk.call('wm', 'transient', self._w, master) + transient = wm_transient + def wm_withdraw(self): + """Withdraw this widget from the screen such that it is unmapped + and forgotten by the window manager. Re-draw it with wm_deiconify.""" + return self.tk.call('wm', 'withdraw', self._w) + withdraw = wm_withdraw + + +class Tk(Misc, Wm): + """Toplevel widget of Tk which represents mostly the main window + of an application. It has an associated Tcl interpreter.""" + _w = '.' + def __init__(self, screenName=None, baseName=None, className='Tk', + useTk=1, sync=0, use=None): + """Return a new Toplevel widget on screen SCREENNAME. A new Tcl interpreter will + be created. BASENAME will be used for the identification of the profile file (see + readprofile). + It is constructed from sys.argv[0] without extensions if None is given. CLASSNAME + is the name of the widget class.""" + self.master = None + self.children = {} + self._tkloaded = 0 + # to avoid recursions in the getattr code in case of failure, we + # ensure that self.tk is always _something_. + self.tk = None + if baseName is None: + import os + baseName = os.path.basename(sys.argv[0]) + baseName, ext = os.path.splitext(baseName) + if ext not in ('.py', '.pyc', '.pyo'): + baseName = baseName + ext + interactive = 0 + self.tk = _tkinter.create(screenName, baseName, className, interactive, wantobjects, useTk, sync, use) + if useTk: + self._loadtk() + if not sys.flags.ignore_environment: + # Issue #16248: Honor the -E flag to avoid code injection. + self.readprofile(baseName, className) + def loadtk(self): + if not self._tkloaded: + self.tk.loadtk() + self._loadtk() + def _loadtk(self): + self._tkloaded = 1 + global _default_root + # Version sanity checks + tk_version = self.tk.getvar('tk_version') + if tk_version != _tkinter.TK_VERSION: + raise RuntimeError, \ + "tk.h version (%s) doesn't match libtk.a version (%s)" \ + % (_tkinter.TK_VERSION, tk_version) + # Under unknown circumstances, tcl_version gets coerced to float + tcl_version = str(self.tk.getvar('tcl_version')) + if tcl_version != _tkinter.TCL_VERSION: + raise RuntimeError, \ + "tcl.h version (%s) doesn't match libtcl.a version (%s)" \ + % (_tkinter.TCL_VERSION, tcl_version) + if TkVersion < 4.0: + raise RuntimeError, \ + "Tk 4.0 or higher is required; found Tk %s" \ + % str(TkVersion) + # Create and register the tkerror and exit commands + # We need to inline parts of _register here, _ register + # would register differently-named commands. + if self._tclCommands is None: + self._tclCommands = [] + self.tk.createcommand('tkerror', _tkerror) + self.tk.createcommand('exit', _exit) + self._tclCommands.append('tkerror') + self._tclCommands.append('exit') + if _support_default_root and not _default_root: + _default_root = self + self.protocol("WM_DELETE_WINDOW", self.destroy) + def destroy(self): + """Destroy this and all descendants widgets. This will + end the application of this Tcl interpreter.""" + for c in self.children.values(): c.destroy() + self.tk.call('destroy', self._w) + Misc.destroy(self) + global _default_root + if _support_default_root and _default_root is self: + _default_root = None + def readprofile(self, baseName, className): + """Internal function. It reads BASENAME.tcl and CLASSNAME.tcl into + the Tcl Interpreter and calls execfile on BASENAME.py and CLASSNAME.py if + such a file exists in the home directory.""" + import os + if 'HOME' in os.environ: home = os.environ['HOME'] + else: home = os.curdir + class_tcl = os.path.join(home, '.%s.tcl' % className) + class_py = os.path.join(home, '.%s.py' % className) + base_tcl = os.path.join(home, '.%s.tcl' % baseName) + base_py = os.path.join(home, '.%s.py' % baseName) + dir = {'self': self} + exec 'from Tkinter import *' in dir + if os.path.isfile(class_tcl): + self.tk.call('source', class_tcl) + if os.path.isfile(class_py): + execfile(class_py, dir) + if os.path.isfile(base_tcl): + self.tk.call('source', base_tcl) + if os.path.isfile(base_py): + execfile(base_py, dir) + def report_callback_exception(self, exc, val, tb): + """Internal function. It reports exception on sys.stderr.""" + import traceback, sys + sys.stderr.write("Exception in Tkinter callback\n") + sys.last_type = exc + sys.last_value = val + sys.last_traceback = tb + traceback.print_exception(exc, val, tb) + def __getattr__(self, attr): + "Delegate attribute access to the interpreter object" + return getattr(self.tk, attr) + +# Ideally, the classes Pack, Place and Grid disappear, the +# pack/place/grid methods are defined on the Widget class, and +# everybody uses w.pack_whatever(...) instead of Pack.whatever(w, +# ...), with pack(), place() and grid() being short for +# pack_configure(), place_configure() and grid_columnconfigure(), and +# forget() being short for pack_forget(). As a practical matter, I'm +# afraid that there is too much code out there that may be using the +# Pack, Place or Grid class, so I leave them intact -- but only as +# backwards compatibility features. Also note that those methods that +# take a master as argument (e.g. pack_propagate) have been moved to +# the Misc class (which now incorporates all methods common between +# toplevel and interior widgets). Again, for compatibility, these are +# copied into the Pack, Place or Grid class. + + +def Tcl(screenName=None, baseName=None, className='Tk', useTk=0): + return Tk(screenName, baseName, className, useTk) + +class Pack: + """Geometry manager Pack. + + Base class to use the methods pack_* in every widget.""" + def pack_configure(self, cnf={}, **kw): + """Pack a widget in the parent widget. Use as options: + after=widget - pack it after you have packed widget + anchor=NSEW (or subset) - position widget according to + given direction + before=widget - pack it before you will pack widget + expand=bool - expand widget if parent size grows + fill=NONE or X or Y or BOTH - fill widget if widget grows + in=master - use master to contain this widget + in_=master - see 'in' option description + ipadx=amount - add internal padding in x direction + ipady=amount - add internal padding in y direction + padx=amount - add padding in x direction + pady=amount - add padding in y direction + side=TOP or BOTTOM or LEFT or RIGHT - where to add this widget. + """ + self.tk.call( + ('pack', 'configure', self._w) + + self._options(cnf, kw)) + pack = configure = config = pack_configure + def pack_forget(self): + """Unmap this widget and do not use it for the packing order.""" + self.tk.call('pack', 'forget', self._w) + forget = pack_forget + def pack_info(self): + """Return information about the packing options + for this widget.""" + words = self.tk.splitlist( + self.tk.call('pack', 'info', self._w)) + dict = {} + for i in range(0, len(words), 2): + key = words[i][1:] + value = words[i+1] + if str(value)[:1] == '.': + value = self._nametowidget(value) + dict[key] = value + return dict + info = pack_info + propagate = pack_propagate = Misc.pack_propagate + slaves = pack_slaves = Misc.pack_slaves + +class Place: + """Geometry manager Place. + + Base class to use the methods place_* in every widget.""" + def place_configure(self, cnf={}, **kw): + """Place a widget in the parent widget. Use as options: + in=master - master relative to which the widget is placed + in_=master - see 'in' option description + x=amount - locate anchor of this widget at position x of master + y=amount - locate anchor of this widget at position y of master + relx=amount - locate anchor of this widget between 0.0 and 1.0 + relative to width of master (1.0 is right edge) + rely=amount - locate anchor of this widget between 0.0 and 1.0 + relative to height of master (1.0 is bottom edge) + anchor=NSEW (or subset) - position anchor according to given direction + width=amount - width of this widget in pixel + height=amount - height of this widget in pixel + relwidth=amount - width of this widget between 0.0 and 1.0 + relative to width of master (1.0 is the same width + as the master) + relheight=amount - height of this widget between 0.0 and 1.0 + relative to height of master (1.0 is the same + height as the master) + bordermode="inside" or "outside" - whether to take border width of + master widget into account + """ + self.tk.call( + ('place', 'configure', self._w) + + self._options(cnf, kw)) + place = configure = config = place_configure + def place_forget(self): + """Unmap this widget.""" + self.tk.call('place', 'forget', self._w) + forget = place_forget + def place_info(self): + """Return information about the placing options + for this widget.""" + words = self.tk.splitlist( + self.tk.call('place', 'info', self._w)) + dict = {} + for i in range(0, len(words), 2): + key = words[i][1:] + value = words[i+1] + if str(value)[:1] == '.': + value = self._nametowidget(value) + dict[key] = value + return dict + info = place_info + slaves = place_slaves = Misc.place_slaves + +class Grid: + """Geometry manager Grid. + + Base class to use the methods grid_* in every widget.""" + # Thanks to Masazumi Yoshikawa (yosikawa@isi.edu) + def grid_configure(self, cnf={}, **kw): + """Position a widget in the parent widget in a grid. Use as options: + column=number - use cell identified with given column (starting with 0) + columnspan=number - this widget will span several columns + in=master - use master to contain this widget + in_=master - see 'in' option description + ipadx=amount - add internal padding in x direction + ipady=amount - add internal padding in y direction + padx=amount - add padding in x direction + pady=amount - add padding in y direction + row=number - use cell identified with given row (starting with 0) + rowspan=number - this widget will span several rows + sticky=NSEW - if cell is larger on which sides will this + widget stick to the cell boundary + """ + self.tk.call( + ('grid', 'configure', self._w) + + self._options(cnf, kw)) + grid = configure = config = grid_configure + bbox = grid_bbox = Misc.grid_bbox + columnconfigure = grid_columnconfigure = Misc.grid_columnconfigure + def grid_forget(self): + """Unmap this widget.""" + self.tk.call('grid', 'forget', self._w) + forget = grid_forget + def grid_remove(self): + """Unmap this widget but remember the grid options.""" + self.tk.call('grid', 'remove', self._w) + def grid_info(self): + """Return information about the options + for positioning this widget in a grid.""" + words = self.tk.splitlist( + self.tk.call('grid', 'info', self._w)) + dict = {} + for i in range(0, len(words), 2): + key = words[i][1:] + value = words[i+1] + if str(value)[:1] == '.': + value = self._nametowidget(value) + dict[key] = value + return dict + info = grid_info + location = grid_location = Misc.grid_location + propagate = grid_propagate = Misc.grid_propagate + rowconfigure = grid_rowconfigure = Misc.grid_rowconfigure + size = grid_size = Misc.grid_size + slaves = grid_slaves = Misc.grid_slaves + +class BaseWidget(Misc): + """Internal class.""" + def _setup(self, master, cnf): + """Internal function. Sets up information about children.""" + if _support_default_root: + global _default_root + if not master: + if not _default_root: + _default_root = Tk() + master = _default_root + self.master = master + self.tk = master.tk + name = None + if 'name' in cnf: + name = cnf['name'] + del cnf['name'] + if not name: + name = repr(id(self)) + self._name = name + if master._w=='.': + self._w = '.' + name + else: + self._w = master._w + '.' + name + self.children = {} + if self._name in self.master.children: + self.master.children[self._name].destroy() + self.master.children[self._name] = self + def __init__(self, master, widgetName, cnf={}, kw={}, extra=()): + """Construct a widget with the parent widget MASTER, a name WIDGETNAME + and appropriate options.""" + if kw: + cnf = _cnfmerge((cnf, kw)) + self.widgetName = widgetName + BaseWidget._setup(self, master, cnf) + if self._tclCommands is None: + self._tclCommands = [] + classes = [] + for k in cnf.keys(): + if type(k) is ClassType: + classes.append((k, cnf[k])) + del cnf[k] + self.tk.call( + (widgetName, self._w) + extra + self._options(cnf)) + for k, v in classes: + k.configure(self, v) + def destroy(self): + """Destroy this and all descendants widgets.""" + for c in self.children.values(): c.destroy() + self.tk.call('destroy', self._w) + if self._name in self.master.children: + del self.master.children[self._name] + Misc.destroy(self) + def _do(self, name, args=()): + # XXX Obsolete -- better use self.tk.call directly! + return self.tk.call((self._w, name) + args) + +class Widget(BaseWidget, Pack, Place, Grid): + """Internal class. + + Base class for a widget which can be positioned with the geometry managers + Pack, Place or Grid.""" + pass + +class Toplevel(BaseWidget, Wm): + """Toplevel widget, e.g. for dialogs.""" + def __init__(self, master=None, cnf={}, **kw): + """Construct a toplevel widget with the parent MASTER. + + Valid resource names: background, bd, bg, borderwidth, class, + colormap, container, cursor, height, highlightbackground, + highlightcolor, highlightthickness, menu, relief, screen, takefocus, + use, visual, width.""" + if kw: + cnf = _cnfmerge((cnf, kw)) + extra = () + for wmkey in ['screen', 'class_', 'class', 'visual', + 'colormap']: + if wmkey in cnf: + val = cnf[wmkey] + # TBD: a hack needed because some keys + # are not valid as keyword arguments + if wmkey[-1] == '_': opt = '-'+wmkey[:-1] + else: opt = '-'+wmkey + extra = extra + (opt, val) + del cnf[wmkey] + BaseWidget.__init__(self, master, 'toplevel', cnf, {}, extra) + root = self._root() + self.iconname(root.iconname()) + self.title(root.title()) + self.protocol("WM_DELETE_WINDOW", self.destroy) + +class Button(Widget): + """Button widget.""" + def __init__(self, master=None, cnf={}, **kw): + """Construct a button widget with the parent MASTER. + + STANDARD OPTIONS + + activebackground, activeforeground, anchor, + background, bitmap, borderwidth, cursor, + disabledforeground, font, foreground + highlightbackground, highlightcolor, + highlightthickness, image, justify, + padx, pady, relief, repeatdelay, + repeatinterval, takefocus, text, + textvariable, underline, wraplength + + WIDGET-SPECIFIC OPTIONS + + command, compound, default, height, + overrelief, state, width + """ + Widget.__init__(self, master, 'button', cnf, kw) + + def tkButtonEnter(self, *dummy): + self.tk.call('tkButtonEnter', self._w) + + def tkButtonLeave(self, *dummy): + self.tk.call('tkButtonLeave', self._w) + + def tkButtonDown(self, *dummy): + self.tk.call('tkButtonDown', self._w) + + def tkButtonUp(self, *dummy): + self.tk.call('tkButtonUp', self._w) + + def tkButtonInvoke(self, *dummy): + self.tk.call('tkButtonInvoke', self._w) + + def flash(self): + """Flash the button. + + This is accomplished by redisplaying + the button several times, alternating between active and + normal colors. At the end of the flash the button is left + in the same normal/active state as when the command was + invoked. This command is ignored if the button's state is + disabled. + """ + self.tk.call(self._w, 'flash') + + def invoke(self): + """Invoke the command associated with the button. + + The return value is the return value from the command, + or an empty string if there is no command associated with + the button. This command is ignored if the button's state + is disabled. + """ + return self.tk.call(self._w, 'invoke') + +# Indices: +# XXX I don't like these -- take them away +def AtEnd(): + return 'end' +def AtInsert(*args): + s = 'insert' + for a in args: + if a: s = s + (' ' + a) + return s +def AtSelFirst(): + return 'sel.first' +def AtSelLast(): + return 'sel.last' +def At(x, y=None): + if y is None: + return '@%r' % (x,) + else: + return '@%r,%r' % (x, y) + +class Canvas(Widget, XView, YView): + """Canvas widget to display graphical elements like lines or text.""" + def __init__(self, master=None, cnf={}, **kw): + """Construct a canvas widget with the parent MASTER. + + Valid resource names: background, bd, bg, borderwidth, closeenough, + confine, cursor, height, highlightbackground, highlightcolor, + highlightthickness, insertbackground, insertborderwidth, + insertofftime, insertontime, insertwidth, offset, relief, + scrollregion, selectbackground, selectborderwidth, selectforeground, + state, takefocus, width, xscrollcommand, xscrollincrement, + yscrollcommand, yscrollincrement.""" + Widget.__init__(self, master, 'canvas', cnf, kw) + def addtag(self, *args): + """Internal function.""" + self.tk.call((self._w, 'addtag') + args) + def addtag_above(self, newtag, tagOrId): + """Add tag NEWTAG to all items above TAGORID.""" + self.addtag(newtag, 'above', tagOrId) + def addtag_all(self, newtag): + """Add tag NEWTAG to all items.""" + self.addtag(newtag, 'all') + def addtag_below(self, newtag, tagOrId): + """Add tag NEWTAG to all items below TAGORID.""" + self.addtag(newtag, 'below', tagOrId) + def addtag_closest(self, newtag, x, y, halo=None, start=None): + """Add tag NEWTAG to item which is closest to pixel at X, Y. + If several match take the top-most. + All items closer than HALO are considered overlapping (all are + closests). If START is specified the next below this tag is taken.""" + self.addtag(newtag, 'closest', x, y, halo, start) + def addtag_enclosed(self, newtag, x1, y1, x2, y2): + """Add tag NEWTAG to all items in the rectangle defined + by X1,Y1,X2,Y2.""" + self.addtag(newtag, 'enclosed', x1, y1, x2, y2) + def addtag_overlapping(self, newtag, x1, y1, x2, y2): + """Add tag NEWTAG to all items which overlap the rectangle + defined by X1,Y1,X2,Y2.""" + self.addtag(newtag, 'overlapping', x1, y1, x2, y2) + def addtag_withtag(self, newtag, tagOrId): + """Add tag NEWTAG to all items with TAGORID.""" + self.addtag(newtag, 'withtag', tagOrId) + def bbox(self, *args): + """Return a tuple of X1,Y1,X2,Y2 coordinates for a rectangle + which encloses all items with tags specified as arguments.""" + return self._getints( + self.tk.call((self._w, 'bbox') + args)) or None + def tag_unbind(self, tagOrId, sequence, funcid=None): + """Unbind for all items with TAGORID for event SEQUENCE the + function identified with FUNCID.""" + self.tk.call(self._w, 'bind', tagOrId, sequence, '') + if funcid: + self.deletecommand(funcid) + def tag_bind(self, tagOrId, sequence=None, func=None, add=None): + """Bind to all items with TAGORID at event SEQUENCE a call to function FUNC. + + An additional boolean parameter ADD specifies whether FUNC will be + called additionally to the other bound function or whether it will + replace the previous function. See bind for the return value.""" + return self._bind((self._w, 'bind', tagOrId), + sequence, func, add) + def canvasx(self, screenx, gridspacing=None): + """Return the canvas x coordinate of pixel position SCREENX rounded + to nearest multiple of GRIDSPACING units.""" + return getdouble(self.tk.call( + self._w, 'canvasx', screenx, gridspacing)) + def canvasy(self, screeny, gridspacing=None): + """Return the canvas y coordinate of pixel position SCREENY rounded + to nearest multiple of GRIDSPACING units.""" + return getdouble(self.tk.call( + self._w, 'canvasy', screeny, gridspacing)) + def coords(self, *args): + """Return a list of coordinates for the item given in ARGS.""" + # XXX Should use _flatten on args + return map(getdouble, + self.tk.splitlist( + self.tk.call((self._w, 'coords') + args))) + def _create(self, itemType, args, kw): # Args: (val, val, ..., cnf={}) + """Internal function.""" + args = _flatten(args) + cnf = args[-1] + if type(cnf) in (DictionaryType, TupleType): + args = args[:-1] + else: + cnf = {} + return getint(self.tk.call( + self._w, 'create', itemType, + *(args + self._options(cnf, kw)))) + def create_arc(self, *args, **kw): + """Create arc shaped region with coordinates x1,y1,x2,y2.""" + return self._create('arc', args, kw) + def create_bitmap(self, *args, **kw): + """Create bitmap with coordinates x1,y1.""" + return self._create('bitmap', args, kw) + def create_image(self, *args, **kw): + """Create image item with coordinates x1,y1.""" + return self._create('image', args, kw) + def create_line(self, *args, **kw): + """Create line with coordinates x1,y1,...,xn,yn.""" + return self._create('line', args, kw) + def create_oval(self, *args, **kw): + """Create oval with coordinates x1,y1,x2,y2.""" + return self._create('oval', args, kw) + def create_polygon(self, *args, **kw): + """Create polygon with coordinates x1,y1,...,xn,yn.""" + return self._create('polygon', args, kw) + def create_rectangle(self, *args, **kw): + """Create rectangle with coordinates x1,y1,x2,y2.""" + return self._create('rectangle', args, kw) + def create_text(self, *args, **kw): + """Create text with coordinates x1,y1.""" + return self._create('text', args, kw) + def create_window(self, *args, **kw): + """Create window with coordinates x1,y1,x2,y2.""" + return self._create('window', args, kw) + def dchars(self, *args): + """Delete characters of text items identified by tag or id in ARGS (possibly + several times) from FIRST to LAST character (including).""" + self.tk.call((self._w, 'dchars') + args) + def delete(self, *args): + """Delete items identified by all tag or ids contained in ARGS.""" + self.tk.call((self._w, 'delete') + args) + def dtag(self, *args): + """Delete tag or id given as last arguments in ARGS from items + identified by first argument in ARGS.""" + self.tk.call((self._w, 'dtag') + args) + def find(self, *args): + """Internal function.""" + return self._getints( + self.tk.call((self._w, 'find') + args)) or () + def find_above(self, tagOrId): + """Return items above TAGORID.""" + return self.find('above', tagOrId) + def find_all(self): + """Return all items.""" + return self.find('all') + def find_below(self, tagOrId): + """Return all items below TAGORID.""" + return self.find('below', tagOrId) + def find_closest(self, x, y, halo=None, start=None): + """Return item which is closest to pixel at X, Y. + If several match take the top-most. + All items closer than HALO are considered overlapping (all are + closests). If START is specified the next below this tag is taken.""" + return self.find('closest', x, y, halo, start) + def find_enclosed(self, x1, y1, x2, y2): + """Return all items in rectangle defined + by X1,Y1,X2,Y2.""" + return self.find('enclosed', x1, y1, x2, y2) + def find_overlapping(self, x1, y1, x2, y2): + """Return all items which overlap the rectangle + defined by X1,Y1,X2,Y2.""" + return self.find('overlapping', x1, y1, x2, y2) + def find_withtag(self, tagOrId): + """Return all items with TAGORID.""" + return self.find('withtag', tagOrId) + def focus(self, *args): + """Set focus to the first item specified in ARGS.""" + return self.tk.call((self._w, 'focus') + args) + def gettags(self, *args): + """Return tags associated with the first item specified in ARGS.""" + return self.tk.splitlist( + self.tk.call((self._w, 'gettags') + args)) + def icursor(self, *args): + """Set cursor at position POS in the item identified by TAGORID. + In ARGS TAGORID must be first.""" + self.tk.call((self._w, 'icursor') + args) + def index(self, *args): + """Return position of cursor as integer in item specified in ARGS.""" + return getint(self.tk.call((self._w, 'index') + args)) + def insert(self, *args): + """Insert TEXT in item TAGORID at position POS. ARGS must + be TAGORID POS TEXT.""" + self.tk.call((self._w, 'insert') + args) + def itemcget(self, tagOrId, option): + """Return the resource value for an OPTION for item TAGORID.""" + return self.tk.call( + (self._w, 'itemcget') + (tagOrId, '-'+option)) + def itemconfigure(self, tagOrId, cnf=None, **kw): + """Configure resources of an item TAGORID. + + The values for resources are specified as keyword + arguments. To get an overview about + the allowed keyword arguments call the method without arguments. + """ + return self._configure(('itemconfigure', tagOrId), cnf, kw) + itemconfig = itemconfigure + # lower, tkraise/lift hide Misc.lower, Misc.tkraise/lift, + # so the preferred name for them is tag_lower, tag_raise + # (similar to tag_bind, and similar to the Text widget); + # unfortunately can't delete the old ones yet (maybe in 1.6) + def tag_lower(self, *args): + """Lower an item TAGORID given in ARGS + (optional below another item).""" + self.tk.call((self._w, 'lower') + args) + lower = tag_lower + def move(self, *args): + """Move an item TAGORID given in ARGS.""" + self.tk.call((self._w, 'move') + args) + def postscript(self, cnf={}, **kw): + """Print the contents of the canvas to a postscript + file. Valid options: colormap, colormode, file, fontmap, + height, pageanchor, pageheight, pagewidth, pagex, pagey, + rotate, witdh, x, y.""" + return self.tk.call((self._w, 'postscript') + + self._options(cnf, kw)) + def tag_raise(self, *args): + """Raise an item TAGORID given in ARGS + (optional above another item).""" + self.tk.call((self._w, 'raise') + args) + lift = tkraise = tag_raise + def scale(self, *args): + """Scale item TAGORID with XORIGIN, YORIGIN, XSCALE, YSCALE.""" + self.tk.call((self._w, 'scale') + args) + def scan_mark(self, x, y): + """Remember the current X, Y coordinates.""" + self.tk.call(self._w, 'scan', 'mark', x, y) + def scan_dragto(self, x, y, gain=10): + """Adjust the view of the canvas to GAIN times the + difference between X and Y and the coordinates given in + scan_mark.""" + self.tk.call(self._w, 'scan', 'dragto', x, y, gain) + def select_adjust(self, tagOrId, index): + """Adjust the end of the selection near the cursor of an item TAGORID to index.""" + self.tk.call(self._w, 'select', 'adjust', tagOrId, index) + def select_clear(self): + """Clear the selection if it is in this widget.""" + self.tk.call(self._w, 'select', 'clear') + def select_from(self, tagOrId, index): + """Set the fixed end of a selection in item TAGORID to INDEX.""" + self.tk.call(self._w, 'select', 'from', tagOrId, index) + def select_item(self): + """Return the item which has the selection.""" + return self.tk.call(self._w, 'select', 'item') or None + def select_to(self, tagOrId, index): + """Set the variable end of a selection in item TAGORID to INDEX.""" + self.tk.call(self._w, 'select', 'to', tagOrId, index) + def type(self, tagOrId): + """Return the type of the item TAGORID.""" + return self.tk.call(self._w, 'type', tagOrId) or None + +class Checkbutton(Widget): + """Checkbutton widget which is either in on- or off-state.""" + def __init__(self, master=None, cnf={}, **kw): + """Construct a checkbutton widget with the parent MASTER. + + Valid resource names: activebackground, activeforeground, anchor, + background, bd, bg, bitmap, borderwidth, command, cursor, + disabledforeground, fg, font, foreground, height, + highlightbackground, highlightcolor, highlightthickness, image, + indicatoron, justify, offvalue, onvalue, padx, pady, relief, + selectcolor, selectimage, state, takefocus, text, textvariable, + underline, variable, width, wraplength.""" + Widget.__init__(self, master, 'checkbutton', cnf, kw) + def deselect(self): + """Put the button in off-state.""" + self.tk.call(self._w, 'deselect') + def flash(self): + """Flash the button.""" + self.tk.call(self._w, 'flash') + def invoke(self): + """Toggle the button and invoke a command if given as resource.""" + return self.tk.call(self._w, 'invoke') + def select(self): + """Put the button in on-state.""" + self.tk.call(self._w, 'select') + def toggle(self): + """Toggle the button.""" + self.tk.call(self._w, 'toggle') + +class Entry(Widget, XView): + """Entry widget which allows to display simple text.""" + def __init__(self, master=None, cnf={}, **kw): + """Construct an entry widget with the parent MASTER. + + Valid resource names: background, bd, bg, borderwidth, cursor, + exportselection, fg, font, foreground, highlightbackground, + highlightcolor, highlightthickness, insertbackground, + insertborderwidth, insertofftime, insertontime, insertwidth, + invalidcommand, invcmd, justify, relief, selectbackground, + selectborderwidth, selectforeground, show, state, takefocus, + textvariable, validate, validatecommand, vcmd, width, + xscrollcommand.""" + Widget.__init__(self, master, 'entry', cnf, kw) + def delete(self, first, last=None): + """Delete text from FIRST to LAST (not included).""" + self.tk.call(self._w, 'delete', first, last) + def get(self): + """Return the text.""" + return self.tk.call(self._w, 'get') + def icursor(self, index): + """Insert cursor at INDEX.""" + self.tk.call(self._w, 'icursor', index) + def index(self, index): + """Return position of cursor.""" + return getint(self.tk.call( + self._w, 'index', index)) + def insert(self, index, string): + """Insert STRING at INDEX.""" + self.tk.call(self._w, 'insert', index, string) + def scan_mark(self, x): + """Remember the current X, Y coordinates.""" + self.tk.call(self._w, 'scan', 'mark', x) + def scan_dragto(self, x): + """Adjust the view of the canvas to 10 times the + difference between X and Y and the coordinates given in + scan_mark.""" + self.tk.call(self._w, 'scan', 'dragto', x) + def selection_adjust(self, index): + """Adjust the end of the selection near the cursor to INDEX.""" + self.tk.call(self._w, 'selection', 'adjust', index) + select_adjust = selection_adjust + def selection_clear(self): + """Clear the selection if it is in this widget.""" + self.tk.call(self._w, 'selection', 'clear') + select_clear = selection_clear + def selection_from(self, index): + """Set the fixed end of a selection to INDEX.""" + self.tk.call(self._w, 'selection', 'from', index) + select_from = selection_from + def selection_present(self): + """Return True if there are characters selected in the entry, False + otherwise.""" + return self.tk.getboolean( + self.tk.call(self._w, 'selection', 'present')) + select_present = selection_present + def selection_range(self, start, end): + """Set the selection from START to END (not included).""" + self.tk.call(self._w, 'selection', 'range', start, end) + select_range = selection_range + def selection_to(self, index): + """Set the variable end of a selection to INDEX.""" + self.tk.call(self._w, 'selection', 'to', index) + select_to = selection_to + +class Frame(Widget): + """Frame widget which may contain other widgets and can have a 3D border.""" + def __init__(self, master=None, cnf={}, **kw): + """Construct a frame widget with the parent MASTER. + + Valid resource names: background, bd, bg, borderwidth, class, + colormap, container, cursor, height, highlightbackground, + highlightcolor, highlightthickness, relief, takefocus, visual, width.""" + cnf = _cnfmerge((cnf, kw)) + extra = () + if 'class_' in cnf: + extra = ('-class', cnf['class_']) + del cnf['class_'] + elif 'class' in cnf: + extra = ('-class', cnf['class']) + del cnf['class'] + Widget.__init__(self, master, 'frame', cnf, {}, extra) + +class Label(Widget): + """Label widget which can display text and bitmaps.""" + def __init__(self, master=None, cnf={}, **kw): + """Construct a label widget with the parent MASTER. + + STANDARD OPTIONS + + activebackground, activeforeground, anchor, + background, bitmap, borderwidth, cursor, + disabledforeground, font, foreground, + highlightbackground, highlightcolor, + highlightthickness, image, justify, + padx, pady, relief, takefocus, text, + textvariable, underline, wraplength + + WIDGET-SPECIFIC OPTIONS + + height, state, width + + """ + Widget.__init__(self, master, 'label', cnf, kw) + +class Listbox(Widget, XView, YView): + """Listbox widget which can display a list of strings.""" + def __init__(self, master=None, cnf={}, **kw): + """Construct a listbox widget with the parent MASTER. + + Valid resource names: background, bd, bg, borderwidth, cursor, + exportselection, fg, font, foreground, height, highlightbackground, + highlightcolor, highlightthickness, relief, selectbackground, + selectborderwidth, selectforeground, selectmode, setgrid, takefocus, + width, xscrollcommand, yscrollcommand, listvariable.""" + Widget.__init__(self, master, 'listbox', cnf, kw) + def activate(self, index): + """Activate item identified by INDEX.""" + self.tk.call(self._w, 'activate', index) + def bbox(self, index): + """Return a tuple of X1,Y1,X2,Y2 coordinates for a rectangle + which encloses the item identified by the given index.""" + return self._getints(self.tk.call(self._w, 'bbox', index)) or None + def curselection(self): + """Return the indices of currently selected item.""" + return self._getints(self.tk.call(self._w, 'curselection')) or () + def delete(self, first, last=None): + """Delete items from FIRST to LAST (included).""" + self.tk.call(self._w, 'delete', first, last) + def get(self, first, last=None): + """Get list of items from FIRST to LAST (included).""" + if last is not None: + return self.tk.splitlist(self.tk.call( + self._w, 'get', first, last)) + else: + return self.tk.call(self._w, 'get', first) + def index(self, index): + """Return index of item identified with INDEX.""" + i = self.tk.call(self._w, 'index', index) + if i == 'none': return None + return getint(i) + def insert(self, index, *elements): + """Insert ELEMENTS at INDEX.""" + self.tk.call((self._w, 'insert', index) + elements) + def nearest(self, y): + """Get index of item which is nearest to y coordinate Y.""" + return getint(self.tk.call( + self._w, 'nearest', y)) + def scan_mark(self, x, y): + """Remember the current X, Y coordinates.""" + self.tk.call(self._w, 'scan', 'mark', x, y) + def scan_dragto(self, x, y): + """Adjust the view of the listbox to 10 times the + difference between X and Y and the coordinates given in + scan_mark.""" + self.tk.call(self._w, 'scan', 'dragto', x, y) + def see(self, index): + """Scroll such that INDEX is visible.""" + self.tk.call(self._w, 'see', index) + def selection_anchor(self, index): + """Set the fixed end oft the selection to INDEX.""" + self.tk.call(self._w, 'selection', 'anchor', index) + select_anchor = selection_anchor + def selection_clear(self, first, last=None): + """Clear the selection from FIRST to LAST (included).""" + self.tk.call(self._w, + 'selection', 'clear', first, last) + select_clear = selection_clear + def selection_includes(self, index): + """Return 1 if INDEX is part of the selection.""" + return self.tk.getboolean(self.tk.call( + self._w, 'selection', 'includes', index)) + select_includes = selection_includes + def selection_set(self, first, last=None): + """Set the selection from FIRST to LAST (included) without + changing the currently selected elements.""" + self.tk.call(self._w, 'selection', 'set', first, last) + select_set = selection_set + def size(self): + """Return the number of elements in the listbox.""" + return getint(self.tk.call(self._w, 'size')) + def itemcget(self, index, option): + """Return the resource value for an ITEM and an OPTION.""" + return self.tk.call( + (self._w, 'itemcget') + (index, '-'+option)) + def itemconfigure(self, index, cnf=None, **kw): + """Configure resources of an ITEM. + + The values for resources are specified as keyword arguments. + To get an overview about the allowed keyword arguments + call the method without arguments. + Valid resource names: background, bg, foreground, fg, + selectbackground, selectforeground.""" + return self._configure(('itemconfigure', index), cnf, kw) + itemconfig = itemconfigure + +class Menu(Widget): + """Menu widget which allows to display menu bars, pull-down menus and pop-up menus.""" + def __init__(self, master=None, cnf={}, **kw): + """Construct menu widget with the parent MASTER. + + Valid resource names: activebackground, activeborderwidth, + activeforeground, background, bd, bg, borderwidth, cursor, + disabledforeground, fg, font, foreground, postcommand, relief, + selectcolor, takefocus, tearoff, tearoffcommand, title, type.""" + Widget.__init__(self, master, 'menu', cnf, kw) + def tk_bindForTraversal(self): + pass # obsolete since Tk 4.0 + def tk_mbPost(self): + self.tk.call('tk_mbPost', self._w) + def tk_mbUnpost(self): + self.tk.call('tk_mbUnpost') + def tk_traverseToMenu(self, char): + self.tk.call('tk_traverseToMenu', self._w, char) + def tk_traverseWithinMenu(self, char): + self.tk.call('tk_traverseWithinMenu', self._w, char) + def tk_getMenuButtons(self): + return self.tk.call('tk_getMenuButtons', self._w) + def tk_nextMenu(self, count): + self.tk.call('tk_nextMenu', count) + def tk_nextMenuEntry(self, count): + self.tk.call('tk_nextMenuEntry', count) + def tk_invokeMenu(self): + self.tk.call('tk_invokeMenu', self._w) + def tk_firstMenu(self): + self.tk.call('tk_firstMenu', self._w) + def tk_mbButtonDown(self): + self.tk.call('tk_mbButtonDown', self._w) + def tk_popup(self, x, y, entry=""): + """Post the menu at position X,Y with entry ENTRY.""" + self.tk.call('tk_popup', self._w, x, y, entry) + def activate(self, index): + """Activate entry at INDEX.""" + self.tk.call(self._w, 'activate', index) + def add(self, itemType, cnf={}, **kw): + """Internal function.""" + self.tk.call((self._w, 'add', itemType) + + self._options(cnf, kw)) + def add_cascade(self, cnf={}, **kw): + """Add hierarchical menu item.""" + self.add('cascade', cnf or kw) + def add_checkbutton(self, cnf={}, **kw): + """Add checkbutton menu item.""" + self.add('checkbutton', cnf or kw) + def add_command(self, cnf={}, **kw): + """Add command menu item.""" + self.add('command', cnf or kw) + def add_radiobutton(self, cnf={}, **kw): + """Addd radio menu item.""" + self.add('radiobutton', cnf or kw) + def add_separator(self, cnf={}, **kw): + """Add separator.""" + self.add('separator', cnf or kw) + def insert(self, index, itemType, cnf={}, **kw): + """Internal function.""" + self.tk.call((self._w, 'insert', index, itemType) + + self._options(cnf, kw)) + def insert_cascade(self, index, cnf={}, **kw): + """Add hierarchical menu item at INDEX.""" + self.insert(index, 'cascade', cnf or kw) + def insert_checkbutton(self, index, cnf={}, **kw): + """Add checkbutton menu item at INDEX.""" + self.insert(index, 'checkbutton', cnf or kw) + def insert_command(self, index, cnf={}, **kw): + """Add command menu item at INDEX.""" + self.insert(index, 'command', cnf or kw) + def insert_radiobutton(self, index, cnf={}, **kw): + """Addd radio menu item at INDEX.""" + self.insert(index, 'radiobutton', cnf or kw) + def insert_separator(self, index, cnf={}, **kw): + """Add separator at INDEX.""" + self.insert(index, 'separator', cnf or kw) + def delete(self, index1, index2=None): + """Delete menu items between INDEX1 and INDEX2 (included).""" + if index2 is None: + index2 = index1 + + num_index1, num_index2 = self.index(index1), self.index(index2) + if (num_index1 is None) or (num_index2 is None): + num_index1, num_index2 = 0, -1 + + for i in range(num_index1, num_index2 + 1): + if 'command' in self.entryconfig(i): + c = str(self.entrycget(i, 'command')) + if c: + self.deletecommand(c) + self.tk.call(self._w, 'delete', index1, index2) + def entrycget(self, index, option): + """Return the resource value of an menu item for OPTION at INDEX.""" + return self.tk.call(self._w, 'entrycget', index, '-' + option) + def entryconfigure(self, index, cnf=None, **kw): + """Configure a menu item at INDEX.""" + return self._configure(('entryconfigure', index), cnf, kw) + entryconfig = entryconfigure + def index(self, index): + """Return the index of a menu item identified by INDEX.""" + i = self.tk.call(self._w, 'index', index) + if i == 'none': return None + return getint(i) + def invoke(self, index): + """Invoke a menu item identified by INDEX and execute + the associated command.""" + return self.tk.call(self._w, 'invoke', index) + def post(self, x, y): + """Display a menu at position X,Y.""" + self.tk.call(self._w, 'post', x, y) + def type(self, index): + """Return the type of the menu item at INDEX.""" + return self.tk.call(self._w, 'type', index) + def unpost(self): + """Unmap a menu.""" + self.tk.call(self._w, 'unpost') + def yposition(self, index): + """Return the y-position of the topmost pixel of the menu item at INDEX.""" + return getint(self.tk.call( + self._w, 'yposition', index)) + +class Menubutton(Widget): + """Menubutton widget, obsolete since Tk8.0.""" + def __init__(self, master=None, cnf={}, **kw): + Widget.__init__(self, master, 'menubutton', cnf, kw) + +class Message(Widget): + """Message widget to display multiline text. Obsolete since Label does it too.""" + def __init__(self, master=None, cnf={}, **kw): + Widget.__init__(self, master, 'message', cnf, kw) + +class Radiobutton(Widget): + """Radiobutton widget which shows only one of several buttons in on-state.""" + def __init__(self, master=None, cnf={}, **kw): + """Construct a radiobutton widget with the parent MASTER. + + Valid resource names: activebackground, activeforeground, anchor, + background, bd, bg, bitmap, borderwidth, command, cursor, + disabledforeground, fg, font, foreground, height, + highlightbackground, highlightcolor, highlightthickness, image, + indicatoron, justify, padx, pady, relief, selectcolor, selectimage, + state, takefocus, text, textvariable, underline, value, variable, + width, wraplength.""" + Widget.__init__(self, master, 'radiobutton', cnf, kw) + def deselect(self): + """Put the button in off-state.""" + + self.tk.call(self._w, 'deselect') + def flash(self): + """Flash the button.""" + self.tk.call(self._w, 'flash') + def invoke(self): + """Toggle the button and invoke a command if given as resource.""" + return self.tk.call(self._w, 'invoke') + def select(self): + """Put the button in on-state.""" + self.tk.call(self._w, 'select') + +class Scale(Widget): + """Scale widget which can display a numerical scale.""" + def __init__(self, master=None, cnf={}, **kw): + """Construct a scale widget with the parent MASTER. + + Valid resource names: activebackground, background, bigincrement, bd, + bg, borderwidth, command, cursor, digits, fg, font, foreground, from, + highlightbackground, highlightcolor, highlightthickness, label, + length, orient, relief, repeatdelay, repeatinterval, resolution, + showvalue, sliderlength, sliderrelief, state, takefocus, + tickinterval, to, troughcolor, variable, width.""" + Widget.__init__(self, master, 'scale', cnf, kw) + def get(self): + """Get the current value as integer or float.""" + value = self.tk.call(self._w, 'get') + try: + return getint(value) + except ValueError: + return getdouble(value) + def set(self, value): + """Set the value to VALUE.""" + self.tk.call(self._w, 'set', value) + def coords(self, value=None): + """Return a tuple (X,Y) of the point along the centerline of the + trough that corresponds to VALUE or the current value if None is + given.""" + + return self._getints(self.tk.call(self._w, 'coords', value)) + def identify(self, x, y): + """Return where the point X,Y lies. Valid return values are "slider", + "though1" and "though2".""" + return self.tk.call(self._w, 'identify', x, y) + +class Scrollbar(Widget): + """Scrollbar widget which displays a slider at a certain position.""" + def __init__(self, master=None, cnf={}, **kw): + """Construct a scrollbar widget with the parent MASTER. + + Valid resource names: activebackground, activerelief, + background, bd, bg, borderwidth, command, cursor, + elementborderwidth, highlightbackground, + highlightcolor, highlightthickness, jump, orient, + relief, repeatdelay, repeatinterval, takefocus, + troughcolor, width.""" + Widget.__init__(self, master, 'scrollbar', cnf, kw) + def activate(self, index): + """Display the element at INDEX with activebackground and activerelief. + INDEX can be "arrow1","slider" or "arrow2".""" + self.tk.call(self._w, 'activate', index) + def delta(self, deltax, deltay): + """Return the fractional change of the scrollbar setting if it + would be moved by DELTAX or DELTAY pixels.""" + return getdouble( + self.tk.call(self._w, 'delta', deltax, deltay)) + def fraction(self, x, y): + """Return the fractional value which corresponds to a slider + position of X,Y.""" + return getdouble(self.tk.call(self._w, 'fraction', x, y)) + def identify(self, x, y): + """Return the element under position X,Y as one of + "arrow1","slider","arrow2" or "".""" + return self.tk.call(self._w, 'identify', x, y) + def get(self): + """Return the current fractional values (upper and lower end) + of the slider position.""" + return self._getdoubles(self.tk.call(self._w, 'get')) + def set(self, *args): + """Set the fractional values of the slider position (upper and + lower ends as value between 0 and 1).""" + self.tk.call((self._w, 'set') + args) + + + +class Text(Widget, XView, YView): + """Text widget which can display text in various forms.""" + def __init__(self, master=None, cnf={}, **kw): + """Construct a text widget with the parent MASTER. + + STANDARD OPTIONS + + background, borderwidth, cursor, + exportselection, font, foreground, + highlightbackground, highlightcolor, + highlightthickness, insertbackground, + insertborderwidth, insertofftime, + insertontime, insertwidth, padx, pady, + relief, selectbackground, + selectborderwidth, selectforeground, + setgrid, takefocus, + xscrollcommand, yscrollcommand, + + WIDGET-SPECIFIC OPTIONS + + autoseparators, height, maxundo, + spacing1, spacing2, spacing3, + state, tabs, undo, width, wrap, + + """ + Widget.__init__(self, master, 'text', cnf, kw) + def bbox(self, *args): + """Return a tuple of (x,y,width,height) which gives the bounding + box of the visible part of the character at the index in ARGS.""" + return self._getints( + self.tk.call((self._w, 'bbox') + args)) or None + def tk_textSelectTo(self, index): + self.tk.call('tk_textSelectTo', self._w, index) + def tk_textBackspace(self): + self.tk.call('tk_textBackspace', self._w) + def tk_textIndexCloser(self, a, b, c): + self.tk.call('tk_textIndexCloser', self._w, a, b, c) + def tk_textResetAnchor(self, index): + self.tk.call('tk_textResetAnchor', self._w, index) + def compare(self, index1, op, index2): + """Return whether between index INDEX1 and index INDEX2 the + relation OP is satisfied. OP is one of <, <=, ==, >=, >, or !=.""" + return self.tk.getboolean(self.tk.call( + self._w, 'compare', index1, op, index2)) + def debug(self, boolean=None): + """Turn on the internal consistency checks of the B-Tree inside the text + widget according to BOOLEAN.""" + if boolean is None: + return self.tk.getboolean(self.tk.call(self._w, 'debug')) + self.tk.call(self._w, 'debug', boolean) + def delete(self, index1, index2=None): + """Delete the characters between INDEX1 and INDEX2 (not included).""" + self.tk.call(self._w, 'delete', index1, index2) + def dlineinfo(self, index): + """Return tuple (x,y,width,height,baseline) giving the bounding box + and baseline position of the visible part of the line containing + the character at INDEX.""" + return self._getints(self.tk.call(self._w, 'dlineinfo', index)) + def dump(self, index1, index2=None, command=None, **kw): + """Return the contents of the widget between index1 and index2. + + The type of contents returned in filtered based on the keyword + parameters; if 'all', 'image', 'mark', 'tag', 'text', or 'window' are + given and true, then the corresponding items are returned. The result + is a list of triples of the form (key, value, index). If none of the + keywords are true then 'all' is used by default. + + If the 'command' argument is given, it is called once for each element + of the list of triples, with the values of each triple serving as the + arguments to the function. In this case the list is not returned.""" + args = [] + func_name = None + result = None + if not command: + # Never call the dump command without the -command flag, since the + # output could involve Tcl quoting and would be a pain to parse + # right. Instead just set the command to build a list of triples + # as if we had done the parsing. + result = [] + def append_triple(key, value, index, result=result): + result.append((key, value, index)) + command = append_triple + try: + if not isinstance(command, str): + func_name = command = self._register(command) + args += ["-command", command] + for key in kw: + if kw[key]: args.append("-" + key) + args.append(index1) + if index2: + args.append(index2) + self.tk.call(self._w, "dump", *args) + return result + finally: + if func_name: + self.deletecommand(func_name) + + ## new in tk8.4 + def edit(self, *args): + """Internal method + + This method controls the undo mechanism and + the modified flag. The exact behavior of the + command depends on the option argument that + follows the edit argument. The following forms + of the command are currently supported: + + edit_modified, edit_redo, edit_reset, edit_separator + and edit_undo + + """ + return self.tk.call(self._w, 'edit', *args) + + def edit_modified(self, arg=None): + """Get or Set the modified flag + + If arg is not specified, returns the modified + flag of the widget. The insert, delete, edit undo and + edit redo commands or the user can set or clear the + modified flag. If boolean is specified, sets the + modified flag of the widget to arg. + """ + return self.edit("modified", arg) + + def edit_redo(self): + """Redo the last undone edit + + When the undo option is true, reapplies the last + undone edits provided no other edits were done since + then. Generates an error when the redo stack is empty. + Does nothing when the undo option is false. + """ + return self.edit("redo") + + def edit_reset(self): + """Clears the undo and redo stacks + """ + return self.edit("reset") + + def edit_separator(self): + """Inserts a separator (boundary) on the undo stack. + + Does nothing when the undo option is false + """ + return self.edit("separator") + + def edit_undo(self): + """Undoes the last edit action + + If the undo option is true. An edit action is defined + as all the insert and delete commands that are recorded + on the undo stack in between two separators. Generates + an error when the undo stack is empty. Does nothing + when the undo option is false + """ + return self.edit("undo") + + def get(self, index1, index2=None): + """Return the text from INDEX1 to INDEX2 (not included).""" + return self.tk.call(self._w, 'get', index1, index2) + # (Image commands are new in 8.0) + def image_cget(self, index, option): + """Return the value of OPTION of an embedded image at INDEX.""" + if option[:1] != "-": + option = "-" + option + if option[-1:] == "_": + option = option[:-1] + return self.tk.call(self._w, "image", "cget", index, option) + def image_configure(self, index, cnf=None, **kw): + """Configure an embedded image at INDEX.""" + return self._configure(('image', 'configure', index), cnf, kw) + def image_create(self, index, cnf={}, **kw): + """Create an embedded image at INDEX.""" + return self.tk.call( + self._w, "image", "create", index, + *self._options(cnf, kw)) + def image_names(self): + """Return all names of embedded images in this widget.""" + return self.tk.call(self._w, "image", "names") + def index(self, index): + """Return the index in the form line.char for INDEX.""" + return str(self.tk.call(self._w, 'index', index)) + def insert(self, index, chars, *args): + """Insert CHARS before the characters at INDEX. An additional + tag can be given in ARGS. Additional CHARS and tags can follow in ARGS.""" + self.tk.call((self._w, 'insert', index, chars) + args) + def mark_gravity(self, markName, direction=None): + """Change the gravity of a mark MARKNAME to DIRECTION (LEFT or RIGHT). + Return the current value if None is given for DIRECTION.""" + return self.tk.call( + (self._w, 'mark', 'gravity', markName, direction)) + def mark_names(self): + """Return all mark names.""" + return self.tk.splitlist(self.tk.call( + self._w, 'mark', 'names')) + def mark_set(self, markName, index): + """Set mark MARKNAME before the character at INDEX.""" + self.tk.call(self._w, 'mark', 'set', markName, index) + def mark_unset(self, *markNames): + """Delete all marks in MARKNAMES.""" + self.tk.call((self._w, 'mark', 'unset') + markNames) + def mark_next(self, index): + """Return the name of the next mark after INDEX.""" + return self.tk.call(self._w, 'mark', 'next', index) or None + def mark_previous(self, index): + """Return the name of the previous mark before INDEX.""" + return self.tk.call(self._w, 'mark', 'previous', index) or None + def scan_mark(self, x, y): + """Remember the current X, Y coordinates.""" + self.tk.call(self._w, 'scan', 'mark', x, y) + def scan_dragto(self, x, y): + """Adjust the view of the text to 10 times the + difference between X and Y and the coordinates given in + scan_mark.""" + self.tk.call(self._w, 'scan', 'dragto', x, y) + def search(self, pattern, index, stopindex=None, + forwards=None, backwards=None, exact=None, + regexp=None, nocase=None, count=None, elide=None): + """Search PATTERN beginning from INDEX until STOPINDEX. + Return the index of the first character of a match or an + empty string.""" + args = [self._w, 'search'] + if forwards: args.append('-forwards') + if backwards: args.append('-backwards') + if exact: args.append('-exact') + if regexp: args.append('-regexp') + if nocase: args.append('-nocase') + if elide: args.append('-elide') + if count: args.append('-count'); args.append(count) + if pattern and pattern[0] == '-': args.append('--') + args.append(pattern) + args.append(index) + if stopindex: args.append(stopindex) + return str(self.tk.call(tuple(args))) + def see(self, index): + """Scroll such that the character at INDEX is visible.""" + self.tk.call(self._w, 'see', index) + def tag_add(self, tagName, index1, *args): + """Add tag TAGNAME to all characters between INDEX1 and index2 in ARGS. + Additional pairs of indices may follow in ARGS.""" + self.tk.call( + (self._w, 'tag', 'add', tagName, index1) + args) + def tag_unbind(self, tagName, sequence, funcid=None): + """Unbind for all characters with TAGNAME for event SEQUENCE the + function identified with FUNCID.""" + self.tk.call(self._w, 'tag', 'bind', tagName, sequence, '') + if funcid: + self.deletecommand(funcid) + def tag_bind(self, tagName, sequence, func, add=None): + """Bind to all characters with TAGNAME at event SEQUENCE a call to function FUNC. + + An additional boolean parameter ADD specifies whether FUNC will be + called additionally to the other bound function or whether it will + replace the previous function. See bind for the return value.""" + return self._bind((self._w, 'tag', 'bind', tagName), + sequence, func, add) + def tag_cget(self, tagName, option): + """Return the value of OPTION for tag TAGNAME.""" + if option[:1] != '-': + option = '-' + option + if option[-1:] == '_': + option = option[:-1] + return self.tk.call(self._w, 'tag', 'cget', tagName, option) + def tag_configure(self, tagName, cnf=None, **kw): + """Configure a tag TAGNAME.""" + return self._configure(('tag', 'configure', tagName), cnf, kw) + tag_config = tag_configure + def tag_delete(self, *tagNames): + """Delete all tags in TAGNAMES.""" + self.tk.call((self._w, 'tag', 'delete') + tagNames) + def tag_lower(self, tagName, belowThis=None): + """Change the priority of tag TAGNAME such that it is lower + than the priority of BELOWTHIS.""" + self.tk.call(self._w, 'tag', 'lower', tagName, belowThis) + def tag_names(self, index=None): + """Return a list of all tag names.""" + return self.tk.splitlist( + self.tk.call(self._w, 'tag', 'names', index)) + def tag_nextrange(self, tagName, index1, index2=None): + """Return a list of start and end index for the first sequence of + characters between INDEX1 and INDEX2 which all have tag TAGNAME. + The text is searched forward from INDEX1.""" + return self.tk.splitlist(self.tk.call( + self._w, 'tag', 'nextrange', tagName, index1, index2)) + def tag_prevrange(self, tagName, index1, index2=None): + """Return a list of start and end index for the first sequence of + characters between INDEX1 and INDEX2 which all have tag TAGNAME. + The text is searched backwards from INDEX1.""" + return self.tk.splitlist(self.tk.call( + self._w, 'tag', 'prevrange', tagName, index1, index2)) + def tag_raise(self, tagName, aboveThis=None): + """Change the priority of tag TAGNAME such that it is higher + than the priority of ABOVETHIS.""" + self.tk.call( + self._w, 'tag', 'raise', tagName, aboveThis) + def tag_ranges(self, tagName): + """Return a list of ranges of text which have tag TAGNAME.""" + return self.tk.splitlist(self.tk.call( + self._w, 'tag', 'ranges', tagName)) + def tag_remove(self, tagName, index1, index2=None): + """Remove tag TAGNAME from all characters between INDEX1 and INDEX2.""" + self.tk.call( + self._w, 'tag', 'remove', tagName, index1, index2) + def window_cget(self, index, option): + """Return the value of OPTION of an embedded window at INDEX.""" + if option[:1] != '-': + option = '-' + option + if option[-1:] == '_': + option = option[:-1] + return self.tk.call(self._w, 'window', 'cget', index, option) + def window_configure(self, index, cnf=None, **kw): + """Configure an embedded window at INDEX.""" + return self._configure(('window', 'configure', index), cnf, kw) + window_config = window_configure + def window_create(self, index, cnf={}, **kw): + """Create a window at INDEX.""" + self.tk.call( + (self._w, 'window', 'create', index) + + self._options(cnf, kw)) + def window_names(self): + """Return all names of embedded windows in this widget.""" + return self.tk.splitlist( + self.tk.call(self._w, 'window', 'names')) + def yview_pickplace(self, *what): + """Obsolete function, use see.""" + self.tk.call((self._w, 'yview', '-pickplace') + what) + + +class _setit: + """Internal class. It wraps the command in the widget OptionMenu.""" + def __init__(self, var, value, callback=None): + self.__value = value + self.__var = var + self.__callback = callback + def __call__(self, *args): + self.__var.set(self.__value) + if self.__callback: + self.__callback(self.__value, *args) + +class OptionMenu(Menubutton): + """OptionMenu which allows the user to select a value from a menu.""" + def __init__(self, master, variable, value, *values, **kwargs): + """Construct an optionmenu widget with the parent MASTER, with + the resource textvariable set to VARIABLE, the initially selected + value VALUE, the other menu values VALUES and an additional + keyword argument command.""" + kw = {"borderwidth": 2, "textvariable": variable, + "indicatoron": 1, "relief": RAISED, "anchor": "c", + "highlightthickness": 2} + Widget.__init__(self, master, "menubutton", kw) + self.widgetName = 'tk_optionMenu' + menu = self.__menu = Menu(self, name="menu", tearoff=0) + self.menuname = menu._w + # 'command' is the only supported keyword + callback = kwargs.get('command') + if 'command' in kwargs: + del kwargs['command'] + if kwargs: + raise TclError, 'unknown option -'+kwargs.keys()[0] + menu.add_command(label=value, + command=_setit(variable, value, callback)) + for v in values: + menu.add_command(label=v, + command=_setit(variable, v, callback)) + self["menu"] = menu + + def __getitem__(self, name): + if name == 'menu': + return self.__menu + return Widget.__getitem__(self, name) + + def destroy(self): + """Destroy this widget and the associated menu.""" + Menubutton.destroy(self) + self.__menu = None + +class Image: + """Base class for images.""" + _last_id = 0 + def __init__(self, imgtype, name=None, cnf={}, master=None, **kw): + self.name = None + if not master: + master = _default_root + if not master: + raise RuntimeError, 'Too early to create image' + self.tk = master.tk + if not name: + Image._last_id += 1 + name = "pyimage%r" % (Image._last_id,) # tk itself would use image + # The following is needed for systems where id(x) + # can return a negative number, such as Linux/m68k: + if name[0] == '-': name = '_' + name[1:] + if kw and cnf: cnf = _cnfmerge((cnf, kw)) + elif kw: cnf = kw + options = () + for k, v in cnf.items(): + if hasattr(v, '__call__'): + v = self._register(v) + options = options + ('-'+k, v) + self.tk.call(('image', 'create', imgtype, name,) + options) + self.name = name + def __str__(self): return self.name + def __del__(self): + if self.name: + try: + self.tk.call('image', 'delete', self.name) + except TclError: + # May happen if the root was destroyed + pass + def __setitem__(self, key, value): + self.tk.call(self.name, 'configure', '-'+key, value) + def __getitem__(self, key): + return self.tk.call(self.name, 'configure', '-'+key) + def configure(self, **kw): + """Configure the image.""" + res = () + for k, v in _cnfmerge(kw).items(): + if v is not None: + if k[-1] == '_': k = k[:-1] + if hasattr(v, '__call__'): + v = self._register(v) + res = res + ('-'+k, v) + self.tk.call((self.name, 'config') + res) + config = configure + def height(self): + """Return the height of the image.""" + return getint( + self.tk.call('image', 'height', self.name)) + def type(self): + """Return the type of the imgage, e.g. "photo" or "bitmap".""" + return self.tk.call('image', 'type', self.name) + def width(self): + """Return the width of the image.""" + return getint( + self.tk.call('image', 'width', self.name)) + +class PhotoImage(Image): + """Widget which can display colored images in GIF, PPM/PGM format.""" + def __init__(self, name=None, cnf={}, master=None, **kw): + """Create an image with NAME. + + Valid resource names: data, format, file, gamma, height, palette, + width.""" + Image.__init__(self, 'photo', name, cnf, master, **kw) + def blank(self): + """Display a transparent image.""" + self.tk.call(self.name, 'blank') + def cget(self, option): + """Return the value of OPTION.""" + return self.tk.call(self.name, 'cget', '-' + option) + # XXX config + def __getitem__(self, key): + return self.tk.call(self.name, 'cget', '-' + key) + # XXX copy -from, -to, ...? + def copy(self): + """Return a new PhotoImage with the same image as this widget.""" + destImage = PhotoImage() + self.tk.call(destImage, 'copy', self.name) + return destImage + def zoom(self,x,y=''): + """Return a new PhotoImage with the same image as this widget + but zoom it with X and Y.""" + destImage = PhotoImage() + if y=='': y=x + self.tk.call(destImage, 'copy', self.name, '-zoom',x,y) + return destImage + def subsample(self,x,y=''): + """Return a new PhotoImage based on the same image as this widget + but use only every Xth or Yth pixel.""" + destImage = PhotoImage() + if y=='': y=x + self.tk.call(destImage, 'copy', self.name, '-subsample',x,y) + return destImage + def get(self, x, y): + """Return the color (red, green, blue) of the pixel at X,Y.""" + return self.tk.call(self.name, 'get', x, y) + def put(self, data, to=None): + """Put row formatted colors to image starting from + position TO, e.g. image.put("{red green} {blue yellow}", to=(4,6))""" + args = (self.name, 'put', data) + if to: + if to[0] == '-to': + to = to[1:] + args = args + ('-to',) + tuple(to) + self.tk.call(args) + # XXX read + def write(self, filename, format=None, from_coords=None): + """Write image to file FILENAME in FORMAT starting from + position FROM_COORDS.""" + args = (self.name, 'write', filename) + if format: + args = args + ('-format', format) + if from_coords: + args = args + ('-from',) + tuple(from_coords) + self.tk.call(args) + +class BitmapImage(Image): + """Widget which can display a bitmap.""" + def __init__(self, name=None, cnf={}, master=None, **kw): + """Create a bitmap with NAME. + + Valid resource names: background, data, file, foreground, maskdata, maskfile.""" + Image.__init__(self, 'bitmap', name, cnf, master, **kw) + +def image_names(): + return _default_root.tk.splitlist(_default_root.tk.call('image', 'names')) + +def image_types(): + return _default_root.tk.splitlist(_default_root.tk.call('image', 'types')) + + +class Spinbox(Widget, XView): + """spinbox widget.""" + def __init__(self, master=None, cnf={}, **kw): + """Construct a spinbox widget with the parent MASTER. + + STANDARD OPTIONS + + activebackground, background, borderwidth, + cursor, exportselection, font, foreground, + highlightbackground, highlightcolor, + highlightthickness, insertbackground, + insertborderwidth, insertofftime, + insertontime, insertwidth, justify, relief, + repeatdelay, repeatinterval, + selectbackground, selectborderwidth + selectforeground, takefocus, textvariable + xscrollcommand. + + WIDGET-SPECIFIC OPTIONS + + buttonbackground, buttoncursor, + buttondownrelief, buttonuprelief, + command, disabledbackground, + disabledforeground, format, from, + invalidcommand, increment, + readonlybackground, state, to, + validate, validatecommand values, + width, wrap, + """ + Widget.__init__(self, master, 'spinbox', cnf, kw) + + def bbox(self, index): + """Return a tuple of X1,Y1,X2,Y2 coordinates for a + rectangle which encloses the character given by index. + + The first two elements of the list give the x and y + coordinates of the upper-left corner of the screen + area covered by the character (in pixels relative + to the widget) and the last two elements give the + width and height of the character, in pixels. The + bounding box may refer to a region outside the + visible area of the window. + """ + return self._getints(self.tk.call(self._w, 'bbox', index)) or None + + def delete(self, first, last=None): + """Delete one or more elements of the spinbox. + + First is the index of the first character to delete, + and last is the index of the character just after + the last one to delete. If last isn't specified it + defaults to first+1, i.e. a single character is + deleted. This command returns an empty string. + """ + return self.tk.call(self._w, 'delete', first, last) + + def get(self): + """Returns the spinbox's string""" + return self.tk.call(self._w, 'get') + + def icursor(self, index): + """Alter the position of the insertion cursor. + + The insertion cursor will be displayed just before + the character given by index. Returns an empty string + """ + return self.tk.call(self._w, 'icursor', index) + + def identify(self, x, y): + """Returns the name of the widget at position x, y + + Return value is one of: none, buttondown, buttonup, entry + """ + return self.tk.call(self._w, 'identify', x, y) + + def index(self, index): + """Returns the numerical index corresponding to index + """ + return self.tk.call(self._w, 'index', index) + + def insert(self, index, s): + """Insert string s at index + + Returns an empty string. + """ + return self.tk.call(self._w, 'insert', index, s) + + def invoke(self, element): + """Causes the specified element to be invoked + + The element could be buttondown or buttonup + triggering the action associated with it. + """ + return self.tk.call(self._w, 'invoke', element) + + def scan(self, *args): + """Internal function.""" + return self._getints( + self.tk.call((self._w, 'scan') + args)) or () + + def scan_mark(self, x): + """Records x and the current view in the spinbox window; + + used in conjunction with later scan dragto commands. + Typically this command is associated with a mouse button + press in the widget. It returns an empty string. + """ + return self.scan("mark", x) + + def scan_dragto(self, x): + """Compute the difference between the given x argument + and the x argument to the last scan mark command + + It then adjusts the view left or right by 10 times the + difference in x-coordinates. This command is typically + associated with mouse motion events in the widget, to + produce the effect of dragging the spinbox at high speed + through the window. The return value is an empty string. + """ + return self.scan("dragto", x) + + def selection(self, *args): + """Internal function.""" + return self._getints( + self.tk.call((self._w, 'selection') + args)) or () + + def selection_adjust(self, index): + """Locate the end of the selection nearest to the character + given by index, + + Then adjust that end of the selection to be at index + (i.e including but not going beyond index). The other + end of the selection is made the anchor point for future + select to commands. If the selection isn't currently in + the spinbox, then a new selection is created to include + the characters between index and the most recent selection + anchor point, inclusive. Returns an empty string. + """ + return self.selection("adjust", index) + + def selection_clear(self): + """Clear the selection + + If the selection isn't in this widget then the + command has no effect. Returns an empty string. + """ + return self.selection("clear") + + def selection_element(self, element=None): + """Sets or gets the currently selected element. + + If a spinbutton element is specified, it will be + displayed depressed + """ + return self.selection("element", element) + +########################################################################### + +class LabelFrame(Widget): + """labelframe widget.""" + def __init__(self, master=None, cnf={}, **kw): + """Construct a labelframe widget with the parent MASTER. + + STANDARD OPTIONS + + borderwidth, cursor, font, foreground, + highlightbackground, highlightcolor, + highlightthickness, padx, pady, relief, + takefocus, text + + WIDGET-SPECIFIC OPTIONS + + background, class, colormap, container, + height, labelanchor, labelwidget, + visual, width + """ + Widget.__init__(self, master, 'labelframe', cnf, kw) + +######################################################################## + +class PanedWindow(Widget): + """panedwindow widget.""" + def __init__(self, master=None, cnf={}, **kw): + """Construct a panedwindow widget with the parent MASTER. + + STANDARD OPTIONS + + background, borderwidth, cursor, height, + orient, relief, width + + WIDGET-SPECIFIC OPTIONS + + handlepad, handlesize, opaqueresize, + sashcursor, sashpad, sashrelief, + sashwidth, showhandle, + """ + Widget.__init__(self, master, 'panedwindow', cnf, kw) + + def add(self, child, **kw): + """Add a child widget to the panedwindow in a new pane. + + The child argument is the name of the child widget + followed by pairs of arguments that specify how to + manage the windows. The possible options and values + are the ones accepted by the paneconfigure method. + """ + self.tk.call((self._w, 'add', child) + self._options(kw)) + + def remove(self, child): + """Remove the pane containing child from the panedwindow + + All geometry management options for child will be forgotten. + """ + self.tk.call(self._w, 'forget', child) + forget=remove + + def identify(self, x, y): + """Identify the panedwindow component at point x, y + + If the point is over a sash or a sash handle, the result + is a two element list containing the index of the sash or + handle, and a word indicating whether it is over a sash + or a handle, such as {0 sash} or {2 handle}. If the point + is over any other part of the panedwindow, the result is + an empty list. + """ + return self.tk.call(self._w, 'identify', x, y) + + def proxy(self, *args): + """Internal function.""" + return self._getints( + self.tk.call((self._w, 'proxy') + args)) or () + + def proxy_coord(self): + """Return the x and y pair of the most recent proxy location + """ + return self.proxy("coord") + + def proxy_forget(self): + """Remove the proxy from the display. + """ + return self.proxy("forget") + + def proxy_place(self, x, y): + """Place the proxy at the given x and y coordinates. + """ + return self.proxy("place", x, y) + + def sash(self, *args): + """Internal function.""" + return self._getints( + self.tk.call((self._w, 'sash') + args)) or () + + def sash_coord(self, index): + """Return the current x and y pair for the sash given by index. + + Index must be an integer between 0 and 1 less than the + number of panes in the panedwindow. The coordinates given are + those of the top left corner of the region containing the sash. + pathName sash dragto index x y This command computes the + difference between the given coordinates and the coordinates + given to the last sash coord command for the given sash. It then + moves that sash the computed difference. The return value is the + empty string. + """ + return self.sash("coord", index) + + def sash_mark(self, index): + """Records x and y for the sash given by index; + + Used in conjunction with later dragto commands to move the sash. + """ + return self.sash("mark", index) + + def sash_place(self, index, x, y): + """Place the sash given by index at the given coordinates + """ + return self.sash("place", index, x, y) + + def panecget(self, child, option): + """Query a management option for window. + + Option may be any value allowed by the paneconfigure subcommand + """ + return self.tk.call( + (self._w, 'panecget') + (child, '-'+option)) + + def paneconfigure(self, tagOrId, cnf=None, **kw): + """Query or modify the management options for window. + + If no option is specified, returns a list describing all + of the available options for pathName. If option is + specified with no value, then the command returns a list + describing the one named option (this list will be identical + to the corresponding sublist of the value returned if no + option is specified). If one or more option-value pairs are + specified, then the command modifies the given widget + option(s) to have the given value(s); in this case the + command returns an empty string. The following options + are supported: + + after window + Insert the window after the window specified. window + should be the name of a window already managed by pathName. + before window + Insert the window before the window specified. window + should be the name of a window already managed by pathName. + height size + Specify a height for the window. The height will be the + outer dimension of the window including its border, if + any. If size is an empty string, or if -height is not + specified, then the height requested internally by the + window will be used initially; the height may later be + adjusted by the movement of sashes in the panedwindow. + Size may be any value accepted by Tk_GetPixels. + minsize n + Specifies that the size of the window cannot be made + less than n. This constraint only affects the size of + the widget in the paned dimension -- the x dimension + for horizontal panedwindows, the y dimension for + vertical panedwindows. May be any value accepted by + Tk_GetPixels. + padx n + Specifies a non-negative value indicating how much + extra space to leave on each side of the window in + the X-direction. The value may have any of the forms + accepted by Tk_GetPixels. + pady n + Specifies a non-negative value indicating how much + extra space to leave on each side of the window in + the Y-direction. The value may have any of the forms + accepted by Tk_GetPixels. + sticky style + If a window's pane is larger than the requested + dimensions of the window, this option may be used + to position (or stretch) the window within its pane. + Style is a string that contains zero or more of the + characters n, s, e or w. The string can optionally + contains spaces or commas, but they are ignored. Each + letter refers to a side (north, south, east, or west) + that the window will "stick" to. If both n and s + (or e and w) are specified, the window will be + stretched to fill the entire height (or width) of + its cavity. + width size + Specify a width for the window. The width will be + the outer dimension of the window including its + border, if any. If size is an empty string, or + if -width is not specified, then the width requested + internally by the window will be used initially; the + width may later be adjusted by the movement of sashes + in the panedwindow. Size may be any value accepted by + Tk_GetPixels. + + """ + if cnf is None and not kw: + return self._getconfigure(self._w, 'paneconfigure', tagOrId) + if type(cnf) == StringType and not kw: + return self._getconfigure1( + self._w, 'paneconfigure', tagOrId, '-'+cnf) + self.tk.call((self._w, 'paneconfigure', tagOrId) + + self._options(cnf, kw)) + paneconfig = paneconfigure + + def panes(self): + """Returns an ordered list of the child panes.""" + return self.tk.splitlist(self.tk.call(self._w, 'panes')) + +###################################################################### +# Extensions: + +class Studbutton(Button): + def __init__(self, master=None, cnf={}, **kw): + Widget.__init__(self, master, 'studbutton', cnf, kw) + self.bind('', self.tkButtonEnter) + self.bind('', self.tkButtonLeave) + self.bind('<1>', self.tkButtonDown) + self.bind('', self.tkButtonUp) + +class Tributton(Button): + def __init__(self, master=None, cnf={}, **kw): + Widget.__init__(self, master, 'tributton', cnf, kw) + self.bind('', self.tkButtonEnter) + self.bind('', self.tkButtonLeave) + self.bind('<1>', self.tkButtonDown) + self.bind('', self.tkButtonUp) + self['fg'] = self['bg'] + self['activebackground'] = self['bg'] + +###################################################################### +# Test: + +def _test(): + root = Tk() + text = "This is Tcl/Tk version %s" % TclVersion + if TclVersion >= 8.1: + try: + text = text + unicode("\nThis should be a cedilla: \347", + "iso-8859-1") + except NameError: + pass # no unicode support + label = Label(root, text=text) + label.pack() + test = Button(root, text="Click me!", + command=lambda root=root: root.test.configure( + text="[%s]" % root.test['text'])) + test.pack() + root.test = test + quit = Button(root, text="QUIT", command=root.destroy) + quit.pack() + # The following three commands are needed so the window pops + # up on top on Windows... + root.iconify() + root.update() + root.deiconify() + root.mainloop() + +if __name__ == '__main__': + _test() diff --git a/PythonHome/Lib/lib-tk/Tkinter.pyc b/PythonHome/Lib/lib-tk/Tkinter.pyc deleted file mode 100644 index 0fa768839c1757ff8ca0b38f0d9041a612767a62..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 189968 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 diff --git a/PythonHome/Lib/lib-tk/tkCommonDialog.py b/PythonHome/Lib/lib-tk/tkCommonDialog.py new file mode 100644 index 0000000000..2cd9be4eac --- /dev/null +++ b/PythonHome/Lib/lib-tk/tkCommonDialog.py @@ -0,0 +1,60 @@ +# base class for tk common dialogues +# +# this module provides a base class for accessing the common +# dialogues available in Tk 4.2 and newer. use tkFileDialog, +# tkColorChooser, and tkMessageBox to access the individual +# dialogs. +# +# written by Fredrik Lundh, May 1997 +# + +from Tkinter import * + +class Dialog: + + command = None + + def __init__(self, master=None, **options): + + # FIXME: should this be placed on the module level instead? + if TkVersion < 4.2: + raise TclError, "this module requires Tk 4.2 or newer" + + self.master = master + self.options = options + if not master and options.get('parent'): + self.master = options['parent'] + + def _fixoptions(self): + pass # hook + + def _fixresult(self, widget, result): + return result # hook + + def show(self, **options): + + # update instance options + for k, v in options.items(): + self.options[k] = v + + self._fixoptions() + + # we need a dummy widget to properly process the options + # (at least as long as we use Tkinter 1.63) + w = Frame(self.master) + + try: + + s = w.tk.call(self.command, *w._options(self.options)) + + s = self._fixresult(w, s) + + finally: + + try: + # get rid of the widget + w.destroy() + except: + pass + + return s diff --git a/PythonHome/Lib/lib-tk/tkCommonDialog.pyc b/PythonHome/Lib/lib-tk/tkCommonDialog.pyc deleted file mode 100644 index ef5a85265b4d6a46b339bf18a042512626610dab..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1426 zcmb7D&2G~`5T0Gwqy!Sd;K`vdt{@&jkeSAI8E~IZycRTK+g-4(0bkq z)J=`eotmoYimIqpHRPFHoo&|OkUqD7Z(DgdW?fExzUYgv@b<&gS!uT+8Xg^~Ay>zT zJzs~#VEzfq3KCY@IthLBMObwHB)0Pvw#NbtV% zp-z2G=Xe1kyhI~_OVj4@5_MV9ycP<6XwQxf_dR?y;9KEa@Rn)B}LvDuQ1l4$+l_`4p7D8lStuzVTTVPyXHfewq z;?^PlO-;D}*cq4Mz>P2*tE5Z1wpej0&TJK=m)xRG6eieRQJ+7GRJEDc@to%kuNVrE<}F4?@3gW*wfyzqSu$GJm?)S zdP@>b3?xhzy<-whv9Vv4=!RCtC8}s;LZWGjX5=OIpVa!S)~6(zlW1P+HzZon$rXt) zc~Oo%>Hft;OR_(s8Z1kDR`zG5_rpPRPWI;{o|D$RmJ1TC$b~0{U5nbaBp29nM)uO1 zQi_))UXi9J$5YZ>Gk8)Xzlw3(n-blXLjxqt{!QtvOMFXWbWT&;{;I^Q(z;EY%wBp& zurRtUkDtV|(z?Um=#H#DenMfccso;>l+C0ayIv=@RUa)!;qJ79 zKAt!0xFk!hn?U`uxc9Kz&APc_CG^<1-K^qQw6JTaeR!~)JUeJ7&+fb919$ug!gG~B z?DX6XOsF-J7k#PUMblEU7~i{VrcHwV561ysK0>%K#s=2M}Ch4J@LC*t+`m<9PD{zi7J9T%YAlptmaUr`DU5ZNU zCvlbfhb&as^CUWqomRWCJ#D*?rwOMy&b4|1{9e@rTul??!bl*y!sVvyRXiUynD$EM z7Jlcy91Ly<0|;iG`bUZWLE@+nJ+Q|?GwTNRU;t>~vLJ(4HHbT|0Z#7n2zV>sr~=;K&%?rR8dX@nRF=|0!@?>wb{4jTO;B=>VN^D-<> zrxE29t_~5s8ZBE8XvuU&*M4mEG_GEz`uF>4e9|yXpl8WCgO^VPdcub4<$`q&|u_l2S_+vmIlbq;AwHBLkUeC-a;`n=>Gr? z+4PDr?Mw7&?2z)53GbrS;HFf&fap7D5Evr`3;XxxxAbCF|K)849CL@YpJ2%_d<+aR zKl~oFBGQg~3Crjfz>17K!O{}C2$<*sGn{i|W zj6b58r?vh9?joeMgn=&4SDCVnN&!P3fG12dkYBv`CZpBX=WCijAd5AMjApJt2DiQW z@}BG=`@q6HZS6bqpCEOB)Youp2vh-+f~5TDU)?$JayUncN6d6`(4QDE$4dV@2QQH? z52k8+-jnqXq($L-sOFdR2dL#Sm{WIE@NsCNWU=W(*HnLky zJ)ZwxIQkRF9w2`?^Xy;TSE6YVuoRl`eF)8wEAY8C6#PyA6vH6)H*{PkCpz@2@(MQv z^Yx*c#a%h7oKlNs3-n`#Lc@1hynP_=SblO0A` z3AwrDtzK`pmAqC>{+?wXxS5@{qae)?SIO;1IP#B!JW7(7`Inr=ehrwH<%Az&N|hn5 zpOI}MiOkacOE*NfXu_-4W~gRW48F|)MwXDi5E9PtBNpFh@dFl1C>+BjzJv7F_Htin zXN@{O%BhZxUB5+d+TN@^*xuG0JZ;z7_4F`Fo0+Dzn@_hM?mqmbj{W?klXabbhicB_ z2>~;gi zoVT*Rva~Y3vOGD4zZ;c_%6w&Fa=cPTTJQTv?HA1o-co77_-5A3pd2%c-a={8{0Bcy B!y*6x diff --git a/PythonHome/Lib/lib-tk/tkFont.py b/PythonHome/Lib/lib-tk/tkFont.py new file mode 100644 index 0000000000..61c2f86abd --- /dev/null +++ b/PythonHome/Lib/lib-tk/tkFont.py @@ -0,0 +1,217 @@ +# Tkinter font wrapper +# +# written by Fredrik Lundh, February 1998 +# +# FIXME: should add 'displayof' option where relevant (actual, families, +# measure, and metrics) +# + +__version__ = "0.9" + +import Tkinter + +# weight/slant +NORMAL = "normal" +ROMAN = "roman" +BOLD = "bold" +ITALIC = "italic" + +def nametofont(name): + """Given the name of a tk named font, returns a Font representation. + """ + return Font(name=name, exists=True) + +class Font: + + """Represents a named font. + + Constructor options are: + + font -- font specifier (name, system font, or (family, size, style)-tuple) + name -- name to use for this font configuration (defaults to a unique name) + exists -- does a named font by this name already exist? + Creates a new named font if False, points to the existing font if True. + Raises _Tkinter.TclError if the assertion is false. + + the following are ignored if font is specified: + + family -- font 'family', e.g. Courier, Times, Helvetica + size -- font size in points + weight -- font thickness: NORMAL, BOLD + slant -- font slant: ROMAN, ITALIC + underline -- font underlining: false (0), true (1) + overstrike -- font strikeout: false (0), true (1) + + """ + + def _set(self, kw): + options = [] + for k, v in kw.items(): + options.append("-"+k) + options.append(str(v)) + return tuple(options) + + def _get(self, args): + options = [] + for k in args: + options.append("-"+k) + return tuple(options) + + def _mkdict(self, args): + options = {} + for i in range(0, len(args), 2): + options[args[i][1:]] = args[i+1] + return options + + def __init__(self, root=None, font=None, name=None, exists=False, **options): + if not root: + root = Tkinter._default_root + if font: + # get actual settings corresponding to the given font + font = root.tk.splitlist(root.tk.call("font", "actual", font)) + else: + font = self._set(options) + if not name: + name = "font" + str(id(self)) + self.name = name + + if exists: + self.delete_font = False + # confirm font exists + if self.name not in root.tk.splitlist( + root.tk.call("font", "names")): + raise Tkinter._tkinter.TclError, "named font %s does not already exist" % (self.name,) + # if font config info supplied, apply it + if font: + root.tk.call("font", "configure", self.name, *font) + else: + # create new font (raises TclError if the font exists) + root.tk.call("font", "create", self.name, *font) + self.delete_font = True + # backlinks! + self._root = root + self._split = root.tk.splitlist + self._call = root.tk.call + + def __str__(self): + return self.name + + def __eq__(self, other): + return self.name == other.name and isinstance(other, Font) + + def __getitem__(self, key): + return self.cget(key) + + def __setitem__(self, key, value): + self.configure(**{key: value}) + + def __del__(self): + try: + if self.delete_font: + self._call("font", "delete", self.name) + except (KeyboardInterrupt, SystemExit): + raise + except Exception: + pass + + def copy(self): + "Return a distinct copy of the current font" + return Font(self._root, **self.actual()) + + def actual(self, option=None): + "Return actual font attributes" + if option: + return self._call("font", "actual", self.name, "-"+option) + else: + return self._mkdict( + self._split(self._call("font", "actual", self.name)) + ) + + def cget(self, option): + "Get font attribute" + return self._call("font", "config", self.name, "-"+option) + + def config(self, **options): + "Modify font attributes" + if options: + self._call("font", "config", self.name, + *self._set(options)) + else: + return self._mkdict( + self._split(self._call("font", "config", self.name)) + ) + + configure = config + + def measure(self, text): + "Return text width" + return int(self._call("font", "measure", self.name, text)) + + def metrics(self, *options): + """Return font metrics. + + For best performance, create a dummy widget + using this font before calling this method.""" + + if options: + return int( + self._call("font", "metrics", self.name, self._get(options)) + ) + else: + res = self._split(self._call("font", "metrics", self.name)) + options = {} + for i in range(0, len(res), 2): + options[res[i][1:]] = int(res[i+1]) + return options + +def families(root=None): + "Get font families (as a tuple)" + if not root: + root = Tkinter._default_root + return root.tk.splitlist(root.tk.call("font", "families")) + +def names(root=None): + "Get names of defined fonts (as a tuple)" + if not root: + root = Tkinter._default_root + return root.tk.splitlist(root.tk.call("font", "names")) + +# -------------------------------------------------------------------- +# test stuff + +if __name__ == "__main__": + + root = Tkinter.Tk() + + # create a font + f = Font(family="times", size=30, weight=NORMAL) + + print f.actual() + print f.actual("family") + print f.actual("weight") + + print f.config() + print f.cget("family") + print f.cget("weight") + + print names() + + print f.measure("hello"), f.metrics("linespace") + + print f.metrics() + + f = Font(font=("Courier", 20, "bold")) + print f.measure("hello"), f.metrics("linespace") + + w = Tkinter.Label(root, text="Hello, world", font=f) + w.pack() + + w = Tkinter.Button(root, text="Quit!", command=root.destroy) + w.pack() + + fb = Font(font=w["font"]).copy() + fb.config(weight=BOLD) + + w.config(font=fb) + + Tkinter.mainloop() diff --git a/PythonHome/Lib/lib-tk/tkFont.pyc b/PythonHome/Lib/lib-tk/tkFont.pyc deleted file mode 100644 index 2d0daf3d5c3a90fd8c231620b18b3ceb4879c29e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6815 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 diff --git a/PythonHome/Lib/lib-tk/tkMessageBox.py b/PythonHome/Lib/lib-tk/tkMessageBox.py new file mode 100644 index 0000000000..9ee923576f --- /dev/null +++ b/PythonHome/Lib/lib-tk/tkMessageBox.py @@ -0,0 +1,134 @@ +# tk common message boxes +# +# this module provides an interface to the native message boxes +# available in Tk 4.2 and newer. +# +# written by Fredrik Lundh, May 1997 +# + +# +# options (all have default values): +# +# - default: which button to make default (one of the reply codes) +# +# - icon: which icon to display (see below) +# +# - message: the message to display +# +# - parent: which window to place the dialog on top of +# +# - title: dialog title +# +# - type: dialog type; that is, which buttons to display (see below) +# + +from tkCommonDialog import Dialog + +# +# constants + +# icons +ERROR = "error" +INFO = "info" +QUESTION = "question" +WARNING = "warning" + +# types +ABORTRETRYIGNORE = "abortretryignore" +OK = "ok" +OKCANCEL = "okcancel" +RETRYCANCEL = "retrycancel" +YESNO = "yesno" +YESNOCANCEL = "yesnocancel" + +# replies +ABORT = "abort" +RETRY = "retry" +IGNORE = "ignore" +OK = "ok" +CANCEL = "cancel" +YES = "yes" +NO = "no" + + +# +# message dialog class + +class Message(Dialog): + "A message box" + + command = "tk_messageBox" + + +# +# convenience stuff + +# Rename _icon and _type options to allow overriding them in options +def _show(title=None, message=None, _icon=None, _type=None, **options): + if _icon and "icon" not in options: options["icon"] = _icon + if _type and "type" not in options: options["type"] = _type + if title: options["title"] = title + if message: options["message"] = message + res = Message(**options).show() + # In some Tcl installations, yes/no is converted into a boolean. + if isinstance(res, bool): + if res: + return YES + return NO + # In others we get a Tcl_Obj. + return str(res) + +def showinfo(title=None, message=None, **options): + "Show an info message" + return _show(title, message, INFO, OK, **options) + +def showwarning(title=None, message=None, **options): + "Show a warning message" + return _show(title, message, WARNING, OK, **options) + +def showerror(title=None, message=None, **options): + "Show an error message" + return _show(title, message, ERROR, OK, **options) + +def askquestion(title=None, message=None, **options): + "Ask a question" + return _show(title, message, QUESTION, YESNO, **options) + +def askokcancel(title=None, message=None, **options): + "Ask if operation should proceed; return true if the answer is ok" + s = _show(title, message, QUESTION, OKCANCEL, **options) + return s == OK + +def askyesno(title=None, message=None, **options): + "Ask a question; return true if the answer is yes" + s = _show(title, message, QUESTION, YESNO, **options) + return s == YES + +def askyesnocancel(title=None, message=None, **options): + "Ask a question; return true if the answer is yes, None if cancelled." + s = _show(title, message, QUESTION, YESNOCANCEL, **options) + # s might be a Tcl index object, so convert it to a string + s = str(s) + if s == CANCEL: + return None + return s == YES + +def askretrycancel(title=None, message=None, **options): + "Ask if operation should be retried; return true if the answer is yes" + s = _show(title, message, WARNING, RETRYCANCEL, **options) + return s == RETRY + + +# -------------------------------------------------------------------- +# test stuff + +if __name__ == "__main__": + + print "info", showinfo("Spam", "Egg Information") + print "warning", showwarning("Spam", "Egg Warning") + print "error", showerror("Spam", "Egg Alert") + print "question", askquestion("Spam", "Question?") + print "proceed", askokcancel("Spam", "Proceed?") + print "yes/no", askyesno("Spam", "Got it?") + print "yes/no/cancel", askyesnocancel("Spam", "Want it?") + print "try again", askretrycancel("Spam", "Try again?") diff --git a/PythonHome/Lib/lib-tk/tkMessageBox.pyc b/PythonHome/Lib/lib-tk/tkMessageBox.pyc deleted file mode 100644 index df1ab0679254005e9948a264eb8dd125819eaaa5..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3729 zcmb_fS#uLd5bl*^`M|b}!R9hy0|CTka*%_BvN1+6E{GJbOu5)1rK~k;vyrsx?2HRs zWuD-b%0r&>KX}N$$`44s?wtigIUxp1yRGSOj_&DeM#aBIhF-4x+-#Hm^x^j=Uj3&- zr0_V@CF(ikJLISW`2|u%@{6QO5wEOn#YEKl%Nn2FM>EHAwy-sUh-*NF5;m z0I6Z}he?f)KSFAh{Ly@Th5QPsG4jVq9VGuCsc{M&T60JpqUS`8PJz;w z4$QF-LiR_bPSLXhE!=@o7D9*z;#vf72n~RIY>^TWC;{ZOMa}?$9zZ^^$XOsz1;{yz zoCgAJfK)AV0mzgf7c(S=(=Ji7dKq4f{>G;YPm(Ev+>U~7vToSNVVWkXDe;(iEinUV z{JI%x6D6_f2lF^c<0xJ?V`vAf7@CGA-HO)Z1dRf~q$87(PCJO(Vb>f0CSxqmLbgI3 zC(&tyUcL!dA-+0co{*iQ4Qk%ko<-m9%ZU zo%DJ^3{T+mn&>I8(+}@Os}H-;>J`&@XgXGFNSWT)@(yCab-bD-mYs5;Ee$Zd;k(@P z2go+U>lE)}yF{ISZUaFZ$PGAoyGZE_Ati113?tlK$hzTPN|AF>a)zSQ`!?!B>-{3&}|MT2q`}ZwRYRTII0tjxjk7B4Sz* zOJ+q{hDEcGWP?Lk%d|AqdvHs(5UVzib;OJ0jMIp`W&H9xUZ^-_r{t6hZH_C}l@$}8 zO`^f}#N&{`14|a@1xzOyC=uGk@@^2joOF3OR(TcgEYD^uF4n(q$mSb&vz}L*_RgSt zFFP8*c-|08TjDnBOz)vOZ!J^ZwS{39<=Olzb6$P1zTlll`$M(oio)7kiT9a(-wjM) za&CJmeY@z-fmHLnhPN-;4_fU-+Jg_#eH4@DbjJkL&kIxGs3W=m-bVNoi@fR2ckCI5=Ubchrm=?i5lGhYW{L1V z;|{zTdFO#7Cd6LlkY2;I|JdjZy8q4Fa5Wr`)4_Tk#}>|zYkXieITFfQBybMv+aP;2 z!ezIf#1a$P{h%AF>3VjwaP`c>f&C^qU?ai>FV~BVmlDg%?4R{GKXdD4igkc!zC0jU z3d7DY4vY^AncP~t<;`ly8IwluOr1Bw=mNBptC?3@_8wT{a0wKCU&6{7X6LOC>%R&v zd)Mj(QH%=}r&Dty=;;a?we@v(5rS`h?B#Vt!#rZxxcdOwoiJ6_ZRm%G xf7Rkfb}63W!lUnijFoYb", self.ok) + self.bind("", self.cancel) + + box.pack() + + # + # standard button semantics + + def ok(self, event=None): + + if not self.validate(): + self.initial_focus.focus_set() # put focus back + return + + self.withdraw() + self.update_idletasks() + + try: + self.apply() + finally: + self.cancel() + + def cancel(self, event=None): + + # put focus back to the parent window + if self.parent is not None: + self.parent.focus_set() + self.destroy() + + # + # command hooks + + def validate(self): + '''validate the data + + This method is called automatically to validate the data before the + dialog is destroyed. By default, it always validates OK. + ''' + + return 1 # override + + def apply(self): + '''process the data + + This method is called automatically to process the data, *after* + the dialog is destroyed. By default, it does nothing. + ''' + + pass # override + + +# -------------------------------------------------------------------- +# convenience dialogues + +class _QueryDialog(Dialog): + + def __init__(self, title, prompt, + initialvalue=None, + minvalue = None, maxvalue = None, + parent = None): + + if not parent: + import Tkinter + parent = Tkinter._default_root + + self.prompt = prompt + self.minvalue = minvalue + self.maxvalue = maxvalue + + self.initialvalue = initialvalue + + Dialog.__init__(self, parent, title) + + def destroy(self): + self.entry = None + Dialog.destroy(self) + + def body(self, master): + + w = Label(master, text=self.prompt, justify=LEFT) + w.grid(row=0, padx=5, sticky=W) + + self.entry = Entry(master, name="entry") + self.entry.grid(row=1, padx=5, sticky=W+E) + + if self.initialvalue is not None: + self.entry.insert(0, self.initialvalue) + self.entry.select_range(0, END) + + return self.entry + + def validate(self): + + import tkMessageBox + + try: + result = self.getresult() + except ValueError: + tkMessageBox.showwarning( + "Illegal value", + self.errormessage + "\nPlease try again", + parent = self + ) + return 0 + + if self.minvalue is not None and result < self.minvalue: + tkMessageBox.showwarning( + "Too small", + "The allowed minimum value is %s. " + "Please try again." % self.minvalue, + parent = self + ) + return 0 + + if self.maxvalue is not None and result > self.maxvalue: + tkMessageBox.showwarning( + "Too large", + "The allowed maximum value is %s. " + "Please try again." % self.maxvalue, + parent = self + ) + return 0 + + self.result = result + + return 1 + + +class _QueryInteger(_QueryDialog): + errormessage = "Not an integer." + def getresult(self): + return int(self.entry.get()) + +def askinteger(title, prompt, **kw): + '''get an integer from the user + + Arguments: + + title -- the dialog title + prompt -- the label text + **kw -- see SimpleDialog class + + Return value is an integer + ''' + d = _QueryInteger(title, prompt, **kw) + return d.result + +class _QueryFloat(_QueryDialog): + errormessage = "Not a floating point value." + def getresult(self): + return float(self.entry.get()) + +def askfloat(title, prompt, **kw): + '''get a float from the user + + Arguments: + + title -- the dialog title + prompt -- the label text + **kw -- see SimpleDialog class + + Return value is a float + ''' + d = _QueryFloat(title, prompt, **kw) + return d.result + +class _QueryString(_QueryDialog): + def __init__(self, *args, **kw): + if "show" in kw: + self.__show = kw["show"] + del kw["show"] + else: + self.__show = None + _QueryDialog.__init__(self, *args, **kw) + + def body(self, master): + entry = _QueryDialog.body(self, master) + if self.__show is not None: + entry.configure(show=self.__show) + return entry + + def getresult(self): + return self.entry.get() + +def askstring(title, prompt, **kw): + '''get a string from the user + + Arguments: + + title -- the dialog title + prompt -- the label text + **kw -- see SimpleDialog class + + Return value is a string + ''' + d = _QueryString(title, prompt, **kw) + return d.result + +if __name__ == "__main__": + + root = Tk() + root.update() + + print askinteger("Spam", "Egg count", initialvalue=12*12) + print askfloat("Spam", "Egg weight\n(in tons)", minvalue=1, maxvalue=100) + print askstring("Spam", "Egg label") diff --git a/PythonHome/Lib/lib-tk/tkSimpleDialog.pyc b/PythonHome/Lib/lib-tk/tkSimpleDialog.pyc deleted file mode 100644 index f247a08765f4a820525ba5984c1ba79f42ccb2c0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8723 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 diff --git a/PythonHome/Lib/lib-tk/ttk.py b/PythonHome/Lib/lib-tk/ttk.py new file mode 100644 index 0000000000..77f1d3a9b5 --- /dev/null +++ b/PythonHome/Lib/lib-tk/ttk.py @@ -0,0 +1,1624 @@ +"""Ttk wrapper. + +This module provides classes to allow using Tk themed widget set. + +Ttk is based on a revised and enhanced version of +TIP #48 (http://tip.tcl.tk/48) specified style engine. + +Its basic idea is to separate, to the extent possible, the code +implementing a widget's behavior from the code implementing its +appearance. Widget class bindings are primarily responsible for +maintaining the widget state and invoking callbacks, all aspects +of the widgets appearance lies at Themes. +""" + +__version__ = "0.3.1" + +__author__ = "Guilherme Polo " + +__all__ = ["Button", "Checkbutton", "Combobox", "Entry", "Frame", "Label", + "Labelframe", "LabelFrame", "Menubutton", "Notebook", "Panedwindow", + "PanedWindow", "Progressbar", "Radiobutton", "Scale", "Scrollbar", + "Separator", "Sizegrip", "Style", "Treeview", + # Extensions + "LabeledScale", "OptionMenu", + # functions + "tclobjs_to_py", "setup_master"] + +import Tkinter +from Tkinter import _flatten, _join, _stringify + +# Verify if Tk is new enough to not need the Tile package +_REQUIRE_TILE = True if Tkinter.TkVersion < 8.5 else False + +def _load_tile(master): + if _REQUIRE_TILE: + import os + tilelib = os.environ.get('TILE_LIBRARY') + if tilelib: + # append custom tile path to the list of directories that + # Tcl uses when attempting to resolve packages with the package + # command + master.tk.eval( + 'global auto_path; ' + 'lappend auto_path {%s}' % tilelib) + + master.tk.eval('package require tile') # TclError may be raised here + master._tile_loaded = True + +def _format_optvalue(value, script=False): + """Internal function.""" + if script: + # if caller passes a Tcl script to tk.call, all the values need to + # be grouped into words (arguments to a command in Tcl dialect) + value = _stringify(value) + elif isinstance(value, (list, tuple)): + value = _join(value) + return value + +def _format_optdict(optdict, script=False, ignore=None): + """Formats optdict to a tuple to pass it to tk.call. + + E.g. (script=False): + {'foreground': 'blue', 'padding': [1, 2, 3, 4]} returns: + ('-foreground', 'blue', '-padding', '1 2 3 4')""" + + opts = [] + for opt, value in optdict.iteritems(): + if not ignore or opt not in ignore: + opts.append("-%s" % opt) + if value is not None: + opts.append(_format_optvalue(value, script)) + + return _flatten(opts) + +def _mapdict_values(items): + # each value in mapdict is expected to be a sequence, where each item + # is another sequence containing a state (or several) and a value + # E.g. (script=False): + # [('active', 'selected', 'grey'), ('focus', [1, 2, 3, 4])] + # returns: + # ['active selected', 'grey', 'focus', [1, 2, 3, 4]] + opt_val = [] + for item in items: + state = item[:-1] + val = item[-1] + # hacks for bakward compatibility + state[0] # raise IndexError if empty + if len(state) == 1: + # if it is empty (something that evaluates to False), then + # format it to Tcl code to denote the "normal" state + state = state[0] or '' + else: + # group multiple states + state = ' '.join(state) # raise TypeError if not str + opt_val.append(state) + if val is not None: + opt_val.append(val) + return opt_val + +def _format_mapdict(mapdict, script=False): + """Formats mapdict to pass it to tk.call. + + E.g. (script=False): + {'expand': [('active', 'selected', 'grey'), ('focus', [1, 2, 3, 4])]} + + returns: + + ('-expand', '{active selected} grey focus {1, 2, 3, 4}')""" + + opts = [] + for opt, value in mapdict.iteritems(): + opts.extend(("-%s" % opt, + _format_optvalue(_mapdict_values(value), script))) + + return _flatten(opts) + +def _format_elemcreate(etype, script=False, *args, **kw): + """Formats args and kw according to the given element factory etype.""" + spec = None + opts = () + if etype in ("image", "vsapi"): + if etype == "image": # define an element based on an image + # first arg should be the default image name + iname = args[0] + # next args, if any, are statespec/value pairs which is almost + # a mapdict, but we just need the value + imagespec = _join(_mapdict_values(args[1:])) + spec = "%s %s" % (iname, imagespec) + + else: + # define an element whose visual appearance is drawn using the + # Microsoft Visual Styles API which is responsible for the + # themed styles on Windows XP and Vista. + # Availability: Tk 8.6, Windows XP and Vista. + class_name, part_id = args[:2] + statemap = _join(_mapdict_values(args[2:])) + spec = "%s %s %s" % (class_name, part_id, statemap) + + opts = _format_optdict(kw, script) + + elif etype == "from": # clone an element + # it expects a themename and optionally an element to clone from, + # otherwise it will clone {} (empty element) + spec = args[0] # theme name + if len(args) > 1: # elementfrom specified + opts = (_format_optvalue(args[1], script),) + + if script: + spec = '{%s}' % spec + opts = ' '.join(opts) + + return spec, opts + +def _format_layoutlist(layout, indent=0, indent_size=2): + """Formats a layout list so we can pass the result to ttk::style + layout and ttk::style settings. Note that the layout doesn't has to + be a list necessarily. + + E.g.: + [("Menubutton.background", None), + ("Menubutton.button", {"children": + [("Menubutton.focus", {"children": + [("Menubutton.padding", {"children": + [("Menubutton.label", {"side": "left", "expand": 1})] + })] + })] + }), + ("Menubutton.indicator", {"side": "right"}) + ] + + returns: + + Menubutton.background + Menubutton.button -children { + Menubutton.focus -children { + Menubutton.padding -children { + Menubutton.label -side left -expand 1 + } + } + } + Menubutton.indicator -side right""" + script = [] + + for layout_elem in layout: + elem, opts = layout_elem + opts = opts or {} + fopts = ' '.join(_format_optdict(opts, True, ("children",))) + head = "%s%s%s" % (' ' * indent, elem, (" %s" % fopts) if fopts else '') + + if "children" in opts: + script.append(head + " -children {") + indent += indent_size + newscript, indent = _format_layoutlist(opts['children'], indent, + indent_size) + script.append(newscript) + indent -= indent_size + script.append('%s}' % (' ' * indent)) + else: + script.append(head) + + return '\n'.join(script), indent + +def _script_from_settings(settings): + """Returns an appropriate script, based on settings, according to + theme_settings definition to be used by theme_settings and + theme_create.""" + script = [] + # a script will be generated according to settings passed, which + # will then be evaluated by Tcl + for name, opts in settings.iteritems(): + # will format specific keys according to Tcl code + if opts.get('configure'): # format 'configure' + s = ' '.join(_format_optdict(opts['configure'], True)) + script.append("ttk::style configure %s %s;" % (name, s)) + + if opts.get('map'): # format 'map' + s = ' '.join(_format_mapdict(opts['map'], True)) + script.append("ttk::style map %s %s;" % (name, s)) + + if 'layout' in opts: # format 'layout' which may be empty + if not opts['layout']: + s = 'null' # could be any other word, but this one makes sense + else: + s, _ = _format_layoutlist(opts['layout']) + script.append("ttk::style layout %s {\n%s\n}" % (name, s)) + + if opts.get('element create'): # format 'element create' + eopts = opts['element create'] + etype = eopts[0] + + # find where args end, and where kwargs start + argc = 1 # etype was the first one + while argc < len(eopts) and not hasattr(eopts[argc], 'iteritems'): + argc += 1 + + elemargs = eopts[1:argc] + elemkw = eopts[argc] if argc < len(eopts) and eopts[argc] else {} + spec, opts = _format_elemcreate(etype, True, *elemargs, **elemkw) + + script.append("ttk::style element create %s %s %s %s" % ( + name, etype, spec, opts)) + + return '\n'.join(script) + +def _dict_from_tcltuple(ttuple, cut_minus=True): + """Break tuple in pairs, format it properly, then build the return + dict. If cut_minus is True, the supposed '-' prefixing options will + be removed. + + ttuple is expected to contain an even number of elements.""" + opt_start = 1 if cut_minus else 0 + + retdict = {} + it = iter(ttuple) + for opt, val in zip(it, it): + retdict[str(opt)[opt_start:]] = val + + return tclobjs_to_py(retdict) + +def _list_from_statespec(stuple): + """Construct a list from the given statespec tuple according to the + accepted statespec accepted by _format_mapdict.""" + nval = [] + for val in stuple: + typename = getattr(val, 'typename', None) + if typename is None: + nval.append(val) + else: # this is a Tcl object + val = str(val) + if typename == 'StateSpec': + val = val.split() + nval.append(val) + + it = iter(nval) + return [_flatten(spec) for spec in zip(it, it)] + +def _list_from_layouttuple(tk, ltuple): + """Construct a list from the tuple returned by ttk::layout, this is + somewhat the reverse of _format_layoutlist.""" + ltuple = tk.splitlist(ltuple) + res = [] + + indx = 0 + while indx < len(ltuple): + name = ltuple[indx] + opts = {} + res.append((name, opts)) + indx += 1 + + while indx < len(ltuple): # grab name's options + opt, val = ltuple[indx:indx + 2] + if not opt.startswith('-'): # found next name + break + + opt = opt[1:] # remove the '-' from the option + indx += 2 + + if opt == 'children': + val = _list_from_layouttuple(tk, val) + + opts[opt] = val + + return res + +def _val_or_dict(tk, options, *args): + """Format options then call Tk command with args and options and return + the appropriate result. + + If no option is specified, a dict is returned. If a option is + specified with the None value, the value for that option is returned. + Otherwise, the function just sets the passed options and the caller + shouldn't be expecting a return value anyway.""" + options = _format_optdict(options) + res = tk.call(*(args + options)) + + if len(options) % 2: # option specified without a value, return its value + return res + + return _dict_from_tcltuple(tk.splitlist(res)) + +def _convert_stringval(value): + """Converts a value to, hopefully, a more appropriate Python object.""" + value = unicode(value) + try: + value = int(value) + except (ValueError, TypeError): + pass + + return value + +def _to_number(x): + if isinstance(x, str): + if '.' in x: + x = float(x) + else: + x = int(x) + return x + +def tclobjs_to_py(adict): + """Returns adict with its values converted from Tcl objects to Python + objects.""" + for opt, val in adict.iteritems(): + if val and hasattr(val, '__len__') and not isinstance(val, basestring): + if getattr(val[0], 'typename', None) == 'StateSpec': + val = _list_from_statespec(val) + else: + val = map(_convert_stringval, val) + + elif hasattr(val, 'typename'): # some other (single) Tcl object + val = _convert_stringval(val) + + adict[opt] = val + + return adict + +def setup_master(master=None): + """If master is not None, itself is returned. If master is None, + the default master is returned if there is one, otherwise a new + master is created and returned. + + If it is not allowed to use the default root and master is None, + RuntimeError is raised.""" + if master is None: + if Tkinter._support_default_root: + master = Tkinter._default_root or Tkinter.Tk() + else: + raise RuntimeError( + "No master specified and Tkinter is " + "configured to not support default root") + return master + + +class Style(object): + """Manipulate style database.""" + + _name = "ttk::style" + + def __init__(self, master=None): + master = setup_master(master) + + if not getattr(master, '_tile_loaded', False): + # Load tile now, if needed + _load_tile(master) + + self.master = master + self.tk = self.master.tk + + + def configure(self, style, query_opt=None, **kw): + """Query or sets the default value of the specified option(s) in + style. + + Each key in kw is an option and each value is either a string or + a sequence identifying the value for that option.""" + if query_opt is not None: + kw[query_opt] = None + return _val_or_dict(self.tk, kw, self._name, "configure", style) + + + def map(self, style, query_opt=None, **kw): + """Query or sets dynamic values of the specified option(s) in + style. + + Each key in kw is an option and each value should be a list or a + tuple (usually) containing statespecs grouped in tuples, or list, + or something else of your preference. A statespec is compound of + one or more states and then a value.""" + if query_opt is not None: + return _list_from_statespec(self.tk.splitlist( + self.tk.call(self._name, "map", style, '-%s' % query_opt))) + + return _dict_from_tcltuple(self.tk.splitlist( + self.tk.call(self._name, "map", style, *(_format_mapdict(kw))))) + + + def lookup(self, style, option, state=None, default=None): + """Returns the value specified for option in style. + + If state is specified it is expected to be a sequence of one + or more states. If the default argument is set, it is used as + a fallback value in case no specification for option is found.""" + state = ' '.join(state) if state else '' + + return self.tk.call(self._name, "lookup", style, '-%s' % option, + state, default) + + + def layout(self, style, layoutspec=None): + """Define the widget layout for given style. If layoutspec is + omitted, return the layout specification for given style. + + layoutspec is expected to be a list or an object different than + None that evaluates to False if you want to "turn off" that style. + If it is a list (or tuple, or something else), each item should be + a tuple where the first item is the layout name and the second item + should have the format described below: + + LAYOUTS + + A layout can contain the value None, if takes no options, or + a dict of options specifying how to arrange the element. + The layout mechanism uses a simplified version of the pack + geometry manager: given an initial cavity, each element is + allocated a parcel. Valid options/values are: + + side: whichside + Specifies which side of the cavity to place the + element; one of top, right, bottom or left. If + omitted, the element occupies the entire cavity. + + sticky: nswe + Specifies where the element is placed inside its + allocated parcel. + + children: [sublayout... ] + Specifies a list of elements to place inside the + element. Each element is a tuple (or other sequence) + where the first item is the layout name, and the other + is a LAYOUT.""" + lspec = None + if layoutspec: + lspec = _format_layoutlist(layoutspec)[0] + elif layoutspec is not None: # will disable the layout ({}, '', etc) + lspec = "null" # could be any other word, but this may make sense + # when calling layout(style) later + + return _list_from_layouttuple(self.tk, + self.tk.call(self._name, "layout", style, lspec)) + + + def element_create(self, elementname, etype, *args, **kw): + """Create a new element in the current theme of given etype.""" + spec, opts = _format_elemcreate(etype, False, *args, **kw) + self.tk.call(self._name, "element", "create", elementname, etype, + spec, *opts) + + + def element_names(self): + """Returns the list of elements defined in the current theme.""" + return self.tk.splitlist(self.tk.call(self._name, "element", "names")) + + + def element_options(self, elementname): + """Return the list of elementname's options.""" + return self.tk.splitlist(self.tk.call(self._name, "element", "options", elementname)) + + + def theme_create(self, themename, parent=None, settings=None): + """Creates a new theme. + + It is an error if themename already exists. If parent is + specified, the new theme will inherit styles, elements and + layouts from the specified parent theme. If settings are present, + they are expected to have the same syntax used for theme_settings.""" + script = _script_from_settings(settings) if settings else '' + + if parent: + self.tk.call(self._name, "theme", "create", themename, + "-parent", parent, "-settings", script) + else: + self.tk.call(self._name, "theme", "create", themename, + "-settings", script) + + + def theme_settings(self, themename, settings): + """Temporarily sets the current theme to themename, apply specified + settings and then restore the previous theme. + + Each key in settings is a style and each value may contain the + keys 'configure', 'map', 'layout' and 'element create' and they + are expected to have the same format as specified by the methods + configure, map, layout and element_create respectively.""" + script = _script_from_settings(settings) + self.tk.call(self._name, "theme", "settings", themename, script) + + + def theme_names(self): + """Returns a list of all known themes.""" + return self.tk.splitlist(self.tk.call(self._name, "theme", "names")) + + + def theme_use(self, themename=None): + """If themename is None, returns the theme in use, otherwise, set + the current theme to themename, refreshes all widgets and emits + a <> event.""" + if themename is None: + # Starting on Tk 8.6, checking this global is no longer needed + # since it allows doing self.tk.call(self._name, "theme", "use") + return self.tk.eval("return $ttk::currentTheme") + + # using "ttk::setTheme" instead of "ttk::style theme use" causes + # the variable currentTheme to be updated, also, ttk::setTheme calls + # "ttk::style theme use" in order to change theme. + self.tk.call("ttk::setTheme", themename) + + +class Widget(Tkinter.Widget): + """Base class for Tk themed widgets.""" + + def __init__(self, master, widgetname, kw=None): + """Constructs a Ttk Widget with the parent master. + + STANDARD OPTIONS + + class, cursor, takefocus, style + + SCROLLABLE WIDGET OPTIONS + + xscrollcommand, yscrollcommand + + LABEL WIDGET OPTIONS + + text, textvariable, underline, image, compound, width + + WIDGET STATES + + active, disabled, focus, pressed, selected, background, + readonly, alternate, invalid + """ + master = setup_master(master) + if not getattr(master, '_tile_loaded', False): + # Load tile now, if needed + _load_tile(master) + Tkinter.Widget.__init__(self, master, widgetname, kw=kw) + + + def identify(self, x, y): + """Returns the name of the element at position x, y, or the empty + string if the point does not lie within any element. + + x and y are pixel coordinates relative to the widget.""" + return self.tk.call(self._w, "identify", x, y) + + + def instate(self, statespec, callback=None, *args, **kw): + """Test the widget's state. + + If callback is not specified, returns True if the widget state + matches statespec and False otherwise. If callback is specified, + then it will be invoked with *args, **kw if the widget state + matches statespec. statespec is expected to be a sequence.""" + ret = self.tk.getboolean( + self.tk.call(self._w, "instate", ' '.join(statespec))) + if ret and callback: + return callback(*args, **kw) + + return bool(ret) + + + def state(self, statespec=None): + """Modify or inquire widget state. + + Widget state is returned if statespec is None, otherwise it is + set according to the statespec flags and then a new state spec + is returned indicating which flags were changed. statespec is + expected to be a sequence.""" + if statespec is not None: + statespec = ' '.join(statespec) + + return self.tk.splitlist(str(self.tk.call(self._w, "state", statespec))) + + +class Button(Widget): + """Ttk Button widget, displays a textual label and/or image, and + evaluates a command when pressed.""" + + def __init__(self, master=None, **kw): + """Construct a Ttk Button widget with the parent master. + + STANDARD OPTIONS + + class, compound, cursor, image, state, style, takefocus, + text, textvariable, underline, width + + WIDGET-SPECIFIC OPTIONS + + command, default, width + """ + Widget.__init__(self, master, "ttk::button", kw) + + + def invoke(self): + """Invokes the command associated with the button.""" + return self.tk.call(self._w, "invoke") + + +class Checkbutton(Widget): + """Ttk Checkbutton widget which is either in on- or off-state.""" + + def __init__(self, master=None, **kw): + """Construct a Ttk Checkbutton widget with the parent master. + + STANDARD OPTIONS + + class, compound, cursor, image, state, style, takefocus, + text, textvariable, underline, width + + WIDGET-SPECIFIC OPTIONS + + command, offvalue, onvalue, variable + """ + Widget.__init__(self, master, "ttk::checkbutton", kw) + + + def invoke(self): + """Toggles between the selected and deselected states and + invokes the associated command. If the widget is currently + selected, sets the option variable to the offvalue option + and deselects the widget; otherwise, sets the option variable + to the option onvalue. + + Returns the result of the associated command.""" + return self.tk.call(self._w, "invoke") + + +class Entry(Widget, Tkinter.Entry): + """Ttk Entry widget displays a one-line text string and allows that + string to be edited by the user.""" + + def __init__(self, master=None, widget=None, **kw): + """Constructs a Ttk Entry widget with the parent master. + + STANDARD OPTIONS + + class, cursor, style, takefocus, xscrollcommand + + WIDGET-SPECIFIC OPTIONS + + exportselection, invalidcommand, justify, show, state, + textvariable, validate, validatecommand, width + + VALIDATION MODES + + none, key, focus, focusin, focusout, all + """ + Widget.__init__(self, master, widget or "ttk::entry", kw) + + + def bbox(self, index): + """Return a tuple of (x, y, width, height) which describes the + bounding box of the character given by index.""" + return self._getints(self.tk.call(self._w, "bbox", index)) + + + def identify(self, x, y): + """Returns the name of the element at position x, y, or the + empty string if the coordinates are outside the window.""" + return self.tk.call(self._w, "identify", x, y) + + + def validate(self): + """Force revalidation, independent of the conditions specified + by the validate option. Returns False if validation fails, True + if it succeeds. Sets or clears the invalid state accordingly.""" + return bool(self.tk.getboolean(self.tk.call(self._w, "validate"))) + + +class Combobox(Entry): + """Ttk Combobox widget combines a text field with a pop-down list of + values.""" + + def __init__(self, master=None, **kw): + """Construct a Ttk Combobox widget with the parent master. + + STANDARD OPTIONS + + class, cursor, style, takefocus + + WIDGET-SPECIFIC OPTIONS + + exportselection, justify, height, postcommand, state, + textvariable, values, width + """ + Entry.__init__(self, master, "ttk::combobox", **kw) + + + def current(self, newindex=None): + """If newindex is supplied, sets the combobox value to the + element at position newindex in the list of values. Otherwise, + returns the index of the current value in the list of values + or -1 if the current value does not appear in the list.""" + if newindex is None: + return self.tk.getint(self.tk.call(self._w, "current")) + return self.tk.call(self._w, "current", newindex) + + + def set(self, value): + """Sets the value of the combobox to value.""" + self.tk.call(self._w, "set", value) + + +class Frame(Widget): + """Ttk Frame widget is a container, used to group other widgets + together.""" + + def __init__(self, master=None, **kw): + """Construct a Ttk Frame with parent master. + + STANDARD OPTIONS + + class, cursor, style, takefocus + + WIDGET-SPECIFIC OPTIONS + + borderwidth, relief, padding, width, height + """ + Widget.__init__(self, master, "ttk::frame", kw) + + +class Label(Widget): + """Ttk Label widget displays a textual label and/or image.""" + + def __init__(self, master=None, **kw): + """Construct a Ttk Label with parent master. + + STANDARD OPTIONS + + class, compound, cursor, image, style, takefocus, text, + textvariable, underline, width + + WIDGET-SPECIFIC OPTIONS + + anchor, background, font, foreground, justify, padding, + relief, text, wraplength + """ + Widget.__init__(self, master, "ttk::label", kw) + + +class Labelframe(Widget): + """Ttk Labelframe widget is a container used to group other widgets + together. It has an optional label, which may be a plain text string + or another widget.""" + + def __init__(self, master=None, **kw): + """Construct a Ttk Labelframe with parent master. + + STANDARD OPTIONS + + class, cursor, style, takefocus + + WIDGET-SPECIFIC OPTIONS + labelanchor, text, underline, padding, labelwidget, width, + height + """ + Widget.__init__(self, master, "ttk::labelframe", kw) + +LabelFrame = Labelframe # Tkinter name compatibility + + +class Menubutton(Widget): + """Ttk Menubutton widget displays a textual label and/or image, and + displays a menu when pressed.""" + + def __init__(self, master=None, **kw): + """Construct a Ttk Menubutton with parent master. + + STANDARD OPTIONS + + class, compound, cursor, image, state, style, takefocus, + text, textvariable, underline, width + + WIDGET-SPECIFIC OPTIONS + + direction, menu + """ + Widget.__init__(self, master, "ttk::menubutton", kw) + + +class Notebook(Widget): + """Ttk Notebook widget manages a collection of windows and displays + a single one at a time. Each child window is associated with a tab, + which the user may select to change the currently-displayed window.""" + + def __init__(self, master=None, **kw): + """Construct a Ttk Notebook with parent master. + + STANDARD OPTIONS + + class, cursor, style, takefocus + + WIDGET-SPECIFIC OPTIONS + + height, padding, width + + TAB OPTIONS + + state, sticky, padding, text, image, compound, underline + + TAB IDENTIFIERS (tab_id) + + The tab_id argument found in several methods may take any of + the following forms: + + * An integer between zero and the number of tabs + * The name of a child window + * A positional specification of the form "@x,y", which + defines the tab + * The string "current", which identifies the + currently-selected tab + * The string "end", which returns the number of tabs (only + valid for method index) + """ + Widget.__init__(self, master, "ttk::notebook", kw) + + + def add(self, child, **kw): + """Adds a new tab to the notebook. + + If window is currently managed by the notebook but hidden, it is + restored to its previous position.""" + self.tk.call(self._w, "add", child, *(_format_optdict(kw))) + + + def forget(self, tab_id): + """Removes the tab specified by tab_id, unmaps and unmanages the + associated window.""" + self.tk.call(self._w, "forget", tab_id) + + + def hide(self, tab_id): + """Hides the tab specified by tab_id. + + The tab will not be displayed, but the associated window remains + managed by the notebook and its configuration remembered. Hidden + tabs may be restored with the add command.""" + self.tk.call(self._w, "hide", tab_id) + + + def identify(self, x, y): + """Returns the name of the tab element at position x, y, or the + empty string if none.""" + return self.tk.call(self._w, "identify", x, y) + + + def index(self, tab_id): + """Returns the numeric index of the tab specified by tab_id, or + the total number of tabs if tab_id is the string "end".""" + return self.tk.getint(self.tk.call(self._w, "index", tab_id)) + + + def insert(self, pos, child, **kw): + """Inserts a pane at the specified position. + + pos is either the string end, an integer index, or the name of + a managed child. If child is already managed by the notebook, + moves it to the specified position.""" + self.tk.call(self._w, "insert", pos, child, *(_format_optdict(kw))) + + + def select(self, tab_id=None): + """Selects the specified tab. + + The associated child window will be displayed, and the + previously-selected window (if different) is unmapped. If tab_id + is omitted, returns the widget name of the currently selected + pane.""" + return self.tk.call(self._w, "select", tab_id) + + + def tab(self, tab_id, option=None, **kw): + """Query or modify the options of the specific tab_id. + + If kw is not given, returns a dict of the tab option values. If option + is specified, returns the value of that option. Otherwise, sets the + options to the corresponding values.""" + if option is not None: + kw[option] = None + return _val_or_dict(self.tk, kw, self._w, "tab", tab_id) + + + def tabs(self): + """Returns a list of windows managed by the notebook.""" + return self.tk.splitlist(self.tk.call(self._w, "tabs") or ()) + + + def enable_traversal(self): + """Enable keyboard traversal for a toplevel window containing + this notebook. + + This will extend the bindings for the toplevel window containing + this notebook as follows: + + Control-Tab: selects the tab following the currently selected + one + + Shift-Control-Tab: selects the tab preceding the currently + selected one + + Alt-K: where K is the mnemonic (underlined) character of any + tab, will select that tab. + + Multiple notebooks in a single toplevel may be enabled for + traversal, including nested notebooks. However, notebook traversal + only works properly if all panes are direct children of the + notebook.""" + # The only, and good, difference I see is about mnemonics, which works + # after calling this method. Control-Tab and Shift-Control-Tab always + # works (here at least). + self.tk.call("ttk::notebook::enableTraversal", self._w) + + +class Panedwindow(Widget, Tkinter.PanedWindow): + """Ttk Panedwindow widget displays a number of subwindows, stacked + either vertically or horizontally.""" + + def __init__(self, master=None, **kw): + """Construct a Ttk Panedwindow with parent master. + + STANDARD OPTIONS + + class, cursor, style, takefocus + + WIDGET-SPECIFIC OPTIONS + + orient, width, height + + PANE OPTIONS + + weight + """ + Widget.__init__(self, master, "ttk::panedwindow", kw) + + + forget = Tkinter.PanedWindow.forget # overrides Pack.forget + + + def insert(self, pos, child, **kw): + """Inserts a pane at the specified positions. + + pos is either the string end, and integer index, or the name + of a child. If child is already managed by the paned window, + moves it to the specified position.""" + self.tk.call(self._w, "insert", pos, child, *(_format_optdict(kw))) + + + def pane(self, pane, option=None, **kw): + """Query or modify the options of the specified pane. + + pane is either an integer index or the name of a managed subwindow. + If kw is not given, returns a dict of the pane option values. If + option is specified then the value for that option is returned. + Otherwise, sets the options to the corresponding values.""" + if option is not None: + kw[option] = None + return _val_or_dict(self.tk, kw, self._w, "pane", pane) + + + def sashpos(self, index, newpos=None): + """If newpos is specified, sets the position of sash number index. + + May adjust the positions of adjacent sashes to ensure that + positions are monotonically increasing. Sash positions are further + constrained to be between 0 and the total size of the widget. + + Returns the new position of sash number index.""" + return self.tk.getint(self.tk.call(self._w, "sashpos", index, newpos)) + +PanedWindow = Panedwindow # Tkinter name compatibility + + +class Progressbar(Widget): + """Ttk Progressbar widget shows the status of a long-running + operation. They can operate in two modes: determinate mode shows the + amount completed relative to the total amount of work to be done, and + indeterminate mode provides an animated display to let the user know + that something is happening.""" + + def __init__(self, master=None, **kw): + """Construct a Ttk Progressbar with parent master. + + STANDARD OPTIONS + + class, cursor, style, takefocus + + WIDGET-SPECIFIC OPTIONS + + orient, length, mode, maximum, value, variable, phase + """ + Widget.__init__(self, master, "ttk::progressbar", kw) + + + def start(self, interval=None): + """Begin autoincrement mode: schedules a recurring timer event + that calls method step every interval milliseconds. + + interval defaults to 50 milliseconds (20 steps/second) if ommited.""" + self.tk.call(self._w, "start", interval) + + + def step(self, amount=None): + """Increments the value option by amount. + + amount defaults to 1.0 if omitted.""" + self.tk.call(self._w, "step", amount) + + + def stop(self): + """Stop autoincrement mode: cancels any recurring timer event + initiated by start.""" + self.tk.call(self._w, "stop") + + +class Radiobutton(Widget): + """Ttk Radiobutton widgets are used in groups to show or change a + set of mutually-exclusive options.""" + + def __init__(self, master=None, **kw): + """Construct a Ttk Radiobutton with parent master. + + STANDARD OPTIONS + + class, compound, cursor, image, state, style, takefocus, + text, textvariable, underline, width + + WIDGET-SPECIFIC OPTIONS + + command, value, variable + """ + Widget.__init__(self, master, "ttk::radiobutton", kw) + + + def invoke(self): + """Sets the option variable to the option value, selects the + widget, and invokes the associated command. + + Returns the result of the command, or an empty string if + no command is specified.""" + return self.tk.call(self._w, "invoke") + + +class Scale(Widget, Tkinter.Scale): + """Ttk Scale widget is typically used to control the numeric value of + a linked variable that varies uniformly over some range.""" + + def __init__(self, master=None, **kw): + """Construct a Ttk Scale with parent master. + + STANDARD OPTIONS + + class, cursor, style, takefocus + + WIDGET-SPECIFIC OPTIONS + + command, from, length, orient, to, value, variable + """ + Widget.__init__(self, master, "ttk::scale", kw) + + + def configure(self, cnf=None, **kw): + """Modify or query scale options. + + Setting a value for any of the "from", "from_" or "to" options + generates a <> event.""" + if cnf: + kw.update(cnf) + Widget.configure(self, **kw) + if any(['from' in kw, 'from_' in kw, 'to' in kw]): + self.event_generate('<>') + + + def get(self, x=None, y=None): + """Get the current value of the value option, or the value + corresponding to the coordinates x, y if they are specified. + + x and y are pixel coordinates relative to the scale widget + origin.""" + return self.tk.call(self._w, 'get', x, y) + + +class Scrollbar(Widget, Tkinter.Scrollbar): + """Ttk Scrollbar controls the viewport of a scrollable widget.""" + + def __init__(self, master=None, **kw): + """Construct a Ttk Scrollbar with parent master. + + STANDARD OPTIONS + + class, cursor, style, takefocus + + WIDGET-SPECIFIC OPTIONS + + command, orient + """ + Widget.__init__(self, master, "ttk::scrollbar", kw) + + +class Separator(Widget): + """Ttk Separator widget displays a horizontal or vertical separator + bar.""" + + def __init__(self, master=None, **kw): + """Construct a Ttk Separator with parent master. + + STANDARD OPTIONS + + class, cursor, style, takefocus + + WIDGET-SPECIFIC OPTIONS + + orient + """ + Widget.__init__(self, master, "ttk::separator", kw) + + +class Sizegrip(Widget): + """Ttk Sizegrip allows the user to resize the containing toplevel + window by pressing and dragging the grip.""" + + def __init__(self, master=None, **kw): + """Construct a Ttk Sizegrip with parent master. + + STANDARD OPTIONS + + class, cursor, state, style, takefocus + """ + Widget.__init__(self, master, "ttk::sizegrip", kw) + + +class Treeview(Widget, Tkinter.XView, Tkinter.YView): + """Ttk Treeview widget displays a hierarchical collection of items. + + Each item has a textual label, an optional image, and an optional list + of data values. The data values are displayed in successive columns + after the tree label.""" + + def __init__(self, master=None, **kw): + """Construct a Ttk Treeview with parent master. + + STANDARD OPTIONS + + class, cursor, style, takefocus, xscrollcommand, + yscrollcommand + + WIDGET-SPECIFIC OPTIONS + + columns, displaycolumns, height, padding, selectmode, show + + ITEM OPTIONS + + text, image, values, open, tags + + TAG OPTIONS + + foreground, background, font, image + """ + Widget.__init__(self, master, "ttk::treeview", kw) + + + def bbox(self, item, column=None): + """Returns the bounding box (relative to the treeview widget's + window) of the specified item in the form x y width height. + + If column is specified, returns the bounding box of that cell. + If the item is not visible (i.e., if it is a descendant of a + closed item or is scrolled offscreen), returns an empty string.""" + return self._getints(self.tk.call(self._w, "bbox", item, column)) or '' + + + def get_children(self, item=None): + """Returns a tuple of children belonging to item. + + If item is not specified, returns root children.""" + return self.tk.splitlist( + self.tk.call(self._w, "children", item or '') or ()) + + + def set_children(self, item, *newchildren): + """Replaces item's child with newchildren. + + Children present in item that are not present in newchildren + are detached from tree. No items in newchildren may be an + ancestor of item.""" + self.tk.call(self._w, "children", item, newchildren) + + + def column(self, column, option=None, **kw): + """Query or modify the options for the specified column. + + If kw is not given, returns a dict of the column option values. If + option is specified then the value for that option is returned. + Otherwise, sets the options to the corresponding values.""" + if option is not None: + kw[option] = None + return _val_or_dict(self.tk, kw, self._w, "column", column) + + + def delete(self, *items): + """Delete all specified items and all their descendants. The root + item may not be deleted.""" + self.tk.call(self._w, "delete", items) + + + def detach(self, *items): + """Unlinks all of the specified items from the tree. + + The items and all of their descendants are still present, and may + be reinserted at another point in the tree, but will not be + displayed. The root item may not be detached.""" + self.tk.call(self._w, "detach", items) + + + def exists(self, item): + """Returns True if the specified item is present in the tree, + False otherwise.""" + return bool(self.tk.getboolean(self.tk.call(self._w, "exists", item))) + + + def focus(self, item=None): + """If item is specified, sets the focus item to item. Otherwise, + returns the current focus item, or '' if there is none.""" + return self.tk.call(self._w, "focus", item) + + + def heading(self, column, option=None, **kw): + """Query or modify the heading options for the specified column. + + If kw is not given, returns a dict of the heading option values. If + option is specified then the value for that option is returned. + Otherwise, sets the options to the corresponding values. + + Valid options/values are: + text: text + The text to display in the column heading + image: image_name + Specifies an image to display to the right of the column + heading + anchor: anchor + Specifies how the heading text should be aligned. One of + the standard Tk anchor values + command: callback + A callback to be invoked when the heading label is + pressed. + + To configure the tree column heading, call this with column = "#0" """ + cmd = kw.get('command') + if cmd and not isinstance(cmd, basestring): + # callback not registered yet, do it now + kw['command'] = self.master.register(cmd, self._substitute) + + if option is not None: + kw[option] = None + + return _val_or_dict(self.tk, kw, self._w, 'heading', column) + + + def identify(self, component, x, y): + """Returns a description of the specified component under the + point given by x and y, or the empty string if no such component + is present at that position.""" + return self.tk.call(self._w, "identify", component, x, y) + + + def identify_row(self, y): + """Returns the item ID of the item at position y.""" + return self.identify("row", 0, y) + + + def identify_column(self, x): + """Returns the data column identifier of the cell at position x. + + The tree column has ID #0.""" + return self.identify("column", x, 0) + + + def identify_region(self, x, y): + """Returns one of: + + heading: Tree heading area. + separator: Space between two columns headings; + tree: The tree area. + cell: A data cell. + + * Availability: Tk 8.6""" + return self.identify("region", x, y) + + + def identify_element(self, x, y): + """Returns the element at position x, y. + + * Availability: Tk 8.6""" + return self.identify("element", x, y) + + + def index(self, item): + """Returns the integer index of item within its parent's list + of children.""" + return self.tk.getint(self.tk.call(self._w, "index", item)) + + + def insert(self, parent, index, iid=None, **kw): + """Creates a new item and return the item identifier of the newly + created item. + + parent is the item ID of the parent item, or the empty string + to create a new top-level item. index is an integer, or the value + end, specifying where in the list of parent's children to insert + the new item. If index is less than or equal to zero, the new node + is inserted at the beginning, if index is greater than or equal to + the current number of children, it is inserted at the end. If iid + is specified, it is used as the item identifier, iid must not + already exist in the tree. Otherwise, a new unique identifier + is generated.""" + opts = _format_optdict(kw) + if iid: + res = self.tk.call(self._w, "insert", parent, index, + "-id", iid, *opts) + else: + res = self.tk.call(self._w, "insert", parent, index, *opts) + + return res + + + def item(self, item, option=None, **kw): + """Query or modify the options for the specified item. + + If no options are given, a dict with options/values for the item + is returned. If option is specified then the value for that option + is returned. Otherwise, sets the options to the corresponding + values as given by kw.""" + if option is not None: + kw[option] = None + return _val_or_dict(self.tk, kw, self._w, "item", item) + + + def move(self, item, parent, index): + """Moves item to position index in parent's list of children. + + It is illegal to move an item under one of its descendants. If + index is less than or equal to zero, item is moved to the + beginning, if greater than or equal to the number of children, + it is moved to the end. If item was detached it is reattached.""" + self.tk.call(self._w, "move", item, parent, index) + + reattach = move # A sensible method name for reattaching detached items + + + def next(self, item): + """Returns the identifier of item's next sibling, or '' if item + is the last child of its parent.""" + return self.tk.call(self._w, "next", item) + + + def parent(self, item): + """Returns the ID of the parent of item, or '' if item is at the + top level of the hierarchy.""" + return self.tk.call(self._w, "parent", item) + + + def prev(self, item): + """Returns the identifier of item's previous sibling, or '' if + item is the first child of its parent.""" + return self.tk.call(self._w, "prev", item) + + + def see(self, item): + """Ensure that item is visible. + + Sets all of item's ancestors open option to True, and scrolls + the widget if necessary so that item is within the visible + portion of the tree.""" + self.tk.call(self._w, "see", item) + + + def selection(self, selop=None, items=None): + """If selop is not specified, returns selected items.""" + return self.tk.call(self._w, "selection", selop, items) + + + def selection_set(self, items): + """items becomes the new selection.""" + self.selection("set", items) + + + def selection_add(self, items): + """Add items to the selection.""" + self.selection("add", items) + + + def selection_remove(self, items): + """Remove items from the selection.""" + self.selection("remove", items) + + + def selection_toggle(self, items): + """Toggle the selection state of each item in items.""" + self.selection("toggle", items) + + + def set(self, item, column=None, value=None): + """With one argument, returns a dictionary of column/value pairs + for the specified item. With two arguments, returns the current + value of the specified column. With three arguments, sets the + value of given column in given item to the specified value.""" + res = self.tk.call(self._w, "set", item, column, value) + if column is None and value is None: + return _dict_from_tcltuple(self.tk.splitlist(res), False) + else: + return res + + + def tag_bind(self, tagname, sequence=None, callback=None): + """Bind a callback for the given event sequence to the tag tagname. + When an event is delivered to an item, the callbacks for each + of the item's tags option are called.""" + self._bind((self._w, "tag", "bind", tagname), sequence, callback, add=0) + + + def tag_configure(self, tagname, option=None, **kw): + """Query or modify the options for the specified tagname. + + If kw is not given, returns a dict of the option settings for tagname. + If option is specified, returns the value for that option for the + specified tagname. Otherwise, sets the options to the corresponding + values for the given tagname.""" + if option is not None: + kw[option] = None + return _val_or_dict(self.tk, kw, self._w, "tag", "configure", + tagname) + + + def tag_has(self, tagname, item=None): + """If item is specified, returns 1 or 0 depending on whether the + specified item has the given tagname. Otherwise, returns a list of + all items which have the specified tag. + + * Availability: Tk 8.6""" + return self.tk.getboolean( + self.tk.call(self._w, "tag", "has", tagname, item)) + + +# Extensions + +class LabeledScale(Frame, object): + """A Ttk Scale widget with a Ttk Label widget indicating its + current value. + + The Ttk Scale can be accessed through instance.scale, and Ttk Label + can be accessed through instance.label""" + + def __init__(self, master=None, variable=None, from_=0, to=10, **kw): + """Construct an horizontal LabeledScale with parent master, a + variable to be associated with the Ttk Scale widget and its range. + If variable is not specified, a Tkinter.IntVar is created. + + WIDGET-SPECIFIC OPTIONS + + compound: 'top' or 'bottom' + Specifies how to display the label relative to the scale. + Defaults to 'top'. + """ + self._label_top = kw.pop('compound', 'top') == 'top' + + Frame.__init__(self, master, **kw) + self._variable = variable or Tkinter.IntVar(master) + self._variable.set(from_) + self._last_valid = from_ + + self.label = Label(self) + self.scale = Scale(self, variable=self._variable, from_=from_, to=to) + self.scale.bind('<>', self._adjust) + + # position scale and label according to the compound option + scale_side = 'bottom' if self._label_top else 'top' + label_side = 'top' if scale_side == 'bottom' else 'bottom' + self.scale.pack(side=scale_side, fill='x') + tmp = Label(self).pack(side=label_side) # place holder + self.label.place(anchor='n' if label_side == 'top' else 's') + + # update the label as scale or variable changes + self.__tracecb = self._variable.trace_variable('w', self._adjust) + self.bind('', self._adjust) + self.bind('', self._adjust) + + + def destroy(self): + """Destroy this widget and possibly its associated variable.""" + try: + self._variable.trace_vdelete('w', self.__tracecb) + except AttributeError: + # widget has been destroyed already + pass + else: + del self._variable + Frame.destroy(self) + + + def _adjust(self, *args): + """Adjust the label position according to the scale.""" + def adjust_label(): + self.update_idletasks() # "force" scale redraw + + x, y = self.scale.coords() + if self._label_top: + y = self.scale.winfo_y() - self.label.winfo_reqheight() + else: + y = self.scale.winfo_reqheight() + self.label.winfo_reqheight() + + self.label.place_configure(x=x, y=y) + + from_ = _to_number(self.scale['from']) + to = _to_number(self.scale['to']) + if to < from_: + from_, to = to, from_ + newval = self._variable.get() + if not from_ <= newval <= to: + # value outside range, set value back to the last valid one + self.value = self._last_valid + return + + self._last_valid = newval + self.label['text'] = newval + self.after_idle(adjust_label) + + + def _get_value(self): + """Return current scale value.""" + return self._variable.get() + + + def _set_value(self, val): + """Set new scale value.""" + self._variable.set(val) + + + value = property(_get_value, _set_value) + + +class OptionMenu(Menubutton): + """Themed OptionMenu, based after Tkinter's OptionMenu, which allows + the user to select a value from a menu.""" + + def __init__(self, master, variable, default=None, *values, **kwargs): + """Construct a themed OptionMenu widget with master as the parent, + the resource textvariable set to variable, the initially selected + value specified by the default parameter, the menu values given by + *values and additional keywords. + + WIDGET-SPECIFIC OPTIONS + + style: stylename + Menubutton style. + direction: 'above', 'below', 'left', 'right', or 'flush' + Menubutton direction. + command: callback + A callback that will be invoked after selecting an item. + """ + kw = {'textvariable': variable, 'style': kwargs.pop('style', None), + 'direction': kwargs.pop('direction', None)} + Menubutton.__init__(self, master, **kw) + self['menu'] = Tkinter.Menu(self, tearoff=False) + + self._variable = variable + self._callback = kwargs.pop('command', None) + if kwargs: + raise Tkinter.TclError('unknown option -%s' % ( + kwargs.iterkeys().next())) + + self.set_menu(default, *values) + + + def __getitem__(self, item): + if item == 'menu': + return self.nametowidget(Menubutton.__getitem__(self, item)) + + return Menubutton.__getitem__(self, item) + + + def set_menu(self, default=None, *values): + """Build a new menu of radiobuttons with *values and optionally + a default value.""" + menu = self['menu'] + menu.delete(0, 'end') + for val in values: + menu.add_radiobutton(label=val, + command=Tkinter._setit(self._variable, val, self._callback)) + + if default: + self._variable.set(default) + + + def destroy(self): + """Destroy this widget and its associated variable.""" + del self._variable + Menubutton.destroy(self) diff --git a/PythonHome/Lib/lib-tk/ttk.pyc b/PythonHome/Lib/lib-tk/ttk.pyc deleted file mode 100644 index 505fd54ceb6010932a9db5708c1f2fbbb7f35f8e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 60597 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"EGg{vwB} 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', self.onResize) + + def reset(self, canvwidth=None, canvheight=None, bg = None): + """Adjust canvas and scrollbars according to given canvas size.""" + if canvwidth: + self.canvwidth = canvwidth + if canvheight: + self.canvheight = canvheight + if bg: + self.bg = bg + self._canvas.config(bg=bg, + scrollregion=(-self.canvwidth//2, -self.canvheight//2, + self.canvwidth//2, self.canvheight//2)) + self._canvas.xview_moveto(0.5*(self.canvwidth - self.width + 30) / + self.canvwidth) + self._canvas.yview_moveto(0.5*(self.canvheight- self.height + 30) / + self.canvheight) + self.adjustScrolls() + + + def adjustScrolls(self): + """ Adjust scrollbars according to window- and canvas-size. + """ + cwidth = self._canvas.winfo_width() + cheight = self._canvas.winfo_height() + self._canvas.xview_moveto(0.5*(self.canvwidth-cwidth)/self.canvwidth) + self._canvas.yview_moveto(0.5*(self.canvheight-cheight)/self.canvheight) + if cwidth < self.canvwidth or cheight < self.canvheight: + self.hscroll.grid(padx=1, in_ = self, pady=1, row=1, + column=0, rowspan=1, columnspan=1, sticky='news') + self.vscroll.grid(padx=1, in_ = self, pady=1, row=0, + column=1, rowspan=1, columnspan=1, sticky='news') + else: + self.hscroll.grid_forget() + self.vscroll.grid_forget() + + def onResize(self, event): + """self-explanatory""" + self.adjustScrolls() + + def bbox(self, *args): + """ 'forward' method, which canvas itself has inherited... + """ + return self._canvas.bbox(*args) + + def cget(self, *args, **kwargs): + """ 'forward' method, which canvas itself has inherited... + """ + return self._canvas.cget(*args, **kwargs) + + def config(self, *args, **kwargs): + """ 'forward' method, which canvas itself has inherited... + """ + self._canvas.config(*args, **kwargs) + + def bind(self, *args, **kwargs): + """ 'forward' method, which canvas itself has inherited... + """ + self._canvas.bind(*args, **kwargs) + + def unbind(self, *args, **kwargs): + """ 'forward' method, which canvas itself has inherited... + """ + self._canvas.unbind(*args, **kwargs) + + def focus_force(self): + """ 'forward' method, which canvas itself has inherited... + """ + self._canvas.focus_force() + +__forwardmethods(ScrolledCanvas, TK.Canvas, '_canvas') + + +class _Root(TK.Tk): + """Root class for Screen based on Tkinter.""" + def __init__(self): + TK.Tk.__init__(self) + + def setupcanvas(self, width, height, cwidth, cheight): + self._canvas = ScrolledCanvas(self, width, height, cwidth, cheight) + self._canvas.pack(expand=1, fill="both") + + def _getcanvas(self): + return self._canvas + + def set_geometry(self, width, height, startx, starty): + self.geometry("%dx%d%+d%+d"%(width, height, startx, starty)) + + def ondestroy(self, destroy): + self.wm_protocol("WM_DELETE_WINDOW", destroy) + + def win_width(self): + return self.winfo_screenwidth() + + def win_height(self): + return self.winfo_screenheight() + +Canvas = TK.Canvas + + +class TurtleScreenBase(object): + """Provide the basic graphics functionality. + Interface between Tkinter and turtle.py. + + To port turtle.py to some different graphics toolkit + a corresponding TurtleScreenBase class has to be implemented. + """ + + @staticmethod + def _blankimage(): + """return a blank image object + """ + img = TK.PhotoImage(width=1, height=1) + img.blank() + return img + + @staticmethod + def _image(filename): + """return an image object containing the + imagedata from a gif-file named filename. + """ + return TK.PhotoImage(file=filename) + + def __init__(self, cv): + self.cv = cv + if isinstance(cv, ScrolledCanvas): + w = self.cv.canvwidth + h = self.cv.canvheight + else: # expected: ordinary TK.Canvas + w = int(self.cv.cget("width")) + h = int(self.cv.cget("height")) + self.cv.config(scrollregion = (-w//2, -h//2, w//2, h//2 )) + self.canvwidth = w + self.canvheight = h + self.xscale = self.yscale = 1.0 + + def _createpoly(self): + """Create an invisible polygon item on canvas self.cv) + """ + return self.cv.create_polygon((0, 0, 0, 0, 0, 0), fill="", outline="") + + def _drawpoly(self, polyitem, coordlist, fill=None, + outline=None, width=None, top=False): + """Configure polygonitem polyitem according to provided + arguments: + coordlist is sequence of coordinates + fill is filling color + outline is outline color + top is a boolean value, which specifies if polyitem + will be put on top of the canvas' displaylist so it + will not be covered by other items. + """ + cl = [] + for x, y in coordlist: + cl.append(x * self.xscale) + cl.append(-y * self.yscale) + self.cv.coords(polyitem, *cl) + if fill is not None: + self.cv.itemconfigure(polyitem, fill=fill) + if outline is not None: + self.cv.itemconfigure(polyitem, outline=outline) + if width is not None: + self.cv.itemconfigure(polyitem, width=width) + if top: + self.cv.tag_raise(polyitem) + + def _createline(self): + """Create an invisible line item on canvas self.cv) + """ + return self.cv.create_line(0, 0, 0, 0, fill="", width=2, + capstyle = TK.ROUND) + + def _drawline(self, lineitem, coordlist=None, + fill=None, width=None, top=False): + """Configure lineitem according to provided arguments: + coordlist is sequence of coordinates + fill is drawing color + width is width of drawn line. + top is a boolean value, which specifies if polyitem + will be put on top of the canvas' displaylist so it + will not be covered by other items. + """ + if coordlist is not None: + cl = [] + for x, y in coordlist: + cl.append(x * self.xscale) + cl.append(-y * self.yscale) + self.cv.coords(lineitem, *cl) + if fill is not None: + self.cv.itemconfigure(lineitem, fill=fill) + if width is not None: + self.cv.itemconfigure(lineitem, width=width) + if top: + self.cv.tag_raise(lineitem) + + def _delete(self, item): + """Delete graphics item from canvas. + If item is"all" delete all graphics items. + """ + self.cv.delete(item) + + def _update(self): + """Redraw graphics items on canvas + """ + self.cv.update() + + def _delay(self, delay): + """Delay subsequent canvas actions for delay ms.""" + self.cv.after(delay) + + def _iscolorstring(self, color): + """Check if the string color is a legal Tkinter color string. + """ + try: + rgb = self.cv.winfo_rgb(color) + ok = True + except TK.TclError: + ok = False + return ok + + def _bgcolor(self, color=None): + """Set canvas' backgroundcolor if color is not None, + else return backgroundcolor.""" + if color is not None: + self.cv.config(bg = color) + self._update() + else: + return self.cv.cget("bg") + + def _write(self, pos, txt, align, font, pencolor): + """Write txt at pos in canvas with specified font + and color. + Return text item and x-coord of right bottom corner + of text's bounding box.""" + x, y = pos + x = x * self.xscale + y = y * self.yscale + anchor = {"left":"sw", "center":"s", "right":"se" } + item = self.cv.create_text(x-1, -y, text = txt, anchor = anchor[align], + fill = pencolor, font = font) + x0, y0, x1, y1 = self.cv.bbox(item) + self.cv.update() + return item, x1-1 + +## def _dot(self, pos, size, color): +## """may be implemented for some other graphics toolkit""" + + def _onclick(self, item, fun, num=1, add=None): + """Bind fun to mouse-click event on turtle. + fun must be a function with two arguments, the coordinates + of the clicked point on the canvas. + num, the number of the mouse-button defaults to 1 + """ + if fun is None: + self.cv.tag_unbind(item, "" % num) + else: + def eventfun(event): + x, y = (self.cv.canvasx(event.x)/self.xscale, + -self.cv.canvasy(event.y)/self.yscale) + fun(x, y) + self.cv.tag_bind(item, "" % num, eventfun, add) + + def _onrelease(self, item, fun, num=1, add=None): + """Bind fun to mouse-button-release event on turtle. + fun must be a function with two arguments, the coordinates + of the point on the canvas where mouse button is released. + num, the number of the mouse-button defaults to 1 + + If a turtle is clicked, first _onclick-event will be performed, + then _onscreensclick-event. + """ + if fun is None: + self.cv.tag_unbind(item, "" % num) + else: + def eventfun(event): + x, y = (self.cv.canvasx(event.x)/self.xscale, + -self.cv.canvasy(event.y)/self.yscale) + fun(x, y) + self.cv.tag_bind(item, "" % num, + eventfun, add) + + def _ondrag(self, item, fun, num=1, add=None): + """Bind fun to mouse-move-event (with pressed mouse button) on turtle. + fun must be a function with two arguments, the coordinates of the + actual mouse position on the canvas. + num, the number of the mouse-button defaults to 1 + + Every sequence of mouse-move-events on a turtle is preceded by a + mouse-click event on that turtle. + """ + if fun is None: + self.cv.tag_unbind(item, "" % num) + else: + def eventfun(event): + try: + x, y = (self.cv.canvasx(event.x)/self.xscale, + -self.cv.canvasy(event.y)/self.yscale) + fun(x, y) + except: + pass + self.cv.tag_bind(item, "" % num, eventfun, add) + + def _onscreenclick(self, fun, num=1, add=None): + """Bind fun to mouse-click event on canvas. + fun must be a function with two arguments, the coordinates + of the clicked point on the canvas. + num, the number of the mouse-button defaults to 1 + + If a turtle is clicked, first _onclick-event will be performed, + then _onscreensclick-event. + """ + if fun is None: + self.cv.unbind("" % num) + else: + def eventfun(event): + x, y = (self.cv.canvasx(event.x)/self.xscale, + -self.cv.canvasy(event.y)/self.yscale) + fun(x, y) + self.cv.bind("" % num, eventfun, add) + + def _onkey(self, fun, key): + """Bind fun to key-release event of key. + Canvas must have focus. See method listen + """ + if fun is None: + self.cv.unbind("" % key, None) + else: + def eventfun(event): + fun() + self.cv.bind("" % key, eventfun) + + def _listen(self): + """Set focus on canvas (in order to collect key-events) + """ + self.cv.focus_force() + + def _ontimer(self, fun, t): + """Install a timer, which calls fun after t milliseconds. + """ + if t == 0: + self.cv.after_idle(fun) + else: + self.cv.after(t, fun) + + def _createimage(self, image): + """Create and return image item on canvas. + """ + return self.cv.create_image(0, 0, image=image) + + def _drawimage(self, item, (x, y), image): + """Configure image item as to draw image object + at position (x,y) on canvas) + """ + self.cv.coords(item, (x * self.xscale, -y * self.yscale)) + self.cv.itemconfig(item, image=image) + + def _setbgpic(self, item, image): + """Configure image item as to draw image object + at center of canvas. Set item to the first item + in the displaylist, so it will be drawn below + any other item .""" + self.cv.itemconfig(item, image=image) + self.cv.tag_lower(item) + + def _type(self, item): + """Return 'line' or 'polygon' or 'image' depending on + type of item. + """ + return self.cv.type(item) + + def _pointlist(self, item): + """returns list of coordinate-pairs of points of item + Example (for insiders): + >>> from turtle import * + >>> getscreen()._pointlist(getturtle().turtle._item) + [(0.0, 9.9999999999999982), (0.0, -9.9999999999999982), + (9.9999999999999982, 0.0)] + >>> """ + cl = self.cv.coords(item) + pl = [(cl[i], -cl[i+1]) for i in range(0, len(cl), 2)] + return pl + + def _setscrollregion(self, srx1, sry1, srx2, sry2): + self.cv.config(scrollregion=(srx1, sry1, srx2, sry2)) + + def _rescale(self, xscalefactor, yscalefactor): + items = self.cv.find_all() + for item in items: + coordinates = self.cv.coords(item) + newcoordlist = [] + while coordinates: + x, y = coordinates[:2] + newcoordlist.append(x * xscalefactor) + newcoordlist.append(y * yscalefactor) + coordinates = coordinates[2:] + self.cv.coords(item, *newcoordlist) + + def _resize(self, canvwidth=None, canvheight=None, bg=None): + """Resize the canvas the turtles are drawing on. Does + not alter the drawing window. + """ + # needs amendment + if not isinstance(self.cv, ScrolledCanvas): + return self.canvwidth, self.canvheight + if canvwidth is canvheight is bg is None: + return self.cv.canvwidth, self.cv.canvheight + if canvwidth is not None: + self.canvwidth = canvwidth + if canvheight is not None: + self.canvheight = canvheight + self.cv.reset(canvwidth, canvheight, bg) + + def _window_size(self): + """ Return the width and height of the turtle window. + """ + width = self.cv.winfo_width() + if width <= 1: # the window isn't managed by a geometry manager + width = self.cv['width'] + height = self.cv.winfo_height() + if height <= 1: # the window isn't managed by a geometry manager + height = self.cv['height'] + return width, height + + +############################################################################## +### End of Tkinter - interface ### +############################################################################## + + +class Terminator (Exception): + """Will be raised in TurtleScreen.update, if _RUNNING becomes False. + + This stops execution of a turtle graphics script. + Main purpose: use in the Demo-Viewer turtle.Demo.py. + """ + pass + + +class TurtleGraphicsError(Exception): + """Some TurtleGraphics Error + """ + + +class Shape(object): + """Data structure modeling shapes. + + attribute _type is one of "polygon", "image", "compound" + attribute _data is - depending on _type a poygon-tuple, + an image or a list constructed using the addcomponent method. + """ + def __init__(self, type_, data=None): + self._type = type_ + if type_ == "polygon": + if isinstance(data, list): + data = tuple(data) + elif type_ == "image": + if isinstance(data, basestring): + if data.lower().endswith(".gif") and isfile(data): + data = TurtleScreen._image(data) + # else data assumed to be Photoimage + elif type_ == "compound": + data = [] + else: + raise TurtleGraphicsError("There is no shape type %s" % type_) + self._data = data + + def addcomponent(self, poly, fill, outline=None): + """Add component to a shape of type compound. + + Arguments: poly is a polygon, i. e. a tuple of number pairs. + fill is the fillcolor of the component, + outline is the outline color of the component. + + call (for a Shapeobject namend s): + -- s.addcomponent(((0,0), (10,10), (-10,10)), "red", "blue") + + Example: + >>> poly = ((0,0),(10,-5),(0,10),(-10,-5)) + >>> s = Shape("compound") + >>> s.addcomponent(poly, "red", "blue") + >>> # .. add more components and then use register_shape() + """ + if self._type != "compound": + raise TurtleGraphicsError("Cannot add component to %s Shape" + % self._type) + if outline is None: + outline = fill + self._data.append([poly, fill, outline]) + + +class Tbuffer(object): + """Ring buffer used as undobuffer for RawTurtle objects.""" + def __init__(self, bufsize=10): + self.bufsize = bufsize + self.buffer = [[None]] * bufsize + self.ptr = -1 + self.cumulate = False + def reset(self, bufsize=None): + if bufsize is None: + for i in range(self.bufsize): + self.buffer[i] = [None] + else: + self.bufsize = bufsize + self.buffer = [[None]] * bufsize + self.ptr = -1 + def push(self, item): + if self.bufsize > 0: + if not self.cumulate: + self.ptr = (self.ptr + 1) % self.bufsize + self.buffer[self.ptr] = item + else: + self.buffer[self.ptr].append(item) + def pop(self): + if self.bufsize > 0: + item = self.buffer[self.ptr] + if item is None: + return None + else: + self.buffer[self.ptr] = [None] + self.ptr = (self.ptr - 1) % self.bufsize + return (item) + def nr_of_items(self): + return self.bufsize - self.buffer.count([None]) + def __repr__(self): + return str(self.buffer) + " " + str(self.ptr) + + + +class TurtleScreen(TurtleScreenBase): + """Provides screen oriented methods like setbg etc. + + Only relies upon the methods of TurtleScreenBase and NOT + upon components of the underlying graphics toolkit - + which is Tkinter in this case. + """ +# _STANDARD_DELAY = 5 + _RUNNING = True + + def __init__(self, cv, mode=_CFG["mode"], + colormode=_CFG["colormode"], delay=_CFG["delay"]): + self._shapes = { + "arrow" : Shape("polygon", ((-10,0), (10,0), (0,10))), + "turtle" : Shape("polygon", ((0,16), (-2,14), (-1,10), (-4,7), + (-7,9), (-9,8), (-6,5), (-7,1), (-5,-3), (-8,-6), + (-6,-8), (-4,-5), (0,-7), (4,-5), (6,-8), (8,-6), + (5,-3), (7,1), (6,5), (9,8), (7,9), (4,7), (1,10), + (2,14))), + "circle" : Shape("polygon", ((10,0), (9.51,3.09), (8.09,5.88), + (5.88,8.09), (3.09,9.51), (0,10), (-3.09,9.51), + (-5.88,8.09), (-8.09,5.88), (-9.51,3.09), (-10,0), + (-9.51,-3.09), (-8.09,-5.88), (-5.88,-8.09), + (-3.09,-9.51), (-0.00,-10.00), (3.09,-9.51), + (5.88,-8.09), (8.09,-5.88), (9.51,-3.09))), + "square" : Shape("polygon", ((10,-10), (10,10), (-10,10), + (-10,-10))), + "triangle" : Shape("polygon", ((10,-5.77), (0,11.55), + (-10,-5.77))), + "classic": Shape("polygon", ((0,0),(-5,-9),(0,-7),(5,-9))), + "blank" : Shape("image", self._blankimage()) + } + + self._bgpics = {"nopic" : ""} + + TurtleScreenBase.__init__(self, cv) + self._mode = mode + self._delayvalue = delay + self._colormode = _CFG["colormode"] + self._keys = [] + self.clear() + + def clear(self): + """Delete all drawings and all turtles from the TurtleScreen. + + Reset empty TurtleScreen to its initial state: white background, + no backgroundimage, no eventbindings and tracing on. + + No argument. + + Example (for a TurtleScreen instance named screen): + >>> screen.clear() + + Note: this method is not available as function. + """ + self._delayvalue = _CFG["delay"] + self._colormode = _CFG["colormode"] + self._delete("all") + self._bgpic = self._createimage("") + self._bgpicname = "nopic" + self._tracing = 1 + self._updatecounter = 0 + self._turtles = [] + self.bgcolor("white") + for btn in 1, 2, 3: + self.onclick(None, btn) + for key in self._keys[:]: + self.onkey(None, key) + Turtle._pen = None + + def mode(self, mode=None): + """Set turtle-mode ('standard', 'logo' or 'world') and perform reset. + + Optional argument: + mode -- on of the strings 'standard', 'logo' or 'world' + + Mode 'standard' is compatible with turtle.py. + Mode 'logo' is compatible with most Logo-Turtle-Graphics. + Mode 'world' uses userdefined 'worldcoordinates'. *Attention*: in + this mode angles appear distorted if x/y unit-ratio doesn't equal 1. + If mode is not given, return the current mode. + + Mode Initial turtle heading positive angles + ------------|-------------------------|------------------- + 'standard' to the right (east) counterclockwise + 'logo' upward (north) clockwise + + Examples: + >>> mode('logo') # resets turtle heading to north + >>> mode() + 'logo' + """ + if mode is None: + return self._mode + mode = mode.lower() + if mode not in ["standard", "logo", "world"]: + raise TurtleGraphicsError("No turtle-graphics-mode %s" % mode) + self._mode = mode + if mode in ["standard", "logo"]: + self._setscrollregion(-self.canvwidth//2, -self.canvheight//2, + self.canvwidth//2, self.canvheight//2) + self.xscale = self.yscale = 1.0 + self.reset() + + def setworldcoordinates(self, llx, lly, urx, ury): + """Set up a user defined coordinate-system. + + Arguments: + llx -- a number, x-coordinate of lower left corner of canvas + lly -- a number, y-coordinate of lower left corner of canvas + urx -- a number, x-coordinate of upper right corner of canvas + ury -- a number, y-coordinate of upper right corner of canvas + + Set up user coodinat-system and switch to mode 'world' if necessary. + This performs a screen.reset. If mode 'world' is already active, + all drawings are redrawn according to the new coordinates. + + But ATTENTION: in user-defined coordinatesystems angles may appear + distorted. (see Screen.mode()) + + Example (for a TurtleScreen instance named screen): + >>> screen.setworldcoordinates(-10,-0.5,50,1.5) + >>> for _ in range(36): + ... left(10) + ... forward(0.5) + """ + if self.mode() != "world": + self.mode("world") + xspan = float(urx - llx) + yspan = float(ury - lly) + wx, wy = self._window_size() + self.screensize(wx-20, wy-20) + oldxscale, oldyscale = self.xscale, self.yscale + self.xscale = self.canvwidth / xspan + self.yscale = self.canvheight / yspan + srx1 = llx * self.xscale + sry1 = -ury * self.yscale + srx2 = self.canvwidth + srx1 + sry2 = self.canvheight + sry1 + self._setscrollregion(srx1, sry1, srx2, sry2) + self._rescale(self.xscale/oldxscale, self.yscale/oldyscale) + self.update() + + def register_shape(self, name, shape=None): + """Adds a turtle shape to TurtleScreen's shapelist. + + Arguments: + (1) name is the name of a gif-file and shape is None. + Installs the corresponding image shape. + !! Image-shapes DO NOT rotate when turning the turtle, + !! so they do not display the heading of the turtle! + (2) name is an arbitrary string and shape is a tuple + of pairs of coordinates. Installs the corresponding + polygon shape + (3) name is an arbitrary string and shape is a + (compound) Shape object. Installs the corresponding + compound shape. + To use a shape, you have to issue the command shape(shapename). + + call: register_shape("turtle.gif") + --or: register_shape("tri", ((0,0), (10,10), (-10,10))) + + Example (for a TurtleScreen instance named screen): + >>> screen.register_shape("triangle", ((5,-3),(0,5),(-5,-3))) + + """ + if shape is None: + # image + if name.lower().endswith(".gif"): + shape = Shape("image", self._image(name)) + else: + raise TurtleGraphicsError("Bad arguments for register_shape.\n" + + "Use help(register_shape)" ) + elif isinstance(shape, tuple): + shape = Shape("polygon", shape) + ## else shape assumed to be Shape-instance + self._shapes[name] = shape + # print "shape added:" , self._shapes + + def _colorstr(self, color): + """Return color string corresponding to args. + + Argument may be a string or a tuple of three + numbers corresponding to actual colormode, + i.e. in the range 0<=n<=colormode. + + If the argument doesn't represent a color, + an error is raised. + """ + if len(color) == 1: + color = color[0] + if isinstance(color, basestring): + if self._iscolorstring(color) or color == "": + return color + else: + raise TurtleGraphicsError("bad color string: %s" % str(color)) + try: + r, g, b = color + except: + raise TurtleGraphicsError("bad color arguments: %s" % str(color)) + if self._colormode == 1.0: + r, g, b = [round(255.0*x) for x in (r, g, b)] + if not ((0 <= r <= 255) and (0 <= g <= 255) and (0 <= b <= 255)): + raise TurtleGraphicsError("bad color sequence: %s" % str(color)) + return "#%02x%02x%02x" % (r, g, b) + + def _color(self, cstr): + if not cstr.startswith("#"): + return cstr + if len(cstr) == 7: + cl = [int(cstr[i:i+2], 16) for i in (1, 3, 5)] + elif len(cstr) == 4: + cl = [16*int(cstr[h], 16) for h in cstr[1:]] + else: + raise TurtleGraphicsError("bad colorstring: %s" % cstr) + return tuple([c * self._colormode/255 for c in cl]) + + def colormode(self, cmode=None): + """Return the colormode or set it to 1.0 or 255. + + Optional argument: + cmode -- one of the values 1.0 or 255 + + r, g, b values of colortriples have to be in range 0..cmode. + + Example (for a TurtleScreen instance named screen): + >>> screen.colormode() + 1.0 + >>> screen.colormode(255) + >>> pencolor(240,160,80) + """ + if cmode is None: + return self._colormode + if cmode == 1.0: + self._colormode = float(cmode) + elif cmode == 255: + self._colormode = int(cmode) + + def reset(self): + """Reset all Turtles on the Screen to their initial state. + + No argument. + + Example (for a TurtleScreen instance named screen): + >>> screen.reset() + """ + for turtle in self._turtles: + turtle._setmode(self._mode) + turtle.reset() + + def turtles(self): + """Return the list of turtles on the screen. + + Example (for a TurtleScreen instance named screen): + >>> screen.turtles() + [] + """ + return self._turtles + + def bgcolor(self, *args): + """Set or return backgroundcolor of the TurtleScreen. + + Arguments (if given): a color string or three numbers + in the range 0..colormode or a 3-tuple of such numbers. + + Example (for a TurtleScreen instance named screen): + >>> screen.bgcolor("orange") + >>> screen.bgcolor() + 'orange' + >>> screen.bgcolor(0.5,0,0.5) + >>> screen.bgcolor() + '#800080' + """ + if args: + color = self._colorstr(args) + else: + color = None + color = self._bgcolor(color) + if color is not None: + color = self._color(color) + return color + + def tracer(self, n=None, delay=None): + """Turns turtle animation on/off and set delay for update drawings. + + Optional arguments: + n -- nonnegative integer + delay -- nonnegative integer + + If n is given, only each n-th regular screen update is really performed. + (Can be used to accelerate the drawing of complex graphics.) + Second arguments sets delay value (see RawTurtle.delay()) + + Example (for a TurtleScreen instance named screen): + >>> screen.tracer(8, 25) + >>> dist = 2 + >>> for i in range(200): + ... fd(dist) + ... rt(90) + ... dist += 2 + """ + if n is None: + return self._tracing + self._tracing = int(n) + self._updatecounter = 0 + if delay is not None: + self._delayvalue = int(delay) + if self._tracing: + self.update() + + def delay(self, delay=None): + """ Return or set the drawing delay in milliseconds. + + Optional argument: + delay -- positive integer + + Example (for a TurtleScreen instance named screen): + >>> screen.delay(15) + >>> screen.delay() + 15 + """ + if delay is None: + return self._delayvalue + self._delayvalue = int(delay) + + def _incrementudc(self): + """Increment update counter.""" + if not TurtleScreen._RUNNING: + TurtleScreen._RUNNNING = True + raise Terminator + if self._tracing > 0: + self._updatecounter += 1 + self._updatecounter %= self._tracing + + def update(self): + """Perform a TurtleScreen update. + """ + tracing = self._tracing + self._tracing = True + for t in self.turtles(): + t._update_data() + t._drawturtle() + self._tracing = tracing + self._update() + + def window_width(self): + """ Return the width of the turtle window. + + Example (for a TurtleScreen instance named screen): + >>> screen.window_width() + 640 + """ + return self._window_size()[0] + + def window_height(self): + """ Return the height of the turtle window. + + Example (for a TurtleScreen instance named screen): + >>> screen.window_height() + 480 + """ + return self._window_size()[1] + + def getcanvas(self): + """Return the Canvas of this TurtleScreen. + + No argument. + + Example (for a Screen instance named screen): + >>> cv = screen.getcanvas() + >>> cv + + """ + return self.cv + + def getshapes(self): + """Return a list of names of all currently available turtle shapes. + + No argument. + + Example (for a TurtleScreen instance named screen): + >>> screen.getshapes() + ['arrow', 'blank', 'circle', ... , 'turtle'] + """ + return sorted(self._shapes.keys()) + + def onclick(self, fun, btn=1, add=None): + """Bind fun to mouse-click event on canvas. + + Arguments: + fun -- a function with two arguments, the coordinates of the + clicked point on the canvas. + num -- the number of the mouse-button, defaults to 1 + + Example (for a TurtleScreen instance named screen + and a Turtle instance named turtle): + + >>> screen.onclick(goto) + >>> # Subsequently clicking into the TurtleScreen will + >>> # make the turtle move to the clicked point. + >>> screen.onclick(None) + """ + self._onscreenclick(fun, btn, add) + + def onkey(self, fun, key): + """Bind fun to key-release event of key. + + Arguments: + fun -- a function with no arguments + key -- a string: key (e.g. "a") or key-symbol (e.g. "space") + + In order to be able to register key-events, TurtleScreen + must have focus. (See method listen.) + + Example (for a TurtleScreen instance named screen): + + >>> def f(): + ... fd(50) + ... lt(60) + ... + >>> screen.onkey(f, "Up") + >>> screen.listen() + + Subsequently the turtle can be moved by repeatedly pressing + the up-arrow key, consequently drawing a hexagon + + """ + if fun is None: + if key in self._keys: + self._keys.remove(key) + elif key not in self._keys: + self._keys.append(key) + self._onkey(fun, key) + + def listen(self, xdummy=None, ydummy=None): + """Set focus on TurtleScreen (in order to collect key-events) + + No arguments. + Dummy arguments are provided in order + to be able to pass listen to the onclick method. + + Example (for a TurtleScreen instance named screen): + >>> screen.listen() + """ + self._listen() + + def ontimer(self, fun, t=0): + """Install a timer, which calls fun after t milliseconds. + + Arguments: + fun -- a function with no arguments. + t -- a number >= 0 + + Example (for a TurtleScreen instance named screen): + + >>> running = True + >>> def f(): + ... if running: + ... fd(50) + ... lt(60) + ... screen.ontimer(f, 250) + ... + >>> f() # makes the turtle marching around + >>> running = False + """ + self._ontimer(fun, t) + + def bgpic(self, picname=None): + """Set background image or return name of current backgroundimage. + + Optional argument: + picname -- a string, name of a gif-file or "nopic". + + If picname is a filename, set the corresponding image as background. + If picname is "nopic", delete backgroundimage, if present. + If picname is None, return the filename of the current backgroundimage. + + Example (for a TurtleScreen instance named screen): + >>> screen.bgpic() + 'nopic' + >>> screen.bgpic("landscape.gif") + >>> screen.bgpic() + 'landscape.gif' + """ + if picname is None: + return self._bgpicname + if picname not in self._bgpics: + self._bgpics[picname] = self._image(picname) + self._setbgpic(self._bgpic, self._bgpics[picname]) + self._bgpicname = picname + + def screensize(self, canvwidth=None, canvheight=None, bg=None): + """Resize the canvas the turtles are drawing on. + + Optional arguments: + canvwidth -- positive integer, new width of canvas in pixels + canvheight -- positive integer, new height of canvas in pixels + bg -- colorstring or color-tuple, new backgroundcolor + If no arguments are given, return current (canvaswidth, canvasheight) + + Do not alter the drawing window. To observe hidden parts of + the canvas use the scrollbars. (Can make visible those parts + of a drawing, which were outside the canvas before!) + + Example (for a Turtle instance named turtle): + >>> turtle.screensize(2000,1500) + >>> # e. g. to search for an erroneously escaped turtle ;-) + """ + return self._resize(canvwidth, canvheight, bg) + + onscreenclick = onclick + resetscreen = reset + clearscreen = clear + addshape = register_shape + +class TNavigator(object): + """Navigation part of the RawTurtle. + Implements methods for turtle movement. + """ + START_ORIENTATION = { + "standard": Vec2D(1.0, 0.0), + "world" : Vec2D(1.0, 0.0), + "logo" : Vec2D(0.0, 1.0) } + DEFAULT_MODE = "standard" + DEFAULT_ANGLEOFFSET = 0 + DEFAULT_ANGLEORIENT = 1 + + def __init__(self, mode=DEFAULT_MODE): + self._angleOffset = self.DEFAULT_ANGLEOFFSET + self._angleOrient = self.DEFAULT_ANGLEORIENT + self._mode = mode + self.undobuffer = None + self.degrees() + self._mode = None + self._setmode(mode) + TNavigator.reset(self) + + def reset(self): + """reset turtle to its initial values + + Will be overwritten by parent class + """ + self._position = Vec2D(0.0, 0.0) + self._orient = TNavigator.START_ORIENTATION[self._mode] + + def _setmode(self, mode=None): + """Set turtle-mode to 'standard', 'world' or 'logo'. + """ + if mode is None: + return self._mode + if mode not in ["standard", "logo", "world"]: + return + self._mode = mode + if mode in ["standard", "world"]: + self._angleOffset = 0 + self._angleOrient = 1 + else: # mode == "logo": + self._angleOffset = self._fullcircle/4. + self._angleOrient = -1 + + def _setDegreesPerAU(self, fullcircle): + """Helper function for degrees() and radians()""" + self._fullcircle = fullcircle + self._degreesPerAU = 360/fullcircle + if self._mode == "standard": + self._angleOffset = 0 + else: + self._angleOffset = fullcircle/4. + + def degrees(self, fullcircle=360.0): + """ Set angle measurement units to degrees. + + Optional argument: + fullcircle - a number + + Set angle measurement units, i. e. set number + of 'degrees' for a full circle. Dafault value is + 360 degrees. + + Example (for a Turtle instance named turtle): + >>> turtle.left(90) + >>> turtle.heading() + 90 + + Change angle measurement unit to grad (also known as gon, + grade, or gradian and equals 1/100-th of the right angle.) + >>> turtle.degrees(400.0) + >>> turtle.heading() + 100 + + """ + self._setDegreesPerAU(fullcircle) + + def radians(self): + """ Set the angle measurement units to radians. + + No arguments. + + Example (for a Turtle instance named turtle): + >>> turtle.heading() + 90 + >>> turtle.radians() + >>> turtle.heading() + 1.5707963267948966 + """ + self._setDegreesPerAU(2*math.pi) + + def _go(self, distance): + """move turtle forward by specified distance""" + ende = self._position + self._orient * distance + self._goto(ende) + + def _rotate(self, angle): + """Turn turtle counterclockwise by specified angle if angle > 0.""" + angle *= self._degreesPerAU + self._orient = self._orient.rotate(angle) + + def _goto(self, end): + """move turtle to position end.""" + self._position = end + + def forward(self, distance): + """Move the turtle forward by the specified distance. + + Aliases: forward | fd + + Argument: + distance -- a number (integer or float) + + Move the turtle forward by the specified distance, in the direction + the turtle is headed. + + Example (for a Turtle instance named turtle): + >>> turtle.position() + (0.00, 0.00) + >>> turtle.forward(25) + >>> turtle.position() + (25.00,0.00) + >>> turtle.forward(-75) + >>> turtle.position() + (-50.00,0.00) + """ + self._go(distance) + + def back(self, distance): + """Move the turtle backward by distance. + + Aliases: back | backward | bk + + Argument: + distance -- a number + + Move the turtle backward by distance ,opposite to the direction the + turtle is headed. Do not change the turtle's heading. + + Example (for a Turtle instance named turtle): + >>> turtle.position() + (0.00, 0.00) + >>> turtle.backward(30) + >>> turtle.position() + (-30.00, 0.00) + """ + self._go(-distance) + + def right(self, angle): + """Turn turtle right by angle units. + + Aliases: right | rt + + Argument: + angle -- a number (integer or float) + + Turn turtle right by angle units. (Units are by default degrees, + but can be set via the degrees() and radians() functions.) + Angle orientation depends on mode. (See this.) + + Example (for a Turtle instance named turtle): + >>> turtle.heading() + 22.0 + >>> turtle.right(45) + >>> turtle.heading() + 337.0 + """ + self._rotate(-angle) + + def left(self, angle): + """Turn turtle left by angle units. + + Aliases: left | lt + + Argument: + angle -- a number (integer or float) + + Turn turtle left by angle units. (Units are by default degrees, + but can be set via the degrees() and radians() functions.) + Angle orientation depends on mode. (See this.) + + Example (for a Turtle instance named turtle): + >>> turtle.heading() + 22.0 + >>> turtle.left(45) + >>> turtle.heading() + 67.0 + """ + self._rotate(angle) + + def pos(self): + """Return the turtle's current location (x,y), as a Vec2D-vector. + + Aliases: pos | position + + No arguments. + + Example (for a Turtle instance named turtle): + >>> turtle.pos() + (0.00, 240.00) + """ + return self._position + + def xcor(self): + """ Return the turtle's x coordinate. + + No arguments. + + Example (for a Turtle instance named turtle): + >>> reset() + >>> turtle.left(60) + >>> turtle.forward(100) + >>> print turtle.xcor() + 50.0 + """ + return self._position[0] + + def ycor(self): + """ Return the turtle's y coordinate + --- + No arguments. + + Example (for a Turtle instance named turtle): + >>> reset() + >>> turtle.left(60) + >>> turtle.forward(100) + >>> print turtle.ycor() + 86.6025403784 + """ + return self._position[1] + + + def goto(self, x, y=None): + """Move turtle to an absolute position. + + Aliases: setpos | setposition | goto: + + Arguments: + x -- a number or a pair/vector of numbers + y -- a number None + + call: goto(x, y) # two coordinates + --or: goto((x, y)) # a pair (tuple) of coordinates + --or: goto(vec) # e.g. as returned by pos() + + Move turtle to an absolute position. If the pen is down, + a line will be drawn. The turtle's orientation does not change. + + Example (for a Turtle instance named turtle): + >>> tp = turtle.pos() + >>> tp + (0.00, 0.00) + >>> turtle.setpos(60,30) + >>> turtle.pos() + (60.00,30.00) + >>> turtle.setpos((20,80)) + >>> turtle.pos() + (20.00,80.00) + >>> turtle.setpos(tp) + >>> turtle.pos() + (0.00,0.00) + """ + if y is None: + self._goto(Vec2D(*x)) + else: + self._goto(Vec2D(x, y)) + + def home(self): + """Move turtle to the origin - coordinates (0,0). + + No arguments. + + Move turtle to the origin - coordinates (0,0) and set its + heading to its start-orientation (which depends on mode). + + Example (for a Turtle instance named turtle): + >>> turtle.home() + """ + self.goto(0, 0) + self.setheading(0) + + def setx(self, x): + """Set the turtle's first coordinate to x + + Argument: + x -- a number (integer or float) + + Set the turtle's first coordinate to x, leave second coordinate + unchanged. + + Example (for a Turtle instance named turtle): + >>> turtle.position() + (0.00, 240.00) + >>> turtle.setx(10) + >>> turtle.position() + (10.00, 240.00) + """ + self._goto(Vec2D(x, self._position[1])) + + def sety(self, y): + """Set the turtle's second coordinate to y + + Argument: + y -- a number (integer or float) + + Set the turtle's first coordinate to x, second coordinate remains + unchanged. + + Example (for a Turtle instance named turtle): + >>> turtle.position() + (0.00, 40.00) + >>> turtle.sety(-10) + >>> turtle.position() + (0.00, -10.00) + """ + self._goto(Vec2D(self._position[0], y)) + + def distance(self, x, y=None): + """Return the distance from the turtle to (x,y) in turtle step units. + + Arguments: + x -- a number or a pair/vector of numbers or a turtle instance + y -- a number None None + + call: distance(x, y) # two coordinates + --or: distance((x, y)) # a pair (tuple) of coordinates + --or: distance(vec) # e.g. as returned by pos() + --or: distance(mypen) # where mypen is another turtle + + Example (for a Turtle instance named turtle): + >>> turtle.pos() + (0.00, 0.00) + >>> turtle.distance(30,40) + 50.0 + >>> pen = Turtle() + >>> pen.forward(77) + >>> turtle.distance(pen) + 77.0 + """ + if y is not None: + pos = Vec2D(x, y) + if isinstance(x, Vec2D): + pos = x + elif isinstance(x, tuple): + pos = Vec2D(*x) + elif isinstance(x, TNavigator): + pos = x._position + return abs(pos - self._position) + + def towards(self, x, y=None): + """Return the angle of the line from the turtle's position to (x, y). + + Arguments: + x -- a number or a pair/vector of numbers or a turtle instance + y -- a number None None + + call: distance(x, y) # two coordinates + --or: distance((x, y)) # a pair (tuple) of coordinates + --or: distance(vec) # e.g. as returned by pos() + --or: distance(mypen) # where mypen is another turtle + + Return the angle, between the line from turtle-position to position + specified by x, y and the turtle's start orientation. (Depends on + modes - "standard" or "logo") + + Example (for a Turtle instance named turtle): + >>> turtle.pos() + (10.00, 10.00) + >>> turtle.towards(0,0) + 225.0 + """ + if y is not None: + pos = Vec2D(x, y) + if isinstance(x, Vec2D): + pos = x + elif isinstance(x, tuple): + pos = Vec2D(*x) + elif isinstance(x, TNavigator): + pos = x._position + x, y = pos - self._position + result = round(math.atan2(y, x)*180.0/math.pi, 10) % 360.0 + result /= self._degreesPerAU + return (self._angleOffset + self._angleOrient*result) % self._fullcircle + + def heading(self): + """ Return the turtle's current heading. + + No arguments. + + Example (for a Turtle instance named turtle): + >>> turtle.left(67) + >>> turtle.heading() + 67.0 + """ + x, y = self._orient + result = round(math.atan2(y, x)*180.0/math.pi, 10) % 360.0 + result /= self._degreesPerAU + return (self._angleOffset + self._angleOrient*result) % self._fullcircle + + def setheading(self, to_angle): + """Set the orientation of the turtle to to_angle. + + Aliases: setheading | seth + + Argument: + to_angle -- a number (integer or float) + + Set the orientation of the turtle to to_angle. + Here are some common directions in degrees: + + standard - mode: logo-mode: + -------------------|-------------------- + 0 - east 0 - north + 90 - north 90 - east + 180 - west 180 - south + 270 - south 270 - west + + Example (for a Turtle instance named turtle): + >>> turtle.setheading(90) + >>> turtle.heading() + 90 + """ + angle = (to_angle - self.heading())*self._angleOrient + full = self._fullcircle + angle = (angle+full/2.)%full - full/2. + self._rotate(angle) + + def circle(self, radius, extent = None, steps = None): + """ Draw a circle with given radius. + + Arguments: + radius -- a number + extent (optional) -- a number + steps (optional) -- an integer + + Draw a circle with given radius. The center is radius units left + of the turtle; extent - an angle - determines which part of the + circle is drawn. If extent is not given, draw the entire circle. + If extent is not a full circle, one endpoint of the arc is the + current pen position. Draw the arc in counterclockwise direction + if radius is positive, otherwise in clockwise direction. Finally + the direction of the turtle is changed by the amount of extent. + + As the circle is approximated by an inscribed regular polygon, + steps determines the number of steps to use. If not given, + it will be calculated automatically. Maybe used to draw regular + polygons. + + call: circle(radius) # full circle + --or: circle(radius, extent) # arc + --or: circle(radius, extent, steps) + --or: circle(radius, steps=6) # 6-sided polygon + + Example (for a Turtle instance named turtle): + >>> turtle.circle(50) + >>> turtle.circle(120, 180) # semicircle + """ + if self.undobuffer: + self.undobuffer.push(["seq"]) + self.undobuffer.cumulate = True + speed = self.speed() + if extent is None: + extent = self._fullcircle + if steps is None: + frac = abs(extent)/self._fullcircle + steps = 1+int(min(11+abs(radius)/6.0, 59.0)*frac) + w = 1.0 * extent / steps + w2 = 0.5 * w + l = 2.0 * radius * math.sin(w2*math.pi/180.0*self._degreesPerAU) + if radius < 0: + l, w, w2 = -l, -w, -w2 + tr = self.tracer() + dl = self._delay() + if speed == 0: + self.tracer(0, 0) + else: + self.speed(0) + self._rotate(w2) + for i in range(steps): + self.speed(speed) + self._go(l) + self.speed(0) + self._rotate(w) + self._rotate(-w2) + if speed == 0: + self.tracer(tr, dl) + self.speed(speed) + if self.undobuffer: + self.undobuffer.cumulate = False + +## three dummy methods to be implemented by child class: + + def speed(self, s=0): + """dummy method - to be overwritten by child class""" + def tracer(self, a=None, b=None): + """dummy method - to be overwritten by child class""" + def _delay(self, n=None): + """dummy method - to be overwritten by child class""" + + fd = forward + bk = back + backward = back + rt = right + lt = left + position = pos + setpos = goto + setposition = goto + seth = setheading + + +class TPen(object): + """Drawing part of the RawTurtle. + Implements drawing properties. + """ + def __init__(self, resizemode=_CFG["resizemode"]): + self._resizemode = resizemode # or "user" or "noresize" + self.undobuffer = None + TPen._reset(self) + + def _reset(self, pencolor=_CFG["pencolor"], + fillcolor=_CFG["fillcolor"]): + self._pensize = 1 + self._shown = True + self._pencolor = pencolor + self._fillcolor = fillcolor + self._drawing = True + self._speed = 3 + self._stretchfactor = (1, 1) + self._tilt = 0 + self._outlinewidth = 1 + ### self.screen = None # to override by child class + + def resizemode(self, rmode=None): + """Set resizemode to one of the values: "auto", "user", "noresize". + + (Optional) Argument: + rmode -- one of the strings "auto", "user", "noresize" + + Different resizemodes have the following effects: + - "auto" adapts the appearance of the turtle + corresponding to the value of pensize. + - "user" adapts the appearance of the turtle according to the + values of stretchfactor and outlinewidth (outline), + which are set by shapesize() + - "noresize" no adaption of the turtle's appearance takes place. + If no argument is given, return current resizemode. + resizemode("user") is called by a call of shapesize with arguments. + + + Examples (for a Turtle instance named turtle): + >>> turtle.resizemode("noresize") + >>> turtle.resizemode() + 'noresize' + """ + if rmode is None: + return self._resizemode + rmode = rmode.lower() + if rmode in ["auto", "user", "noresize"]: + self.pen(resizemode=rmode) + + def pensize(self, width=None): + """Set or return the line thickness. + + Aliases: pensize | width + + Argument: + width -- positive number + + Set the line thickness to width or return it. If resizemode is set + to "auto" and turtleshape is a polygon, that polygon is drawn with + the same line thickness. If no argument is given, current pensize + is returned. + + Example (for a Turtle instance named turtle): + >>> turtle.pensize() + 1 + >>> turtle.pensize(10) # from here on lines of width 10 are drawn + """ + if width is None: + return self._pensize + self.pen(pensize=width) + + + def penup(self): + """Pull the pen up -- no drawing when moving. + + Aliases: penup | pu | up + + No argument + + Example (for a Turtle instance named turtle): + >>> turtle.penup() + """ + if not self._drawing: + return + self.pen(pendown=False) + + def pendown(self): + """Pull the pen down -- drawing when moving. + + Aliases: pendown | pd | down + + No argument. + + Example (for a Turtle instance named turtle): + >>> turtle.pendown() + """ + if self._drawing: + return + self.pen(pendown=True) + + def isdown(self): + """Return True if pen is down, False if it's up. + + No argument. + + Example (for a Turtle instance named turtle): + >>> turtle.penup() + >>> turtle.isdown() + False + >>> turtle.pendown() + >>> turtle.isdown() + True + """ + return self._drawing + + def speed(self, speed=None): + """ Return or set the turtle's speed. + + Optional argument: + speed -- an integer in the range 0..10 or a speedstring (see below) + + Set the turtle's speed to an integer value in the range 0 .. 10. + If no argument is given: return current speed. + + If input is a number greater than 10 or smaller than 0.5, + speed is set to 0. + Speedstrings are mapped to speedvalues in the following way: + 'fastest' : 0 + 'fast' : 10 + 'normal' : 6 + 'slow' : 3 + 'slowest' : 1 + speeds from 1 to 10 enforce increasingly faster animation of + line drawing and turtle turning. + + Attention: + speed = 0 : *no* animation takes place. forward/back makes turtle jump + and likewise left/right make the turtle turn instantly. + + Example (for a Turtle instance named turtle): + >>> turtle.speed(3) + """ + speeds = {'fastest':0, 'fast':10, 'normal':6, 'slow':3, 'slowest':1 } + if speed is None: + return self._speed + if speed in speeds: + speed = speeds[speed] + elif 0.5 < speed < 10.5: + speed = int(round(speed)) + else: + speed = 0 + self.pen(speed=speed) + + def color(self, *args): + """Return or set the pencolor and fillcolor. + + Arguments: + Several input formats are allowed. + They use 0, 1, 2, or 3 arguments as follows: + + color() + Return the current pencolor and the current fillcolor + as a pair of color specification strings as are returned + by pencolor and fillcolor. + color(colorstring), color((r,g,b)), color(r,g,b) + inputs as in pencolor, set both, fillcolor and pencolor, + to the given value. + color(colorstring1, colorstring2), + color((r1,g1,b1), (r2,g2,b2)) + equivalent to pencolor(colorstring1) and fillcolor(colorstring2) + and analogously, if the other input format is used. + + If turtleshape is a polygon, outline and interior of that polygon + is drawn with the newly set colors. + For mor info see: pencolor, fillcolor + + Example (for a Turtle instance named turtle): + >>> turtle.color('red', 'green') + >>> turtle.color() + ('red', 'green') + >>> colormode(255) + >>> color((40, 80, 120), (160, 200, 240)) + >>> color() + ('#285078', '#a0c8f0') + """ + if args: + l = len(args) + if l == 1: + pcolor = fcolor = args[0] + elif l == 2: + pcolor, fcolor = args + elif l == 3: + pcolor = fcolor = args + pcolor = self._colorstr(pcolor) + fcolor = self._colorstr(fcolor) + self.pen(pencolor=pcolor, fillcolor=fcolor) + else: + return self._color(self._pencolor), self._color(self._fillcolor) + + def pencolor(self, *args): + """ Return or set the pencolor. + + Arguments: + Four input formats are allowed: + - pencolor() + Return the current pencolor as color specification string, + possibly in hex-number format (see example). + May be used as input to another color/pencolor/fillcolor call. + - pencolor(colorstring) + s is a Tk color specification string, such as "red" or "yellow" + - pencolor((r, g, b)) + *a tuple* of r, g, and b, which represent, an RGB color, + and each of r, g, and b are in the range 0..colormode, + where colormode is either 1.0 or 255 + - pencolor(r, g, b) + r, g, and b represent an RGB color, and each of r, g, and b + are in the range 0..colormode + + If turtleshape is a polygon, the outline of that polygon is drawn + with the newly set pencolor. + + Example (for a Turtle instance named turtle): + >>> turtle.pencolor('brown') + >>> tup = (0.2, 0.8, 0.55) + >>> turtle.pencolor(tup) + >>> turtle.pencolor() + '#33cc8c' + """ + if args: + color = self._colorstr(args) + if color == self._pencolor: + return + self.pen(pencolor=color) + else: + return self._color(self._pencolor) + + def fillcolor(self, *args): + """ Return or set the fillcolor. + + Arguments: + Four input formats are allowed: + - fillcolor() + Return the current fillcolor as color specification string, + possibly in hex-number format (see example). + May be used as input to another color/pencolor/fillcolor call. + - fillcolor(colorstring) + s is a Tk color specification string, such as "red" or "yellow" + - fillcolor((r, g, b)) + *a tuple* of r, g, and b, which represent, an RGB color, + and each of r, g, and b are in the range 0..colormode, + where colormode is either 1.0 or 255 + - fillcolor(r, g, b) + r, g, and b represent an RGB color, and each of r, g, and b + are in the range 0..colormode + + If turtleshape is a polygon, the interior of that polygon is drawn + with the newly set fillcolor. + + Example (for a Turtle instance named turtle): + >>> turtle.fillcolor('violet') + >>> col = turtle.pencolor() + >>> turtle.fillcolor(col) + >>> turtle.fillcolor(0, .5, 0) + """ + if args: + color = self._colorstr(args) + if color == self._fillcolor: + return + self.pen(fillcolor=color) + else: + return self._color(self._fillcolor) + + def showturtle(self): + """Makes the turtle visible. + + Aliases: showturtle | st + + No argument. + + Example (for a Turtle instance named turtle): + >>> turtle.hideturtle() + >>> turtle.showturtle() + """ + self.pen(shown=True) + + def hideturtle(self): + """Makes the turtle invisible. + + Aliases: hideturtle | ht + + No argument. + + It's a good idea to do this while you're in the + middle of a complicated drawing, because hiding + the turtle speeds up the drawing observably. + + Example (for a Turtle instance named turtle): + >>> turtle.hideturtle() + """ + self.pen(shown=False) + + def isvisible(self): + """Return True if the Turtle is shown, False if it's hidden. + + No argument. + + Example (for a Turtle instance named turtle): + >>> turtle.hideturtle() + >>> print turtle.isvisible(): + False + """ + return self._shown + + def pen(self, pen=None, **pendict): + """Return or set the pen's attributes. + + Arguments: + pen -- a dictionary with some or all of the below listed keys. + **pendict -- one or more keyword-arguments with the below + listed keys as keywords. + + Return or set the pen's attributes in a 'pen-dictionary' + with the following key/value pairs: + "shown" : True/False + "pendown" : True/False + "pencolor" : color-string or color-tuple + "fillcolor" : color-string or color-tuple + "pensize" : positive number + "speed" : number in range 0..10 + "resizemode" : "auto" or "user" or "noresize" + "stretchfactor": (positive number, positive number) + "outline" : positive number + "tilt" : number + + This dictionary can be used as argument for a subsequent + pen()-call to restore the former pen-state. Moreover one + or more of these attributes can be provided as keyword-arguments. + This can be used to set several pen attributes in one statement. + + + Examples (for a Turtle instance named turtle): + >>> turtle.pen(fillcolor="black", pencolor="red", pensize=10) + >>> turtle.pen() + {'pensize': 10, 'shown': True, 'resizemode': 'auto', 'outline': 1, + 'pencolor': 'red', 'pendown': True, 'fillcolor': 'black', + 'stretchfactor': (1,1), 'speed': 3} + >>> penstate=turtle.pen() + >>> turtle.color("yellow","") + >>> turtle.penup() + >>> turtle.pen() + {'pensize': 10, 'shown': True, 'resizemode': 'auto', 'outline': 1, + 'pencolor': 'yellow', 'pendown': False, 'fillcolor': '', + 'stretchfactor': (1,1), 'speed': 3} + >>> p.pen(penstate, fillcolor="green") + >>> p.pen() + {'pensize': 10, 'shown': True, 'resizemode': 'auto', 'outline': 1, + 'pencolor': 'red', 'pendown': True, 'fillcolor': 'green', + 'stretchfactor': (1,1), 'speed': 3} + """ + _pd = {"shown" : self._shown, + "pendown" : self._drawing, + "pencolor" : self._pencolor, + "fillcolor" : self._fillcolor, + "pensize" : self._pensize, + "speed" : self._speed, + "resizemode" : self._resizemode, + "stretchfactor" : self._stretchfactor, + "outline" : self._outlinewidth, + "tilt" : self._tilt + } + + if not (pen or pendict): + return _pd + + if isinstance(pen, dict): + p = pen + else: + p = {} + p.update(pendict) + + _p_buf = {} + for key in p: + _p_buf[key] = _pd[key] + + if self.undobuffer: + self.undobuffer.push(("pen", _p_buf)) + + newLine = False + if "pendown" in p: + if self._drawing != p["pendown"]: + newLine = True + if "pencolor" in p: + if isinstance(p["pencolor"], tuple): + p["pencolor"] = self._colorstr((p["pencolor"],)) + if self._pencolor != p["pencolor"]: + newLine = True + if "pensize" in p: + if self._pensize != p["pensize"]: + newLine = True + if newLine: + self._newLine() + if "pendown" in p: + self._drawing = p["pendown"] + if "pencolor" in p: + self._pencolor = p["pencolor"] + if "pensize" in p: + self._pensize = p["pensize"] + if "fillcolor" in p: + if isinstance(p["fillcolor"], tuple): + p["fillcolor"] = self._colorstr((p["fillcolor"],)) + self._fillcolor = p["fillcolor"] + if "speed" in p: + self._speed = p["speed"] + if "resizemode" in p: + self._resizemode = p["resizemode"] + if "stretchfactor" in p: + sf = p["stretchfactor"] + if isinstance(sf, (int, float)): + sf = (sf, sf) + self._stretchfactor = sf + if "outline" in p: + self._outlinewidth = p["outline"] + if "shown" in p: + self._shown = p["shown"] + if "tilt" in p: + self._tilt = p["tilt"] + self._update() + +## three dummy methods to be implemented by child class: + + def _newLine(self, usePos = True): + """dummy method - to be overwritten by child class""" + def _update(self, count=True, forced=False): + """dummy method - to be overwritten by child class""" + def _color(self, args): + """dummy method - to be overwritten by child class""" + def _colorstr(self, args): + """dummy method - to be overwritten by child class""" + + width = pensize + up = penup + pu = penup + pd = pendown + down = pendown + st = showturtle + ht = hideturtle + + +class _TurtleImage(object): + """Helper class: Datatype to store Turtle attributes + """ + + def __init__(self, screen, shapeIndex): + self.screen = screen + self._type = None + self._setshape(shapeIndex) + + def _setshape(self, shapeIndex): + screen = self.screen # RawTurtle.screens[self.screenIndex] + self.shapeIndex = shapeIndex + if self._type == "polygon" == screen._shapes[shapeIndex]._type: + return + if self._type == "image" == screen._shapes[shapeIndex]._type: + return + if self._type in ["image", "polygon"]: + screen._delete(self._item) + elif self._type == "compound": + for item in self._item: + screen._delete(item) + self._type = screen._shapes[shapeIndex]._type + if self._type == "polygon": + self._item = screen._createpoly() + elif self._type == "image": + self._item = screen._createimage(screen._shapes["blank"]._data) + elif self._type == "compound": + self._item = [screen._createpoly() for item in + screen._shapes[shapeIndex]._data] + + +class RawTurtle(TPen, TNavigator): + """Animation part of the RawTurtle. + Puts RawTurtle upon a TurtleScreen and provides tools for + its animation. + """ + screens = [] + + def __init__(self, canvas=None, + shape=_CFG["shape"], + undobuffersize=_CFG["undobuffersize"], + visible=_CFG["visible"]): + if isinstance(canvas, _Screen): + self.screen = canvas + elif isinstance(canvas, TurtleScreen): + if canvas not in RawTurtle.screens: + RawTurtle.screens.append(canvas) + self.screen = canvas + elif isinstance(canvas, (ScrolledCanvas, Canvas)): + for screen in RawTurtle.screens: + if screen.cv == canvas: + self.screen = screen + break + else: + self.screen = TurtleScreen(canvas) + RawTurtle.screens.append(self.screen) + else: + raise TurtleGraphicsError("bad canvas argument %s" % canvas) + + screen = self.screen + TNavigator.__init__(self, screen.mode()) + TPen.__init__(self) + screen._turtles.append(self) + self.drawingLineItem = screen._createline() + self.turtle = _TurtleImage(screen, shape) + self._poly = None + self._creatingPoly = False + self._fillitem = self._fillpath = None + self._shown = visible + self._hidden_from_screen = False + self.currentLineItem = screen._createline() + self.currentLine = [self._position] + self.items = [self.currentLineItem] + self.stampItems = [] + self._undobuffersize = undobuffersize + self.undobuffer = Tbuffer(undobuffersize) + self._update() + + def reset(self): + """Delete the turtle's drawings and restore its default values. + + No argument. +, + Delete the turtle's drawings from the screen, re-center the turtle + and set variables to the default values. + + Example (for a Turtle instance named turtle): + >>> turtle.position() + (0.00,-22.00) + >>> turtle.heading() + 100.0 + >>> turtle.reset() + >>> turtle.position() + (0.00,0.00) + >>> turtle.heading() + 0.0 + """ + TNavigator.reset(self) + TPen._reset(self) + self._clear() + self._drawturtle() + self._update() + + def setundobuffer(self, size): + """Set or disable undobuffer. + + Argument: + size -- an integer or None + + If size is an integer an empty undobuffer of given size is installed. + Size gives the maximum number of turtle-actions that can be undone + by the undo() function. + If size is None, no undobuffer is present. + + Example (for a Turtle instance named turtle): + >>> turtle.setundobuffer(42) + """ + if size is None: + self.undobuffer = None + else: + self.undobuffer = Tbuffer(size) + + def undobufferentries(self): + """Return count of entries in the undobuffer. + + No argument. + + Example (for a Turtle instance named turtle): + >>> while undobufferentries(): + ... undo() + """ + if self.undobuffer is None: + return 0 + return self.undobuffer.nr_of_items() + + def _clear(self): + """Delete all of pen's drawings""" + self._fillitem = self._fillpath = None + for item in self.items: + self.screen._delete(item) + self.currentLineItem = self.screen._createline() + self.currentLine = [] + if self._drawing: + self.currentLine.append(self._position) + self.items = [self.currentLineItem] + self.clearstamps() + self.setundobuffer(self._undobuffersize) + + + def clear(self): + """Delete the turtle's drawings from the screen. Do not move turtle. + + No arguments. + + Delete the turtle's drawings from the screen. Do not move turtle. + State and position of the turtle as well as drawings of other + turtles are not affected. + + Examples (for a Turtle instance named turtle): + >>> turtle.clear() + """ + self._clear() + self._update() + + def _update_data(self): + self.screen._incrementudc() + if self.screen._updatecounter != 0: + return + if len(self.currentLine)>1: + self.screen._drawline(self.currentLineItem, self.currentLine, + self._pencolor, self._pensize) + + def _update(self): + """Perform a Turtle-data update. + """ + screen = self.screen + if screen._tracing == 0: + return + elif screen._tracing == 1: + self._update_data() + self._drawturtle() + screen._update() # TurtleScreenBase + screen._delay(screen._delayvalue) # TurtleScreenBase + else: + self._update_data() + if screen._updatecounter == 0: + for t in screen.turtles(): + t._drawturtle() + screen._update() + + def tracer(self, flag=None, delay=None): + """Turns turtle animation on/off and set delay for update drawings. + + Optional arguments: + n -- nonnegative integer + delay -- nonnegative integer + + If n is given, only each n-th regular screen update is really performed. + (Can be used to accelerate the drawing of complex graphics.) + Second arguments sets delay value (see RawTurtle.delay()) + + Example (for a Turtle instance named turtle): + >>> turtle.tracer(8, 25) + >>> dist = 2 + >>> for i in range(200): + ... turtle.fd(dist) + ... turtle.rt(90) + ... dist += 2 + """ + return self.screen.tracer(flag, delay) + + def _color(self, args): + return self.screen._color(args) + + def _colorstr(self, args): + return self.screen._colorstr(args) + + def _cc(self, args): + """Convert colortriples to hexstrings. + """ + if isinstance(args, basestring): + return args + try: + r, g, b = args + except: + raise TurtleGraphicsError("bad color arguments: %s" % str(args)) + if self.screen._colormode == 1.0: + r, g, b = [round(255.0*x) for x in (r, g, b)] + if not ((0 <= r <= 255) and (0 <= g <= 255) and (0 <= b <= 255)): + raise TurtleGraphicsError("bad color sequence: %s" % str(args)) + return "#%02x%02x%02x" % (r, g, b) + + def clone(self): + """Create and return a clone of the turtle. + + No argument. + + Create and return a clone of the turtle with same position, heading + and turtle properties. + + Example (for a Turtle instance named mick): + mick = Turtle() + joe = mick.clone() + """ + screen = self.screen + self._newLine(self._drawing) + + turtle = self.turtle + self.screen = None + self.turtle = None # too make self deepcopy-able + + q = deepcopy(self) + + self.screen = screen + self.turtle = turtle + + q.screen = screen + q.turtle = _TurtleImage(screen, self.turtle.shapeIndex) + + screen._turtles.append(q) + ttype = screen._shapes[self.turtle.shapeIndex]._type + if ttype == "polygon": + q.turtle._item = screen._createpoly() + elif ttype == "image": + q.turtle._item = screen._createimage(screen._shapes["blank"]._data) + elif ttype == "compound": + q.turtle._item = [screen._createpoly() for item in + screen._shapes[self.turtle.shapeIndex]._data] + q.currentLineItem = screen._createline() + q._update() + return q + + def shape(self, name=None): + """Set turtle shape to shape with given name / return current shapename. + + Optional argument: + name -- a string, which is a valid shapename + + Set turtle shape to shape with given name or, if name is not given, + return name of current shape. + Shape with name must exist in the TurtleScreen's shape dictionary. + Initially there are the following polygon shapes: + 'arrow', 'turtle', 'circle', 'square', 'triangle', 'classic'. + To learn about how to deal with shapes see Screen-method register_shape. + + Example (for a Turtle instance named turtle): + >>> turtle.shape() + 'arrow' + >>> turtle.shape("turtle") + >>> turtle.shape() + 'turtle' + """ + if name is None: + return self.turtle.shapeIndex + if not name in self.screen.getshapes(): + raise TurtleGraphicsError("There is no shape named %s" % name) + self.turtle._setshape(name) + self._update() + + def shapesize(self, stretch_wid=None, stretch_len=None, outline=None): + """Set/return turtle's stretchfactors/outline. Set resizemode to "user". + + Optional arguments: + stretch_wid : positive number + stretch_len : positive number + outline : positive number + + Return or set the pen's attributes x/y-stretchfactors and/or outline. + Set resizemode to "user". + If and only if resizemode is set to "user", the turtle will be displayed + stretched according to its stretchfactors: + stretch_wid is stretchfactor perpendicular to orientation + stretch_len is stretchfactor in direction of turtles orientation. + outline determines the width of the shapes's outline. + + Examples (for a Turtle instance named turtle): + >>> turtle.resizemode("user") + >>> turtle.shapesize(5, 5, 12) + >>> turtle.shapesize(outline=8) + """ + if stretch_wid is stretch_len is outline is None: + stretch_wid, stretch_len = self._stretchfactor + return stretch_wid, stretch_len, self._outlinewidth + if stretch_wid is not None: + if stretch_len is None: + stretchfactor = stretch_wid, stretch_wid + else: + stretchfactor = stretch_wid, stretch_len + elif stretch_len is not None: + stretchfactor = self._stretchfactor[0], stretch_len + else: + stretchfactor = self._stretchfactor + if outline is None: + outline = self._outlinewidth + self.pen(resizemode="user", + stretchfactor=stretchfactor, outline=outline) + + def settiltangle(self, angle): + """Rotate the turtleshape to point in the specified direction + + Optional argument: + angle -- number + + Rotate the turtleshape to point in the direction specified by angle, + regardless of its current tilt-angle. DO NOT change the turtle's + heading (direction of movement). + + + Examples (for a Turtle instance named turtle): + >>> turtle.shape("circle") + >>> turtle.shapesize(5,2) + >>> turtle.settiltangle(45) + >>> stamp() + >>> turtle.fd(50) + >>> turtle.settiltangle(-45) + >>> stamp() + >>> turtle.fd(50) + """ + tilt = -angle * self._degreesPerAU * self._angleOrient + tilt = (tilt * math.pi / 180.0) % (2*math.pi) + self.pen(resizemode="user", tilt=tilt) + + def tiltangle(self): + """Return the current tilt-angle. + + No argument. + + Return the current tilt-angle, i. e. the angle between the + orientation of the turtleshape and the heading of the turtle + (its direction of movement). + + Examples (for a Turtle instance named turtle): + >>> turtle.shape("circle") + >>> turtle.shapesize(5,2) + >>> turtle.tilt(45) + >>> turtle.tiltangle() + """ + tilt = -self._tilt * (180.0/math.pi) * self._angleOrient + return (tilt / self._degreesPerAU) % self._fullcircle + + def tilt(self, angle): + """Rotate the turtleshape by angle. + + Argument: + angle - a number + + Rotate the turtleshape by angle from its current tilt-angle, + but do NOT change the turtle's heading (direction of movement). + + Examples (for a Turtle instance named turtle): + >>> turtle.shape("circle") + >>> turtle.shapesize(5,2) + >>> turtle.tilt(30) + >>> turtle.fd(50) + >>> turtle.tilt(30) + >>> turtle.fd(50) + """ + self.settiltangle(angle + self.tiltangle()) + + def _polytrafo(self, poly): + """Computes transformed polygon shapes from a shape + according to current position and heading. + """ + screen = self.screen + p0, p1 = self._position + e0, e1 = self._orient + e = Vec2D(e0, e1 * screen.yscale / screen.xscale) + e0, e1 = (1.0 / abs(e)) * e + return [(p0+(e1*x+e0*y)/screen.xscale, p1+(-e0*x+e1*y)/screen.yscale) + for (x, y) in poly] + + def _drawturtle(self): + """Manages the correct rendering of the turtle with respect to + its shape, resizemode, stretch and tilt etc.""" + screen = self.screen + shape = screen._shapes[self.turtle.shapeIndex] + ttype = shape._type + titem = self.turtle._item + if self._shown and screen._updatecounter == 0 and screen._tracing > 0: + self._hidden_from_screen = False + tshape = shape._data + if ttype == "polygon": + if self._resizemode == "noresize": + w = 1 + shape = tshape + else: + if self._resizemode == "auto": + lx = ly = max(1, self._pensize/5.0) + w = self._pensize + tiltangle = 0 + elif self._resizemode == "user": + lx, ly = self._stretchfactor + w = self._outlinewidth + tiltangle = self._tilt + shape = [(lx*x, ly*y) for (x, y) in tshape] + t0, t1 = math.sin(tiltangle), math.cos(tiltangle) + shape = [(t1*x+t0*y, -t0*x+t1*y) for (x, y) in shape] + shape = self._polytrafo(shape) + fc, oc = self._fillcolor, self._pencolor + screen._drawpoly(titem, shape, fill=fc, outline=oc, + width=w, top=True) + elif ttype == "image": + screen._drawimage(titem, self._position, tshape) + elif ttype == "compound": + lx, ly = self._stretchfactor + w = self._outlinewidth + for item, (poly, fc, oc) in zip(titem, tshape): + poly = [(lx*x, ly*y) for (x, y) in poly] + poly = self._polytrafo(poly) + screen._drawpoly(item, poly, fill=self._cc(fc), + outline=self._cc(oc), width=w, top=True) + else: + if self._hidden_from_screen: + return + if ttype == "polygon": + screen._drawpoly(titem, ((0, 0), (0, 0), (0, 0)), "", "") + elif ttype == "image": + screen._drawimage(titem, self._position, + screen._shapes["blank"]._data) + elif ttype == "compound": + for item in titem: + screen._drawpoly(item, ((0, 0), (0, 0), (0, 0)), "", "") + self._hidden_from_screen = True + +############################## stamp stuff ############################### + + def stamp(self): + """Stamp a copy of the turtleshape onto the canvas and return its id. + + No argument. + + Stamp a copy of the turtle shape onto the canvas at the current + turtle position. Return a stamp_id for that stamp, which can be + used to delete it by calling clearstamp(stamp_id). + + Example (for a Turtle instance named turtle): + >>> turtle.color("blue") + >>> turtle.stamp() + 13 + >>> turtle.fd(50) + """ + screen = self.screen + shape = screen._shapes[self.turtle.shapeIndex] + ttype = shape._type + tshape = shape._data + if ttype == "polygon": + stitem = screen._createpoly() + if self._resizemode == "noresize": + w = 1 + shape = tshape + else: + if self._resizemode == "auto": + lx = ly = max(1, self._pensize/5.0) + w = self._pensize + tiltangle = 0 + elif self._resizemode == "user": + lx, ly = self._stretchfactor + w = self._outlinewidth + tiltangle = self._tilt + shape = [(lx*x, ly*y) for (x, y) in tshape] + t0, t1 = math.sin(tiltangle), math.cos(tiltangle) + shape = [(t1*x+t0*y, -t0*x+t1*y) for (x, y) in shape] + shape = self._polytrafo(shape) + fc, oc = self._fillcolor, self._pencolor + screen._drawpoly(stitem, shape, fill=fc, outline=oc, + width=w, top=True) + elif ttype == "image": + stitem = screen._createimage("") + screen._drawimage(stitem, self._position, tshape) + elif ttype == "compound": + stitem = [] + for element in tshape: + item = screen._createpoly() + stitem.append(item) + stitem = tuple(stitem) + lx, ly = self._stretchfactor + w = self._outlinewidth + for item, (poly, fc, oc) in zip(stitem, tshape): + poly = [(lx*x, ly*y) for (x, y) in poly] + poly = self._polytrafo(poly) + screen._drawpoly(item, poly, fill=self._cc(fc), + outline=self._cc(oc), width=w, top=True) + self.stampItems.append(stitem) + self.undobuffer.push(("stamp", stitem)) + return stitem + + def _clearstamp(self, stampid): + """does the work for clearstamp() and clearstamps() + """ + if stampid in self.stampItems: + if isinstance(stampid, tuple): + for subitem in stampid: + self.screen._delete(subitem) + else: + self.screen._delete(stampid) + self.stampItems.remove(stampid) + # Delete stampitem from undobuffer if necessary + # if clearstamp is called directly. + item = ("stamp", stampid) + buf = self.undobuffer + if item not in buf.buffer: + return + index = buf.buffer.index(item) + buf.buffer.remove(item) + if index <= buf.ptr: + buf.ptr = (buf.ptr - 1) % buf.bufsize + buf.buffer.insert((buf.ptr+1)%buf.bufsize, [None]) + + def clearstamp(self, stampid): + """Delete stamp with given stampid + + Argument: + stampid - an integer, must be return value of previous stamp() call. + + Example (for a Turtle instance named turtle): + >>> turtle.color("blue") + >>> astamp = turtle.stamp() + >>> turtle.fd(50) + >>> turtle.clearstamp(astamp) + """ + self._clearstamp(stampid) + self._update() + + def clearstamps(self, n=None): + """Delete all or first/last n of turtle's stamps. + + Optional argument: + n -- an integer + + If n is None, delete all of pen's stamps, + else if n > 0 delete first n stamps + else if n < 0 delete last n stamps. + + Example (for a Turtle instance named turtle): + >>> for i in range(8): + ... turtle.stamp(); turtle.fd(30) + ... + >>> turtle.clearstamps(2) + >>> turtle.clearstamps(-2) + >>> turtle.clearstamps() + """ + if n is None: + toDelete = self.stampItems[:] + elif n >= 0: + toDelete = self.stampItems[:n] + else: + toDelete = self.stampItems[n:] + for item in toDelete: + self._clearstamp(item) + self._update() + + def _goto(self, end): + """Move the pen to the point end, thereby drawing a line + if pen is down. All other methods for turtle movement depend + on this one. + """ + ## Version mit undo-stuff + go_modes = ( self._drawing, + self._pencolor, + self._pensize, + isinstance(self._fillpath, list)) + screen = self.screen + undo_entry = ("go", self._position, end, go_modes, + (self.currentLineItem, + self.currentLine[:], + screen._pointlist(self.currentLineItem), + self.items[:]) + ) + if self.undobuffer: + self.undobuffer.push(undo_entry) + start = self._position + if self._speed and screen._tracing == 1: + diff = (end-start) + diffsq = (diff[0]*screen.xscale)**2 + (diff[1]*screen.yscale)**2 + nhops = 1+int((diffsq**0.5)/(3*(1.1**self._speed)*self._speed)) + delta = diff * (1.0/nhops) + for n in range(1, nhops): + if n == 1: + top = True + else: + top = False + self._position = start + delta * n + if self._drawing: + screen._drawline(self.drawingLineItem, + (start, self._position), + self._pencolor, self._pensize, top) + self._update() + if self._drawing: + screen._drawline(self.drawingLineItem, ((0, 0), (0, 0)), + fill="", width=self._pensize) + # Turtle now at end, + if self._drawing: # now update currentLine + self.currentLine.append(end) + if isinstance(self._fillpath, list): + self._fillpath.append(end) + ###### vererbung!!!!!!!!!!!!!!!!!!!!!! + self._position = end + if self._creatingPoly: + self._poly.append(end) + if len(self.currentLine) > 42: # 42! answer to the ultimate question + # of life, the universe and everything + self._newLine() + self._update() #count=True) + + def _undogoto(self, entry): + """Reverse a _goto. Used for undo() + """ + old, new, go_modes, coodata = entry + drawing, pc, ps, filling = go_modes + cLI, cL, pl, items = coodata + screen = self.screen + if abs(self._position - new) > 0.5: + print "undogoto: HALLO-DA-STIMMT-WAS-NICHT!" + # restore former situation + self.currentLineItem = cLI + self.currentLine = cL + + if pl == [(0, 0), (0, 0)]: + usepc = "" + else: + usepc = pc + screen._drawline(cLI, pl, fill=usepc, width=ps) + + todelete = [i for i in self.items if (i not in items) and + (screen._type(i) == "line")] + for i in todelete: + screen._delete(i) + self.items.remove(i) + + start = old + if self._speed and screen._tracing == 1: + diff = old - new + diffsq = (diff[0]*screen.xscale)**2 + (diff[1]*screen.yscale)**2 + nhops = 1+int((diffsq**0.5)/(3*(1.1**self._speed)*self._speed)) + delta = diff * (1.0/nhops) + for n in range(1, nhops): + if n == 1: + top = True + else: + top = False + self._position = new + delta * n + if drawing: + screen._drawline(self.drawingLineItem, + (start, self._position), + pc, ps, top) + self._update() + if drawing: + screen._drawline(self.drawingLineItem, ((0, 0), (0, 0)), + fill="", width=ps) + # Turtle now at position old, + self._position = old + ## if undo is done during creating a polygon, the last vertex + ## will be deleted. if the polygon is entirely deleted, + ## creatingPoly will be set to False. + ## Polygons created before the last one will not be affected by undo() + if self._creatingPoly: + if len(self._poly) > 0: + self._poly.pop() + if self._poly == []: + self._creatingPoly = False + self._poly = None + if filling: + if self._fillpath == []: + self._fillpath = None + print "Unwahrscheinlich in _undogoto!" + elif self._fillpath is not None: + self._fillpath.pop() + self._update() #count=True) + + def _rotate(self, angle): + """Turns pen clockwise by angle. + """ + if self.undobuffer: + self.undobuffer.push(("rot", angle, self._degreesPerAU)) + angle *= self._degreesPerAU + neworient = self._orient.rotate(angle) + tracing = self.screen._tracing + if tracing == 1 and self._speed > 0: + anglevel = 3.0 * self._speed + steps = 1 + int(abs(angle)/anglevel) + delta = 1.0*angle/steps + for _ in range(steps): + self._orient = self._orient.rotate(delta) + self._update() + self._orient = neworient + self._update() + + def _newLine(self, usePos=True): + """Closes current line item and starts a new one. + Remark: if current line became too long, animation + performance (via _drawline) slowed down considerably. + """ + if len(self.currentLine) > 1: + self.screen._drawline(self.currentLineItem, self.currentLine, + self._pencolor, self._pensize) + self.currentLineItem = self.screen._createline() + self.items.append(self.currentLineItem) + else: + self.screen._drawline(self.currentLineItem, top=True) + self.currentLine = [] + if usePos: + self.currentLine = [self._position] + + def fill(self, flag=None): + """Call fill(True) before drawing a shape to fill, fill(False) when done. + + Optional argument: + flag -- True/False (or 1/0 respectively) + + Call fill(True) before drawing the shape you want to fill, + and fill(False) when done. + When used without argument: return fillstate (True if filling, + False else) + + Example (for a Turtle instance named turtle): + >>> turtle.fill(True) + >>> turtle.forward(100) + >>> turtle.left(90) + >>> turtle.forward(100) + >>> turtle.left(90) + >>> turtle.forward(100) + >>> turtle.left(90) + >>> turtle.forward(100) + >>> turtle.fill(False) + """ + filling = isinstance(self._fillpath, list) + if flag is None: + return filling + screen = self.screen + entry1 = entry2 = () + if filling: + if len(self._fillpath) > 2: + self.screen._drawpoly(self._fillitem, self._fillpath, + fill=self._fillcolor) + entry1 = ("dofill", self._fillitem) + if flag: + self._fillitem = self.screen._createpoly() + self.items.append(self._fillitem) + self._fillpath = [self._position] + entry2 = ("beginfill", self._fillitem) # , self._fillpath) + self._newLine() + else: + self._fillitem = self._fillpath = None + if self.undobuffer: + if entry1 == (): + if entry2 != (): + self.undobuffer.push(entry2) + else: + if entry2 == (): + self.undobuffer.push(entry1) + else: + self.undobuffer.push(["seq", entry1, entry2]) + self._update() + + def begin_fill(self): + """Called just before drawing a shape to be filled. + + No argument. + + Example (for a Turtle instance named turtle): + >>> turtle.begin_fill() + >>> turtle.forward(100) + >>> turtle.left(90) + >>> turtle.forward(100) + >>> turtle.left(90) + >>> turtle.forward(100) + >>> turtle.left(90) + >>> turtle.forward(100) + >>> turtle.end_fill() + """ + self.fill(True) + + def end_fill(self): + """Fill the shape drawn after the call begin_fill(). + + No argument. + + Example (for a Turtle instance named turtle): + >>> turtle.begin_fill() + >>> turtle.forward(100) + >>> turtle.left(90) + >>> turtle.forward(100) + >>> turtle.left(90) + >>> turtle.forward(100) + >>> turtle.left(90) + >>> turtle.forward(100) + >>> turtle.end_fill() + """ + self.fill(False) + + def dot(self, size=None, *color): + """Draw a dot with diameter size, using color. + + Optional arguments: + size -- an integer >= 1 (if given) + color -- a colorstring or a numeric color tuple + + Draw a circular dot with diameter size, using color. + If size is not given, the maximum of pensize+4 and 2*pensize is used. + + Example (for a Turtle instance named turtle): + >>> turtle.dot() + >>> turtle.fd(50); turtle.dot(20, "blue"); turtle.fd(50) + """ + #print "dot-1:", size, color + if not color: + if isinstance(size, (basestring, tuple)): + color = self._colorstr(size) + size = self._pensize + max(self._pensize, 4) + else: + color = self._pencolor + if not size: + size = self._pensize + max(self._pensize, 4) + else: + if size is None: + size = self._pensize + max(self._pensize, 4) + color = self._colorstr(color) + #print "dot-2:", size, color + if hasattr(self.screen, "_dot"): + item = self.screen._dot(self._position, size, color) + #print "dot:", size, color, "item:", item + self.items.append(item) + if self.undobuffer: + self.undobuffer.push(("dot", item)) + else: + pen = self.pen() + if self.undobuffer: + self.undobuffer.push(["seq"]) + self.undobuffer.cumulate = True + try: + if self.resizemode() == 'auto': + self.ht() + self.pendown() + self.pensize(size) + self.pencolor(color) + self.forward(0) + finally: + self.pen(pen) + if self.undobuffer: + self.undobuffer.cumulate = False + + def _write(self, txt, align, font): + """Performs the writing for write() + """ + item, end = self.screen._write(self._position, txt, align, font, + self._pencolor) + self.items.append(item) + if self.undobuffer: + self.undobuffer.push(("wri", item)) + return end + + def write(self, arg, move=False, align="left", font=("Arial", 8, "normal")): + """Write text at the current turtle position. + + Arguments: + arg -- info, which is to be written to the TurtleScreen + move (optional) -- True/False + align (optional) -- one of the strings "left", "center" or right" + font (optional) -- a triple (fontname, fontsize, fonttype) + + Write text - the string representation of arg - at the current + turtle position according to align ("left", "center" or right") + and with the given font. + If move is True, the pen is moved to the bottom-right corner + of the text. By default, move is False. + + Example (for a Turtle instance named turtle): + >>> turtle.write('Home = ', True, align="center") + >>> turtle.write((0,0), True) + """ + if self.undobuffer: + self.undobuffer.push(["seq"]) + self.undobuffer.cumulate = True + end = self._write(str(arg), align.lower(), font) + if move: + x, y = self.pos() + self.setpos(end, y) + if self.undobuffer: + self.undobuffer.cumulate = False + + def begin_poly(self): + """Start recording the vertices of a polygon. + + No argument. + + Start recording the vertices of a polygon. Current turtle position + is first point of polygon. + + Example (for a Turtle instance named turtle): + >>> turtle.begin_poly() + """ + self._poly = [self._position] + self._creatingPoly = True + + def end_poly(self): + """Stop recording the vertices of a polygon. + + No argument. + + Stop recording the vertices of a polygon. Current turtle position is + last point of polygon. This will be connected with the first point. + + Example (for a Turtle instance named turtle): + >>> turtle.end_poly() + """ + self._creatingPoly = False + + def get_poly(self): + """Return the lastly recorded polygon. + + No argument. + + Example (for a Turtle instance named turtle): + >>> p = turtle.get_poly() + >>> turtle.register_shape("myFavouriteShape", p) + """ + ## check if there is any poly? -- 1st solution: + if self._poly is not None: + return tuple(self._poly) + + def getscreen(self): + """Return the TurtleScreen object, the turtle is drawing on. + + No argument. + + Return the TurtleScreen object, the turtle is drawing on. + So TurtleScreen-methods can be called for that object. + + Example (for a Turtle instance named turtle): + >>> ts = turtle.getscreen() + >>> ts + + >>> ts.bgcolor("pink") + """ + return self.screen + + def getturtle(self): + """Return the Turtleobject itself. + + No argument. + + Only reasonable use: as a function to return the 'anonymous turtle': + + Example: + >>> pet = getturtle() + >>> pet.fd(50) + >>> pet + + >>> turtles() + [] + """ + return self + + getpen = getturtle + + + ################################################################ + ### screen oriented methods recurring to methods of TurtleScreen + ################################################################ + + def window_width(self): + """ Returns the width of the turtle window. + + No argument. + + Example (for a TurtleScreen instance named screen): + >>> screen.window_width() + 640 + """ + return self.screen._window_size()[0] + + def window_height(self): + """ Return the height of the turtle window. + + No argument. + + Example (for a TurtleScreen instance named screen): + >>> screen.window_height() + 480 + """ + return self.screen._window_size()[1] + + def _delay(self, delay=None): + """Set delay value which determines speed of turtle animation. + """ + return self.screen.delay(delay) + + ##### event binding methods ##### + + def onclick(self, fun, btn=1, add=None): + """Bind fun to mouse-click event on this turtle on canvas. + + Arguments: + fun -- a function with two arguments, to which will be assigned + the coordinates of the clicked point on the canvas. + num -- number of the mouse-button defaults to 1 (left mouse button). + add -- True or False. If True, new binding will be added, otherwise + it will replace a former binding. + + Example for the anonymous turtle, i. e. the procedural way: + + >>> def turn(x, y): + ... left(360) + ... + >>> onclick(turn) # Now clicking into the turtle will turn it. + >>> onclick(None) # event-binding will be removed + """ + self.screen._onclick(self.turtle._item, fun, btn, add) + self._update() + + def onrelease(self, fun, btn=1, add=None): + """Bind fun to mouse-button-release event on this turtle on canvas. + + Arguments: + fun -- a function with two arguments, to which will be assigned + the coordinates of the clicked point on the canvas. + num -- number of the mouse-button defaults to 1 (left mouse button). + + Example (for a MyTurtle instance named joe): + >>> class MyTurtle(Turtle): + ... def glow(self,x,y): + ... self.fillcolor("red") + ... def unglow(self,x,y): + ... self.fillcolor("") + ... + >>> joe = MyTurtle() + >>> joe.onclick(joe.glow) + >>> joe.onrelease(joe.unglow) + + Clicking on joe turns fillcolor red, unclicking turns it to + transparent. + """ + self.screen._onrelease(self.turtle._item, fun, btn, add) + self._update() + + def ondrag(self, fun, btn=1, add=None): + """Bind fun to mouse-move event on this turtle on canvas. + + Arguments: + fun -- a function with two arguments, to which will be assigned + the coordinates of the clicked point on the canvas. + num -- number of the mouse-button defaults to 1 (left mouse button). + + Every sequence of mouse-move-events on a turtle is preceded by a + mouse-click event on that turtle. + + Example (for a Turtle instance named turtle): + >>> turtle.ondrag(turtle.goto) + + Subsequently clicking and dragging a Turtle will move it + across the screen thereby producing handdrawings (if pen is + down). + """ + self.screen._ondrag(self.turtle._item, fun, btn, add) + + + def _undo(self, action, data): + """Does the main part of the work for undo() + """ + if self.undobuffer is None: + return + if action == "rot": + angle, degPAU = data + self._rotate(-angle*degPAU/self._degreesPerAU) + dummy = self.undobuffer.pop() + elif action == "stamp": + stitem = data[0] + self.clearstamp(stitem) + elif action == "go": + self._undogoto(data) + elif action in ["wri", "dot"]: + item = data[0] + self.screen._delete(item) + self.items.remove(item) + elif action == "dofill": + item = data[0] + self.screen._drawpoly(item, ((0, 0),(0, 0),(0, 0)), + fill="", outline="") + elif action == "beginfill": + item = data[0] + self._fillitem = self._fillpath = None + self.screen._delete(item) + self.items.remove(item) + elif action == "pen": + TPen.pen(self, data[0]) + self.undobuffer.pop() + + def undo(self): + """undo (repeatedly) the last turtle action. + + No argument. + + undo (repeatedly) the last turtle action. + Number of available undo actions is determined by the size of + the undobuffer. + + Example (for a Turtle instance named turtle): + >>> for i in range(4): + ... turtle.fd(50); turtle.lt(80) + ... + >>> for i in range(8): + ... turtle.undo() + ... + """ + if self.undobuffer is None: + return + item = self.undobuffer.pop() + action = item[0] + data = item[1:] + if action == "seq": + while data: + item = data.pop() + self._undo(item[0], item[1:]) + else: + self._undo(action, data) + + turtlesize = shapesize + +RawPen = RawTurtle + +### Screen - Singleton ######################## + +def Screen(): + """Return the singleton screen object. + If none exists at the moment, create a new one and return it, + else return the existing one.""" + if Turtle._screen is None: + Turtle._screen = _Screen() + return Turtle._screen + +class _Screen(TurtleScreen): + + _root = None + _canvas = None + _title = _CFG["title"] + + def __init__(self): + # XXX there is no need for this code to be conditional, + # as there will be only a single _Screen instance, anyway + # XXX actually, the turtle demo is injecting root window, + # so perhaps the conditional creation of a root should be + # preserved (perhaps by passing it as an optional parameter) + if _Screen._root is None: + _Screen._root = self._root = _Root() + self._root.title(_Screen._title) + self._root.ondestroy(self._destroy) + if _Screen._canvas is None: + width = _CFG["width"] + height = _CFG["height"] + canvwidth = _CFG["canvwidth"] + canvheight = _CFG["canvheight"] + leftright = _CFG["leftright"] + topbottom = _CFG["topbottom"] + self._root.setupcanvas(width, height, canvwidth, canvheight) + _Screen._canvas = self._root._getcanvas() + TurtleScreen.__init__(self, _Screen._canvas) + self.setup(width, height, leftright, topbottom) + + def setup(self, width=_CFG["width"], height=_CFG["height"], + startx=_CFG["leftright"], starty=_CFG["topbottom"]): + """ Set the size and position of the main window. + + Arguments: + width: as integer a size in pixels, as float a fraction of the screen. + Default is 50% of screen. + height: as integer the height in pixels, as float a fraction of the + screen. Default is 75% of screen. + startx: if positive, starting position in pixels from the left + edge of the screen, if negative from the right edge + Default, startx=None is to center window horizontally. + starty: if positive, starting position in pixels from the top + edge of the screen, if negative from the bottom edge + Default, starty=None is to center window vertically. + + Examples (for a Screen instance named screen): + >>> screen.setup (width=200, height=200, startx=0, starty=0) + + sets window to 200x200 pixels, in upper left of screen + + >>> screen.setup(width=.75, height=0.5, startx=None, starty=None) + + sets window to 75% of screen by 50% of screen and centers + """ + if not hasattr(self._root, "set_geometry"): + return + sw = self._root.win_width() + sh = self._root.win_height() + if isinstance(width, float) and 0 <= width <= 1: + width = sw*width + if startx is None: + startx = (sw - width) / 2 + if isinstance(height, float) and 0 <= height <= 1: + height = sh*height + if starty is None: + starty = (sh - height) / 2 + self._root.set_geometry(width, height, startx, starty) + self.update() + + def title(self, titlestring): + """Set title of turtle-window + + Argument: + titlestring -- a string, to appear in the titlebar of the + turtle graphics window. + + This is a method of Screen-class. Not available for TurtleScreen- + objects. + + Example (for a Screen instance named screen): + >>> screen.title("Welcome to the turtle-zoo!") + """ + if _Screen._root is not None: + _Screen._root.title(titlestring) + _Screen._title = titlestring + + def _destroy(self): + root = self._root + if root is _Screen._root: + Turtle._pen = None + Turtle._screen = None + _Screen._root = None + _Screen._canvas = None + TurtleScreen._RUNNING = True + root.destroy() + + def bye(self): + """Shut the turtlegraphics window. + + Example (for a TurtleScreen instance named screen): + >>> screen.bye() + """ + self._destroy() + + def exitonclick(self): + """Go into mainloop until the mouse is clicked. + + No arguments. + + Bind bye() method to mouseclick on TurtleScreen. + If "using_IDLE" - value in configuration dictionary is False + (default value), enter mainloop. + If IDLE with -n switch (no subprocess) is used, this value should be + set to True in turtle.cfg. In this case IDLE's mainloop + is active also for the client script. + + This is a method of the Screen-class and not available for + TurtleScreen instances. + + Example (for a Screen instance named screen): + >>> screen.exitonclick() + + """ + def exitGracefully(x, y): + """Screen.bye() with two dummy-parameters""" + self.bye() + self.onclick(exitGracefully) + if _CFG["using_IDLE"]: + return + try: + mainloop() + except AttributeError: + exit(0) + + +class Turtle(RawTurtle): + """RawTurtle auto-creating (scrolled) canvas. + + When a Turtle object is created or a function derived from some + Turtle method is called a TurtleScreen object is automatically created. + """ + _pen = None + _screen = None + + def __init__(self, + shape=_CFG["shape"], + undobuffersize=_CFG["undobuffersize"], + visible=_CFG["visible"]): + if Turtle._screen is None: + Turtle._screen = Screen() + RawTurtle.__init__(self, Turtle._screen, + shape=shape, + undobuffersize=undobuffersize, + visible=visible) + +Pen = Turtle + +def _getpen(): + """Create the 'anonymous' turtle if not already present.""" + if Turtle._pen is None: + Turtle._pen = Turtle() + return Turtle._pen + +def _getscreen(): + """Create a TurtleScreen if not already present.""" + if Turtle._screen is None: + Turtle._screen = Screen() + return Turtle._screen + +def write_docstringdict(filename="turtle_docstringdict"): + """Create and write docstring-dictionary to file. + + Optional argument: + filename -- a string, used as filename + default value is turtle_docstringdict + + Has to be called explicitly, (not used by the turtle-graphics classes) + The docstring dictionary will be written to the Python script .py + It is intended to serve as a template for translation of the docstrings + into different languages. + """ + docsdict = {} + + for methodname in _tg_screen_functions: + key = "_Screen."+methodname + docsdict[key] = eval(key).__doc__ + for methodname in _tg_turtle_functions: + key = "Turtle."+methodname + docsdict[key] = eval(key).__doc__ + + f = open("%s.py" % filename,"w") + keys = sorted([x for x in docsdict.keys() + if x.split('.')[1] not in _alias_list]) + f.write('docsdict = {\n\n') + for key in keys[:-1]: + f.write('%s :\n' % repr(key)) + f.write(' """%s\n""",\n\n' % docsdict[key]) + key = keys[-1] + f.write('%s :\n' % repr(key)) + f.write(' """%s\n"""\n\n' % docsdict[key]) + f.write("}\n") + f.close() + +def read_docstrings(lang): + """Read in docstrings from lang-specific docstring dictionary. + + Transfer docstrings, translated to lang, from a dictionary-file + to the methods of classes Screen and Turtle and - in revised form - + to the corresponding functions. + """ + modname = "turtle_docstringdict_%(language)s" % {'language':lang.lower()} + module = __import__(modname) + docsdict = module.docsdict + for key in docsdict: + #print key + try: + eval(key).im_func.__doc__ = docsdict[key] + except: + print "Bad docstring-entry: %s" % key + +_LANGUAGE = _CFG["language"] + +try: + if _LANGUAGE != "english": + read_docstrings(_LANGUAGE) +except ImportError: + print "Cannot find docsdict for", _LANGUAGE +except: + print ("Unknown Error when trying to import %s-docstring-dictionary" % + _LANGUAGE) + + +def getmethparlist(ob): + "Get strings describing the arguments for the given object" + argText1 = argText2 = "" + # bit of a hack for methods - turn it into a function + # but we drop the "self" param. + if type(ob)==types.MethodType: + fob = ob.im_func + argOffset = 1 + else: + fob = ob + argOffset = 0 + # Try and build one for Python defined functions + if type(fob) in [types.FunctionType, types.LambdaType]: + try: + counter = fob.func_code.co_argcount + items2 = list(fob.func_code.co_varnames[argOffset:counter]) + realArgs = fob.func_code.co_varnames[argOffset:counter] + defaults = fob.func_defaults or [] + defaults = list(map(lambda name: "=%s" % repr(name), defaults)) + defaults = [""] * (len(realArgs)-len(defaults)) + defaults + items1 = map(lambda arg, dflt: arg+dflt, realArgs, defaults) + if fob.func_code.co_flags & 0x4: + items1.append("*"+fob.func_code.co_varnames[counter]) + items2.append("*"+fob.func_code.co_varnames[counter]) + counter += 1 + if fob.func_code.co_flags & 0x8: + items1.append("**"+fob.func_code.co_varnames[counter]) + items2.append("**"+fob.func_code.co_varnames[counter]) + argText1 = ", ".join(items1) + argText1 = "(%s)" % argText1 + argText2 = ", ".join(items2) + argText2 = "(%s)" % argText2 + except: + pass + return argText1, argText2 + +def _turtle_docrevise(docstr): + """To reduce docstrings from RawTurtle class for functions + """ + import re + if docstr is None: + return None + turtlename = _CFG["exampleturtle"] + newdocstr = docstr.replace("%s." % turtlename,"") + parexp = re.compile(r' \(.+ %s\):' % turtlename) + newdocstr = parexp.sub(":", newdocstr) + return newdocstr + +def _screen_docrevise(docstr): + """To reduce docstrings from TurtleScreen class for functions + """ + import re + if docstr is None: + return None + screenname = _CFG["examplescreen"] + newdocstr = docstr.replace("%s." % screenname,"") + parexp = re.compile(r' \(.+ %s\):' % screenname) + newdocstr = parexp.sub(":", newdocstr) + return newdocstr + +## The following mechanism makes all methods of RawTurtle and Turtle available +## as functions. So we can enhance, change, add, delete methods to these +## classes and do not need to change anything here. + + +for methodname in _tg_screen_functions: + pl1, pl2 = getmethparlist(eval('_Screen.' + methodname)) + if pl1 == "": + print ">>>>>>", pl1, pl2 + continue + defstr = ("def %(key)s%(pl1)s: return _getscreen().%(key)s%(pl2)s" % + {'key':methodname, 'pl1':pl1, 'pl2':pl2}) + exec defstr + eval(methodname).__doc__ = _screen_docrevise(eval('_Screen.'+methodname).__doc__) + +for methodname in _tg_turtle_functions: + pl1, pl2 = getmethparlist(eval('Turtle.' + methodname)) + if pl1 == "": + print ">>>>>>", pl1, pl2 + continue + defstr = ("def %(key)s%(pl1)s: return _getpen().%(key)s%(pl2)s" % + {'key':methodname, 'pl1':pl1, 'pl2':pl2}) + exec defstr + eval(methodname).__doc__ = _turtle_docrevise(eval('Turtle.'+methodname).__doc__) + + +done = mainloop = TK.mainloop +del pl1, pl2, defstr + +if __name__ == "__main__": + def switchpen(): + if isdown(): + pu() + else: + pd() + + def demo1(): + """Demo of old turtle.py - module""" + reset() + tracer(True) + up() + backward(100) + down() + # draw 3 squares; the last filled + width(3) + for i in range(3): + if i == 2: + fill(1) + for _ in range(4): + forward(20) + left(90) + if i == 2: + color("maroon") + fill(0) + up() + forward(30) + down() + width(1) + color("black") + # move out of the way + tracer(False) + up() + right(90) + forward(100) + right(90) + forward(100) + right(180) + down() + # some text + write("startstart", 1) + write(u"start", 1) + color("red") + # staircase + for i in range(5): + forward(20) + left(90) + forward(20) + right(90) + # filled staircase + tracer(True) + fill(1) + for i in range(5): + forward(20) + left(90) + forward(20) + right(90) + fill(0) + # more text + + def demo2(): + """Demo of some new features.""" + speed(1) + st() + pensize(3) + setheading(towards(0, 0)) + radius = distance(0, 0)/2.0 + rt(90) + for _ in range(18): + switchpen() + circle(radius, 10) + write("wait a moment...") + while undobufferentries(): + undo() + reset() + lt(90) + colormode(255) + laenge = 10 + pencolor("green") + pensize(3) + lt(180) + for i in range(-2, 16): + if i > 0: + begin_fill() + fillcolor(255-15*i, 0, 15*i) + for _ in range(3): + fd(laenge) + lt(120) + laenge += 10 + lt(15) + speed((speed()+1)%12) + end_fill() + + lt(120) + pu() + fd(70) + rt(30) + pd() + color("red","yellow") + speed(0) + fill(1) + for _ in range(4): + circle(50, 90) + rt(90) + fd(30) + rt(90) + fill(0) + lt(90) + pu() + fd(30) + pd() + shape("turtle") + + tri = getturtle() + tri.resizemode("auto") + turtle = Turtle() + turtle.resizemode(u"auto") + turtle.shape("turtle") + turtle.reset() + turtle.left(90) + turtle.speed(0) + turtle.up() + turtle.goto(280, 40) + turtle.lt(30) + turtle.down() + turtle.speed(6) + turtle.color("blue",u"orange") + turtle.pensize(2) + tri.speed(6) + setheading(towards(turtle)) + count = 1 + while tri.distance(turtle) > 4: + turtle.fd(3.5) + turtle.lt(0.6) + tri.setheading(tri.towards(turtle)) + tri.fd(4) + if count % 20 == 0: + turtle.stamp() + tri.stamp() + switchpen() + count += 1 + tri.write("CAUGHT! ", font=("Arial", 16, "bold"), align=u"right") + tri.pencolor("black") + tri.pencolor(u"red") + + def baba(xdummy, ydummy): + clearscreen() + bye() + + time.sleep(2) + + while undobufferentries(): + tri.undo() + turtle.undo() + tri.fd(50) + tri.write(" Click me!", font = ("Courier", 12, "bold") ) + tri.onclick(baba, 1) + + demo1() + demo2() + exitonclick() diff --git a/PythonHome/Lib/lib-tk/turtle.pyc b/PythonHome/Lib/lib-tk/turtle.pyc deleted file mode 100644 index ae500be82ba5ad3d37949e229e98e6bf0d6ab714..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 135965 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 Sr|Y&e4{tZ(N#Z%jMf3%sbt;zt diff --git a/PythonHome/Lib/lib2to3/btm_matcher.py b/PythonHome/Lib/lib2to3/btm_matcher.py new file mode 100644 index 0000000000..736ba2b9d8 --- /dev/null +++ b/PythonHome/Lib/lib2to3/btm_matcher.py @@ -0,0 +1,168 @@ +"""A bottom-up tree matching algorithm implementation meant to speed +up 2to3's matching process. After the tree patterns are reduced to +their rarest linear path, a linear Aho-Corasick automaton is +created. The linear automaton traverses the linear paths from the +leaves to the root of the AST and returns a set of nodes for further +matching. This reduces significantly the number of candidate nodes.""" + +__author__ = "George Boutsioukis " + +import logging +import itertools +from collections import defaultdict + +from . import pytree +from .btm_utils import reduce_tree + +class BMNode(object): + """Class for a node of the Aho-Corasick automaton used in matching""" + count = itertools.count() + def __init__(self): + self.transition_table = {} + self.fixers = [] + self.id = next(BMNode.count) + self.content = '' + +class BottomMatcher(object): + """The main matcher class. After instantiating the patterns should + be added using the add_fixer method""" + + def __init__(self): + self.match = set() + self.root = BMNode() + self.nodes = [self.root] + self.fixers = [] + self.logger = logging.getLogger("RefactoringTool") + + def add_fixer(self, fixer): + """Reduces a fixer's pattern tree to a linear path and adds it + to the matcher(a common Aho-Corasick automaton). The fixer is + appended on the matching states and called when they are + reached""" + self.fixers.append(fixer) + tree = reduce_tree(fixer.pattern_tree) + linear = tree.get_linear_subpattern() + match_nodes = self.add(linear, start=self.root) + for match_node in match_nodes: + match_node.fixers.append(fixer) + + def add(self, pattern, start): + "Recursively adds a linear pattern to the AC automaton" + #print("adding pattern", pattern, "to", start) + if not pattern: + #print("empty pattern") + return [start] + if isinstance(pattern[0], tuple): + #alternatives + #print("alternatives") + match_nodes = [] + for alternative in pattern[0]: + #add all alternatives, and add the rest of the pattern + #to each end node + end_nodes = self.add(alternative, start=start) + for end in end_nodes: + match_nodes.extend(self.add(pattern[1:], end)) + return match_nodes + else: + #single token + #not last + if pattern[0] not in start.transition_table: + #transition did not exist, create new + next_node = BMNode() + start.transition_table[pattern[0]] = next_node + else: + #transition exists already, follow + next_node = start.transition_table[pattern[0]] + + if pattern[1:]: + end_nodes = self.add(pattern[1:], start=next_node) + else: + end_nodes = [next_node] + return end_nodes + + def run(self, leaves): + """The main interface with the bottom matcher. The tree is + traversed from the bottom using the constructed + automaton. Nodes are only checked once as the tree is + retraversed. When the automaton fails, we give it one more + shot(in case the above tree matches as a whole with the + rejected leaf), then we break for the next leaf. There is the + special case of multiple arguments(see code comments) where we + recheck the nodes + + Args: + The leaves of the AST tree to be matched + + Returns: + A dictionary of node matches with fixers as the keys + """ + current_ac_node = self.root + results = defaultdict(list) + for leaf in leaves: + current_ast_node = leaf + while current_ast_node: + current_ast_node.was_checked = True + for child in current_ast_node.children: + # multiple statements, recheck + if isinstance(child, pytree.Leaf) and child.value == u";": + current_ast_node.was_checked = False + break + if current_ast_node.type == 1: + #name + node_token = current_ast_node.value + else: + node_token = current_ast_node.type + + if node_token in current_ac_node.transition_table: + #token matches + current_ac_node = current_ac_node.transition_table[node_token] + for fixer in current_ac_node.fixers: + if not fixer in results: + results[fixer] = [] + results[fixer].append(current_ast_node) + + else: + #matching failed, reset automaton + current_ac_node = self.root + if (current_ast_node.parent is not None + and current_ast_node.parent.was_checked): + #the rest of the tree upwards has been checked, next leaf + break + + #recheck the rejected node once from the root + if node_token in current_ac_node.transition_table: + #token matches + current_ac_node = current_ac_node.transition_table[node_token] + for fixer in current_ac_node.fixers: + if not fixer in results.keys(): + results[fixer] = [] + results[fixer].append(current_ast_node) + + current_ast_node = current_ast_node.parent + return results + + def print_ac(self): + "Prints a graphviz diagram of the BM automaton(for debugging)" + print("digraph g{") + def print_node(node): + for subnode_key in node.transition_table.keys(): + subnode = node.transition_table[subnode_key] + print("%d -> %d [label=%s] //%s" % + (node.id, subnode.id, type_repr(subnode_key), str(subnode.fixers))) + if subnode_key == 1: + print(subnode.content) + print_node(subnode) + print_node(self.root) + print("}") + +# taken from pytree.py for debugging; only used by print_ac +_type_reprs = {} +def type_repr(type_num): + global _type_reprs + if not _type_reprs: + from .pygram import python_symbols + # printing tokens is possible but not as useful + # from .pgen2 import token // token.__dict__.items(): + for name, val in python_symbols.__dict__.items(): + if type(val) == int: _type_reprs[val] = name + return _type_reprs.setdefault(type_num, type_num) diff --git a/PythonHome/Lib/lib2to3/btm_matcher.pyc b/PythonHome/Lib/lib2to3/btm_matcher.pyc deleted file mode 100644 index 9e2b89b487a137fdbbba1c9d5583ec51dc745fe4..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5665 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 J=YQ7q{tM>`2$BE* diff --git a/PythonHome/Lib/lib2to3/btm_utils.py b/PythonHome/Lib/lib2to3/btm_utils.py new file mode 100644 index 0000000000..2276dc9e96 --- /dev/null +++ b/PythonHome/Lib/lib2to3/btm_utils.py @@ -0,0 +1,283 @@ +"Utility functions used by the btm_matcher module" + +from . import pytree +from .pgen2 import grammar, token +from .pygram import pattern_symbols, python_symbols + +syms = pattern_symbols +pysyms = python_symbols +tokens = grammar.opmap +token_labels = token + +TYPE_ANY = -1 +TYPE_ALTERNATIVES = -2 +TYPE_GROUP = -3 + +class MinNode(object): + """This class serves as an intermediate representation of the + pattern tree during the conversion to sets of leaf-to-root + subpatterns""" + + def __init__(self, type=None, name=None): + self.type = type + self.name = name + self.children = [] + self.leaf = False + self.parent = None + self.alternatives = [] + self.group = [] + + def __repr__(self): + return str(self.type) + ' ' + str(self.name) + + def leaf_to_root(self): + """Internal method. Returns a characteristic path of the + pattern tree. This method must be run for all leaves until the + linear subpatterns are merged into a single""" + node = self + subp = [] + while node: + if node.type == TYPE_ALTERNATIVES: + node.alternatives.append(subp) + if len(node.alternatives) == len(node.children): + #last alternative + subp = [tuple(node.alternatives)] + node.alternatives = [] + node = node.parent + continue + else: + node = node.parent + subp = None + break + + if node.type == TYPE_GROUP: + node.group.append(subp) + #probably should check the number of leaves + if len(node.group) == len(node.children): + subp = get_characteristic_subpattern(node.group) + node.group = [] + node = node.parent + continue + else: + node = node.parent + subp = None + break + + if node.type == token_labels.NAME and node.name: + #in case of type=name, use the name instead + subp.append(node.name) + else: + subp.append(node.type) + + node = node.parent + return subp + + def get_linear_subpattern(self): + """Drives the leaf_to_root method. The reason that + leaf_to_root must be run multiple times is because we need to + reject 'group' matches; for example the alternative form + (a | b c) creates a group [b c] that needs to be matched. Since + matching multiple linear patterns overcomes the automaton's + capabilities, leaf_to_root merges each group into a single + choice based on 'characteristic'ity, + + i.e. (a|b c) -> (a|b) if b more characteristic than c + + Returns: The most 'characteristic'(as defined by + get_characteristic_subpattern) path for the compiled pattern + tree. + """ + + for l in self.leaves(): + subp = l.leaf_to_root() + if subp: + return subp + + def leaves(self): + "Generator that returns the leaves of the tree" + for child in self.children: + for x in child.leaves(): + yield x + if not self.children: + yield self + +def reduce_tree(node, parent=None): + """ + Internal function. Reduces a compiled pattern tree to an + intermediate representation suitable for feeding the + automaton. This also trims off any optional pattern elements(like + [a], a*). + """ + + new_node = None + #switch on the node type + if node.type == syms.Matcher: + #skip + node = node.children[0] + + if node.type == syms.Alternatives : + #2 cases + if len(node.children) <= 2: + #just a single 'Alternative', skip this node + new_node = reduce_tree(node.children[0], parent) + else: + #real alternatives + new_node = MinNode(type=TYPE_ALTERNATIVES) + #skip odd children('|' tokens) + for child in node.children: + if node.children.index(child)%2: + continue + reduced = reduce_tree(child, new_node) + if reduced is not None: + new_node.children.append(reduced) + elif node.type == syms.Alternative: + if len(node.children) > 1: + + new_node = MinNode(type=TYPE_GROUP) + for child in node.children: + reduced = reduce_tree(child, new_node) + if reduced: + new_node.children.append(reduced) + if not new_node.children: + # delete the group if all of the children were reduced to None + new_node = None + + else: + new_node = reduce_tree(node.children[0], parent) + + elif node.type == syms.Unit: + if (isinstance(node.children[0], pytree.Leaf) and + node.children[0].value == '('): + #skip parentheses + return reduce_tree(node.children[1], parent) + if ((isinstance(node.children[0], pytree.Leaf) and + node.children[0].value == '[') + or + (len(node.children)>1 and + hasattr(node.children[1], "value") and + node.children[1].value == '[')): + #skip whole unit if its optional + return None + + leaf = True + details_node = None + alternatives_node = None + has_repeater = False + repeater_node = None + has_variable_name = False + + for child in node.children: + if child.type == syms.Details: + leaf = False + details_node = child + elif child.type == syms.Repeater: + has_repeater = True + repeater_node = child + elif child.type == syms.Alternatives: + alternatives_node = child + if hasattr(child, 'value') and child.value == '=': # variable name + has_variable_name = True + + #skip variable name + if has_variable_name: + #skip variable name, '=' + name_leaf = node.children[2] + if hasattr(name_leaf, 'value') and name_leaf.value == '(': + # skip parenthesis + name_leaf = node.children[3] + else: + name_leaf = node.children[0] + + #set node type + if name_leaf.type == token_labels.NAME: + #(python) non-name or wildcard + if name_leaf.value == 'any': + new_node = MinNode(type=TYPE_ANY) + else: + if hasattr(token_labels, name_leaf.value): + new_node = MinNode(type=getattr(token_labels, name_leaf.value)) + else: + new_node = MinNode(type=getattr(pysyms, name_leaf.value)) + + elif name_leaf.type == token_labels.STRING: + #(python) name or character; remove the apostrophes from + #the string value + name = name_leaf.value.strip("'") + if name in tokens: + new_node = MinNode(type=tokens[name]) + else: + new_node = MinNode(type=token_labels.NAME, name=name) + elif name_leaf.type == syms.Alternatives: + new_node = reduce_tree(alternatives_node, parent) + + #handle repeaters + if has_repeater: + if repeater_node.children[0].value == '*': + #reduce to None + new_node = None + elif repeater_node.children[0].value == '+': + #reduce to a single occurence i.e. do nothing + pass + else: + #TODO: handle {min, max} repeaters + raise NotImplementedError + pass + + #add children + if details_node and new_node is not None: + for child in details_node.children[1:-1]: + #skip '<', '>' markers + reduced = reduce_tree(child, new_node) + if reduced is not None: + new_node.children.append(reduced) + if new_node: + new_node.parent = parent + return new_node + + +def get_characteristic_subpattern(subpatterns): + """Picks the most characteristic from a list of linear patterns + Current order used is: + names > common_names > common_chars + """ + if not isinstance(subpatterns, list): + return subpatterns + if len(subpatterns)==1: + return subpatterns[0] + + # first pick out the ones containing variable names + subpatterns_with_names = [] + subpatterns_with_common_names = [] + common_names = ['in', 'for', 'if' , 'not', 'None'] + subpatterns_with_common_chars = [] + common_chars = "[]().,:" + for subpattern in subpatterns: + if any(rec_test(subpattern, lambda x: type(x) is str)): + if any(rec_test(subpattern, + lambda x: isinstance(x, str) and x in common_chars)): + subpatterns_with_common_chars.append(subpattern) + elif any(rec_test(subpattern, + lambda x: isinstance(x, str) and x in common_names)): + subpatterns_with_common_names.append(subpattern) + + else: + subpatterns_with_names.append(subpattern) + + if subpatterns_with_names: + subpatterns = subpatterns_with_names + elif subpatterns_with_common_names: + subpatterns = subpatterns_with_common_names + elif subpatterns_with_common_chars: + subpatterns = subpatterns_with_common_chars + # of the remaining subpatterns pick out the longest one + return max(subpatterns, key=len) + +def rec_test(sequence, test_func): + """Tests test_func on all items of sequence and items of included + sub-iterables""" + for x in sequence: + if isinstance(x, (list, tuple)): + for y in rec_test(x, test_func): + yield y + else: + yield test_func(x) diff --git a/PythonHome/Lib/lib2to3/btm_utils.pyc b/PythonHome/Lib/lib2to3/btm_utils.pyc deleted file mode 100644 index 91347a105170a67e52918c9119300f486ffce226..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 7368 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 diff --git a/PythonHome/Lib/lib2to3/fixer_base.py b/PythonHome/Lib/lib2to3/fixer_base.py new file mode 100644 index 0000000000..f6421ba3f7 --- /dev/null +++ b/PythonHome/Lib/lib2to3/fixer_base.py @@ -0,0 +1,189 @@ +# Copyright 2006 Google, Inc. All Rights Reserved. +# Licensed to PSF under a Contributor Agreement. + +"""Base class for fixers (optional, but recommended).""" + +# Python imports +import logging +import itertools + +# Local imports +from .patcomp import PatternCompiler +from . import pygram +from .fixer_util import does_tree_import + +class BaseFix(object): + + """Optional base class for fixers. + + The subclass name must be FixFooBar where FooBar is the result of + removing underscores and capitalizing the words of the fix name. + For example, the class name for a fixer named 'has_key' should be + FixHasKey. + """ + + PATTERN = None # Most subclasses should override with a string literal + pattern = None # Compiled pattern, set by compile_pattern() + pattern_tree = None # Tree representation of the pattern + options = None # Options object passed to initializer + filename = None # The filename (set by set_filename) + logger = None # A logger (set by set_filename) + numbers = itertools.count(1) # For new_name() + used_names = set() # A set of all used NAMEs + order = "post" # Does the fixer prefer pre- or post-order traversal + explicit = False # Is this ignored by refactor.py -f all? + run_order = 5 # Fixers will be sorted by run order before execution + # Lower numbers will be run first. + _accept_type = None # [Advanced and not public] This tells RefactoringTool + # which node type to accept when there's not a pattern. + + keep_line_order = False # For the bottom matcher: match with the + # original line order + BM_compatible = False # Compatibility with the bottom matching + # module; every fixer should set this + # manually + + # Shortcut for access to Python grammar symbols + syms = pygram.python_symbols + + def __init__(self, options, log): + """Initializer. Subclass may override. + + Args: + options: an dict containing the options passed to RefactoringTool + that could be used to customize the fixer through the command line. + log: a list to append warnings and other messages to. + """ + self.options = options + self.log = log + self.compile_pattern() + + def compile_pattern(self): + """Compiles self.PATTERN into self.pattern. + + Subclass may override if it doesn't want to use + self.{pattern,PATTERN} in .match(). + """ + if self.PATTERN is not None: + PC = PatternCompiler() + self.pattern, self.pattern_tree = PC.compile_pattern(self.PATTERN, + with_tree=True) + + def set_filename(self, filename): + """Set the filename, and a logger derived from it. + + The main refactoring tool should call this. + """ + self.filename = filename + self.logger = logging.getLogger(filename) + + def match(self, node): + """Returns match for a given parse tree node. + + Should return a true or false object (not necessarily a bool). + It may return a non-empty dict of matching sub-nodes as + returned by a matching pattern. + + Subclass may override. + """ + results = {"node": node} + return self.pattern.match(node, results) and results + + def transform(self, node, results): + """Returns the transformation for a given parse tree node. + + Args: + node: the root of the parse tree that matched the fixer. + results: a dict mapping symbolic names to part of the match. + + Returns: + None, or a node that is a modified copy of the + argument node. The node argument may also be modified in-place to + effect the same change. + + Subclass *must* override. + """ + raise NotImplementedError() + + def new_name(self, template=u"xxx_todo_changeme"): + """Return a string suitable for use as an identifier + + The new name is guaranteed not to conflict with other identifiers. + """ + name = template + while name in self.used_names: + name = template + unicode(self.numbers.next()) + self.used_names.add(name) + return name + + def log_message(self, message): + if self.first_log: + self.first_log = False + self.log.append("### In file %s ###" % self.filename) + self.log.append(message) + + def cannot_convert(self, node, reason=None): + """Warn the user that a given chunk of code is not valid Python 3, + but that it cannot be converted automatically. + + First argument is the top-level node for the code in question. + Optional second argument is why it can't be converted. + """ + lineno = node.get_lineno() + for_output = node.clone() + for_output.prefix = u"" + msg = "Line %d: could not convert: %s" + self.log_message(msg % (lineno, for_output)) + if reason: + self.log_message(reason) + + def warning(self, node, reason): + """Used for warning the user about possible uncertainty in the + translation. + + First argument is the top-level node for the code in question. + Optional second argument is why it can't be converted. + """ + lineno = node.get_lineno() + self.log_message("Line %d: %s" % (lineno, reason)) + + def start_tree(self, tree, filename): + """Some fixers need to maintain tree-wide state. + This method is called once, at the start of tree fix-up. + + tree - the root node of the tree to be processed. + filename - the name of the file the tree came from. + """ + self.used_names = tree.used_names + self.set_filename(filename) + self.numbers = itertools.count(1) + self.first_log = True + + def finish_tree(self, tree, filename): + """Some fixers need to maintain tree-wide state. + This method is called once, at the conclusion of tree fix-up. + + tree - the root node of the tree to be processed. + filename - the name of the file the tree came from. + """ + pass + + +class ConditionalFix(BaseFix): + """ Base class for fixers which not execute if an import is found. """ + + # This is the name of the import which, if found, will cause the test to be skipped + skip_on = None + + def start_tree(self, *args): + super(ConditionalFix, self).start_tree(*args) + self._should_skip = None + + def should_skip(self, node): + if self._should_skip is not None: + return self._should_skip + pkg = self.skip_on.split(".") + name = pkg[-1] + pkg = ".".join(pkg[:-1]) + self._should_skip = does_tree_import(pkg, name, node) + return self._should_skip diff --git a/PythonHome/Lib/lib2to3/fixer_base.pyc b/PythonHome/Lib/lib2to3/fixer_base.pyc deleted file mode 100644 index e427cfca66ae5f311203fd76bee3c1515e3acd78..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 7017 zcmd5>TXP&o8SUAXR$5uU<01F%LM!6VJTy!ZS}ir1&}f0$%b1;GC~#XE%_lNDowHUDN96p1ysT^PR8V{o>-< zKR*7=ZlaoB7k}TyV}Fk#RceSbP-#cyff}OX>m4=hsI;rnC6#y8WJwK|RKWLTl`pGF zPYrwiy{GaOHCa`|RlKh#(^n(Ru&O>&>XA~v9}>e^{A}$C_6Eg)q`^Cva*Qt4ZUAGU74huOiYoQ^tG+*-}voh0R|6PxXUQ+#mb`jF%B8H$~iXI0vh%5w^`X3O)9tcTYr=M)mgaxbX#g7m(~$1C15@GMzhqWBjH!&RbEnIZ%u<<2`5-ICx`t9Ko0RC*agpjIo@Or2v){6l z> zmh9w%*nVhE{iI@8ZV57(meys2tzdPX9 z_Ib$lZjrf+XEN26*1I#|P2y8sJ}_04r8to6g#v!B8rxg#8(X|H*jo^gPP4@6q%2&V z6*Cbv{dx*7GO2c@4$UY|Tv_3Zy|T=|G@Cn!IfIvguA31Flvqx%#hIKf^ZL{=8C4D6-NMV{JT!o?Yoh&Cxpp3Rb+Z zIfi2cCKbPi-_xO^srPUHF_mLYJ_@OvkX}B(;|u#7YFqa|%J%Q)+5VfZeCxhoN<^F9 znx48<^hXhd=c4Eh)Gf!W)qcw%GiUYZv6}ney7%7R-uvN>&I$-lTAFh%n8R0^i_S(m zbDCgQ+;k9jA+m=uTUE<+ziZ~(XjXcNrS#S$cFDouwYd^pA6q-l+<_qD&VZOGDrts^ zJM5H&3DKcK>86bKs@lkR%`$EsjZIyq5+4XDa)=Emy?u5?$tpj>Aj{#ZcNq%093-4( z_K1pJL__O}4myDb1bgY62wSZuPVnKbft&y;BiIyiWJ53q##@fZuuwoz_5dC%uE zyP$pdlePH9mEAGz4K5^7p8tFO+d9r9aX+U zcx$k%3;zg>tE<977_cD;*|8o&Xa&%xLMUfw)kXOwMBDXvTggxz2zTdf<%?&r}%Ck@?EgfyAG?KLId0Zx{I>dG?S@2^`M9lA)6v9B0z0&6M!Gv zdW0Vc_3m@>_S-YM++45X4V>L8>Jp^rh(zA4x~Pf8hgaD_U-6;Oo?VgQHH^B4$1AUY zF=#^&A!?gF7g0E&T7MAzH9GoyK}WQ7SH*=zFvR9SsLrUc{|-Ss>@9Jes)UxBV7#Dk zi79e^#vgGo@VL3ibQAs=!@Ra8h!diz)5(6BXNd%9h6dVEyM#=+;D(L$Erv(J(gv-G z29Yv+A-sWeK*MF4jWTQ~DW{0E!XR2>&^oThH8>@V4#NEbd&+d*rCiIyZc?POW8 zInCn)3zZ9#nbC+w%%fX!qU0bh#*0zCh4I%(mtJ28{EUM9?Rb*<1oXO7y1QgG+@49_ zud1?=5Hh!`@M(N@c7qbEX-(li?T2WfF4aVslarIkm1!CIT~EyaLd9Kt2Alv!oNP3N z2S{<$Q`OsS2ktUVb{G*K!6*ZD4WE9}S0DT6dAP(uXbuETXvFr9D7-$QE9=Nr;I|-u z`#As_3Pm)7`;zp4AQg_ftmZUH)MbvvZm92Z9mCX}fxd|(FeI>~5iASg5s^)M4l|98UGz-I){>0 zv4g@K%La1PEw`kWd%@$u_29}p_I1&^&Hi^$cmY=%jSk31XPN-2v%aLRQu5#;ZI6$T zL5hedAhu&4$5c0N+|YM{5eSa@6|3>;B|~;F%5e4w0ZO3m4v|}!m&7g4`FymZUHOPl z=xaFNIfTH>5X(f($YZ>E27vhA51#c%$Y9C1CQ|qnDmW1A@sUywLCH`D13(?A8bq+9 zB4lnI^-x$DIU6b{m(-}^MFXR(_Cz{p_I66<)`fJqitWK*KL(){|Avi_8Utl!kuN!@ ziz5OIjfJ*I1AG9&pXz(3?f|g+)<%mJ%x67DfrZBfKLxzNR*?z7*>zllhXbrhD3Fr0 zrFlzjokM@R(pE9ot)#Z-dlXby1;#?x>g8ZanM#H;~dNHUcJu*GVo;8NL1 zcoW|YsL(mONq1#pi#&%t&2Y|!6Gmn2rnPs#i5;KAwiv3t%%f(n57A=TtX9^8br@JL zxQ0i3r=O+t+@y+{rWp1s@{Yo;{6K}y^4?n9IH&h-{+=gbx9x+7eJSfBL& z6|bHXuIvoHg_q`{gw_;ALXM&cB)G<9OeBOTiqbNPqL4X%$k{^TXvo`Ge=)-ig-^10 zg9UGU#e#%6Ax#y76YIhipQ*xjRdX^0Z_Aw6VO1BA^hb znvZCmw|@?JpCGRzwuZDF$F1S=2eCM^l5uzz1#Z9FzcfjxpyVvoG_yV|_&vUMSl@XAD}=kZk>YkD*e zUt%8~UwoZN9G!PTzMu0|I1w(~Rsh3m!4tt#K@%ltzTx*-Fy4Car^>y;K16N4^4UCt z>i!!Zfqr-aJfOcc5Ll5Vn3@QLh)CepbnXz1v@mp0gaS|!wWHc)xkyK-qrY7e?-RQ^ e=jH?jf9P@V$21TTOs@;F*u8?B>`LeAU;YCRJ!}L3 diff --git a/PythonHome/Lib/lib2to3/fixer_util.py b/PythonHome/Lib/lib2to3/fixer_util.py new file mode 100644 index 0000000000..78fdf26dce --- /dev/null +++ b/PythonHome/Lib/lib2to3/fixer_util.py @@ -0,0 +1,432 @@ +"""Utility functions, node construction macros, etc.""" +# Author: Collin Winter + +from itertools import islice + +# Local imports +from .pgen2 import token +from .pytree import Leaf, Node +from .pygram import python_symbols as syms +from . import patcomp + + +########################################################### +### Common node-construction "macros" +########################################################### + +def KeywordArg(keyword, value): + return Node(syms.argument, + [keyword, Leaf(token.EQUAL, u"="), value]) + +def LParen(): + return Leaf(token.LPAR, u"(") + +def RParen(): + return Leaf(token.RPAR, u")") + +def Assign(target, source): + """Build an assignment statement""" + if not isinstance(target, list): + target = [target] + if not isinstance(source, list): + source.prefix = u" " + source = [source] + + return Node(syms.atom, + target + [Leaf(token.EQUAL, u"=", prefix=u" ")] + source) + +def Name(name, prefix=None): + """Return a NAME leaf""" + return Leaf(token.NAME, name, prefix=prefix) + +def Attr(obj, attr): + """A node tuple for obj.attr""" + return [obj, Node(syms.trailer, [Dot(), attr])] + +def Comma(): + """A comma leaf""" + return Leaf(token.COMMA, u",") + +def Dot(): + """A period (.) leaf""" + return Leaf(token.DOT, u".") + +def ArgList(args, lparen=LParen(), rparen=RParen()): + """A parenthesised argument list, used by Call()""" + node = Node(syms.trailer, [lparen.clone(), rparen.clone()]) + if args: + node.insert_child(1, Node(syms.arglist, args)) + return node + +def Call(func_name, args=None, prefix=None): + """A function call""" + node = Node(syms.power, [func_name, ArgList(args)]) + if prefix is not None: + node.prefix = prefix + return node + +def Newline(): + """A newline literal""" + return Leaf(token.NEWLINE, u"\n") + +def BlankLine(): + """A blank line""" + return Leaf(token.NEWLINE, u"") + +def Number(n, prefix=None): + return Leaf(token.NUMBER, n, prefix=prefix) + +def Subscript(index_node): + """A numeric or string subscript""" + return Node(syms.trailer, [Leaf(token.LBRACE, u"["), + index_node, + Leaf(token.RBRACE, u"]")]) + +def String(string, prefix=None): + """A string leaf""" + return Leaf(token.STRING, string, prefix=prefix) + +def ListComp(xp, fp, it, test=None): + """A list comprehension of the form [xp for fp in it if test]. + + If test is None, the "if test" part is omitted. + """ + xp.prefix = u"" + fp.prefix = u" " + it.prefix = u" " + for_leaf = Leaf(token.NAME, u"for") + for_leaf.prefix = u" " + in_leaf = Leaf(token.NAME, u"in") + in_leaf.prefix = u" " + inner_args = [for_leaf, fp, in_leaf, it] + if test: + test.prefix = u" " + if_leaf = Leaf(token.NAME, u"if") + if_leaf.prefix = u" " + inner_args.append(Node(syms.comp_if, [if_leaf, test])) + inner = Node(syms.listmaker, [xp, Node(syms.comp_for, inner_args)]) + return Node(syms.atom, + [Leaf(token.LBRACE, u"["), + inner, + Leaf(token.RBRACE, u"]")]) + +def FromImport(package_name, name_leafs): + """ Return an import statement in the form: + from package import name_leafs""" + # XXX: May not handle dotted imports properly (eg, package_name='foo.bar') + #assert package_name == '.' or '.' not in package_name, "FromImport has "\ + # "not been tested with dotted package names -- use at your own "\ + # "peril!" + + for leaf in name_leafs: + # Pull the leaves out of their old tree + leaf.remove() + + children = [Leaf(token.NAME, u"from"), + Leaf(token.NAME, package_name, prefix=u" "), + Leaf(token.NAME, u"import", prefix=u" "), + Node(syms.import_as_names, name_leafs)] + imp = Node(syms.import_from, children) + return imp + + +########################################################### +### Determine whether a node represents a given literal +########################################################### + +def is_tuple(node): + """Does the node represent a tuple literal?""" + if isinstance(node, Node) and node.children == [LParen(), RParen()]: + return True + return (isinstance(node, Node) + and len(node.children) == 3 + and isinstance(node.children[0], Leaf) + and isinstance(node.children[1], Node) + and isinstance(node.children[2], Leaf) + and node.children[0].value == u"(" + and node.children[2].value == u")") + +def is_list(node): + """Does the node represent a list literal?""" + return (isinstance(node, Node) + and len(node.children) > 1 + and isinstance(node.children[0], Leaf) + and isinstance(node.children[-1], Leaf) + and node.children[0].value == u"[" + and node.children[-1].value == u"]") + + +########################################################### +### Misc +########################################################### + +def parenthesize(node): + return Node(syms.atom, [LParen(), node, RParen()]) + + +consuming_calls = set(["sorted", "list", "set", "any", "all", "tuple", "sum", + "min", "max", "enumerate"]) + +def attr_chain(obj, attr): + """Follow an attribute chain. + + If you have a chain of objects where a.foo -> b, b.foo-> c, etc, + use this to iterate over all objects in the chain. Iteration is + terminated by getattr(x, attr) is None. + + Args: + obj: the starting object + attr: the name of the chaining attribute + + Yields: + Each successive object in the chain. + """ + next = getattr(obj, attr) + while next: + yield next + next = getattr(next, attr) + +p0 = """for_stmt< 'for' any 'in' node=any ':' any* > + | comp_for< 'for' any 'in' node=any any* > + """ +p1 = """ +power< + ( 'iter' | 'list' | 'tuple' | 'sorted' | 'set' | 'sum' | + 'any' | 'all' | 'enumerate' | (any* trailer< '.' 'join' >) ) + trailer< '(' node=any ')' > + any* +> +""" +p2 = """ +power< + ( 'sorted' | 'enumerate' ) + trailer< '(' arglist ')' > + any* +> +""" +pats_built = False +def in_special_context(node): + """ Returns true if node is in an environment where all that is required + of it is being iterable (ie, it doesn't matter if it returns a list + or an iterator). + See test_map_nochange in test_fixers.py for some examples and tests. + """ + global p0, p1, p2, pats_built + if not pats_built: + p0 = patcomp.compile_pattern(p0) + p1 = patcomp.compile_pattern(p1) + p2 = patcomp.compile_pattern(p2) + pats_built = True + patterns = [p0, p1, p2] + for pattern, parent in zip(patterns, attr_chain(node, "parent")): + results = {} + if pattern.match(parent, results) and results["node"] is node: + return True + return False + +def is_probably_builtin(node): + """ + Check that something isn't an attribute or function name etc. + """ + prev = node.prev_sibling + if prev is not None and prev.type == token.DOT: + # Attribute lookup. + return False + parent = node.parent + if parent.type in (syms.funcdef, syms.classdef): + return False + if parent.type == syms.expr_stmt and parent.children[0] is node: + # Assignment. + return False + if parent.type == syms.parameters or \ + (parent.type == syms.typedargslist and ( + (prev is not None and prev.type == token.COMMA) or + parent.children[0] is node + )): + # The name of an argument. + return False + return True + +def find_indentation(node): + """Find the indentation of *node*.""" + while node is not None: + if node.type == syms.suite and len(node.children) > 2: + indent = node.children[1] + if indent.type == token.INDENT: + return indent.value + node = node.parent + return u"" + +########################################################### +### The following functions are to find bindings in a suite +########################################################### + +def make_suite(node): + if node.type == syms.suite: + return node + node = node.clone() + parent, node.parent = node.parent, None + suite = Node(syms.suite, [node]) + suite.parent = parent + return suite + +def find_root(node): + """Find the top level namespace.""" + # Scamper up to the top level namespace + while node.type != syms.file_input: + node = node.parent + if not node: + raise ValueError("root found before file_input node was found.") + return node + +def does_tree_import(package, name, node): + """ Returns true if name is imported from package at the + top level of the tree which node belongs to. + To cover the case of an import like 'import foo', use + None for the package and 'foo' for the name. """ + binding = find_binding(name, find_root(node), package) + return bool(binding) + +def is_import(node): + """Returns true if the node is an import statement.""" + return node.type in (syms.import_name, syms.import_from) + +def touch_import(package, name, node): + """ Works like `does_tree_import` but adds an import statement + if it was not imported. """ + def is_import_stmt(node): + return (node.type == syms.simple_stmt and node.children and + is_import(node.children[0])) + + root = find_root(node) + + if does_tree_import(package, name, root): + return + + # figure out where to insert the new import. First try to find + # the first import and then skip to the last one. + insert_pos = offset = 0 + for idx, node in enumerate(root.children): + if not is_import_stmt(node): + continue + for offset, node2 in enumerate(root.children[idx:]): + if not is_import_stmt(node2): + break + insert_pos = idx + offset + break + + # if there are no imports where we can insert, find the docstring. + # if that also fails, we stick to the beginning of the file + if insert_pos == 0: + for idx, node in enumerate(root.children): + if (node.type == syms.simple_stmt and node.children and + node.children[0].type == token.STRING): + insert_pos = idx + 1 + break + + if package is None: + import_ = Node(syms.import_name, [ + Leaf(token.NAME, u"import"), + Leaf(token.NAME, name, prefix=u" ") + ]) + else: + import_ = FromImport(package, [Leaf(token.NAME, name, prefix=u" ")]) + + children = [import_, Newline()] + root.insert_child(insert_pos, Node(syms.simple_stmt, children)) + + +_def_syms = set([syms.classdef, syms.funcdef]) +def find_binding(name, node, package=None): + """ Returns the node which binds variable name, otherwise None. + If optional argument package is supplied, only imports will + be returned. + See test cases for examples.""" + for child in node.children: + ret = None + if child.type == syms.for_stmt: + if _find(name, child.children[1]): + return child + n = find_binding(name, make_suite(child.children[-1]), package) + if n: ret = n + elif child.type in (syms.if_stmt, syms.while_stmt): + n = find_binding(name, make_suite(child.children[-1]), package) + if n: ret = n + elif child.type == syms.try_stmt: + n = find_binding(name, make_suite(child.children[2]), package) + if n: + ret = n + else: + for i, kid in enumerate(child.children[3:]): + if kid.type == token.COLON and kid.value == ":": + # i+3 is the colon, i+4 is the suite + n = find_binding(name, make_suite(child.children[i+4]), package) + if n: ret = n + elif child.type in _def_syms and child.children[1].value == name: + ret = child + elif _is_import_binding(child, name, package): + ret = child + elif child.type == syms.simple_stmt: + ret = find_binding(name, child, package) + elif child.type == syms.expr_stmt: + if _find(name, child.children[0]): + ret = child + + if ret: + if not package: + return ret + if is_import(ret): + return ret + return None + +_block_syms = set([syms.funcdef, syms.classdef, syms.trailer]) +def _find(name, node): + nodes = [node] + while nodes: + node = nodes.pop() + if node.type > 256 and node.type not in _block_syms: + nodes.extend(node.children) + elif node.type == token.NAME and node.value == name: + return node + return None + +def _is_import_binding(node, name, package=None): + """ Will reuturn node if node will import name, or node + will import * from package. None is returned otherwise. + See test cases for examples. """ + + if node.type == syms.import_name and not package: + imp = node.children[1] + if imp.type == syms.dotted_as_names: + for child in imp.children: + if child.type == syms.dotted_as_name: + if child.children[2].value == name: + return node + elif child.type == token.NAME and child.value == name: + return node + elif imp.type == syms.dotted_as_name: + last = imp.children[-1] + if last.type == token.NAME and last.value == name: + return node + elif imp.type == token.NAME and imp.value == name: + return node + elif node.type == syms.import_from: + # unicode(...) is used to make life easier here, because + # from a.b import parses to ['import', ['a', '.', 'b'], ...] + if package and unicode(node.children[1]).strip() != package: + return None + n = node.children[3] + if package and _find(u"as", n): + # See test_from_import_as for explanation + return None + elif n.type == syms.import_as_names and _find(name, n): + return node + elif n.type == syms.import_as_name: + child = n.children[2] + if child.type == token.NAME and child.value == name: + return node + elif n.type == token.NAME and n.value == name: + return node + elif package and n.type == token.STAR: + return node + return None diff --git a/PythonHome/Lib/lib2to3/fixer_util.pyc b/PythonHome/Lib/lib2to3/fixer_util.pyc deleted file mode 100644 index 78ff67d157b9f7e3730fde9ac3a7da589ae9a5d3..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 14173 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 fcBDE{#XSc!@Zs7~l=5c+t + ')' + > + > + """ + + def transform(self, node, results): + syms = self.syms + assert results + func = results["func"] + args = results["args"] + kwds = results.get("kwds") + prefix = node.prefix + func = func.clone() + if (func.type not in (token.NAME, syms.atom) and + (func.type != syms.power or + func.children[-2].type == token.DOUBLESTAR)): + # Need to parenthesize + func = parenthesize(func) + func.prefix = "" + args = args.clone() + args.prefix = "" + if kwds is not None: + kwds = kwds.clone() + kwds.prefix = "" + l_newargs = [pytree.Leaf(token.STAR, u"*"), args] + if kwds is not None: + l_newargs.extend([Comma(), + pytree.Leaf(token.DOUBLESTAR, u"**"), + kwds]) + l_newargs[-2].prefix = u" " # that's the ** token + # XXX Sometimes we could be cleverer, e.g. apply(f, (x, y) + t) + # can be translated into f(x, y, *t) instead of f(*(x, y) + t) + #new = pytree.Node(syms.power, (func, ArgList(l_newargs))) + return Call(func, l_newargs, prefix=prefix) diff --git a/PythonHome/Lib/lib2to3/fixes/fix_apply.pyc b/PythonHome/Lib/lib2to3/fixes/fix_apply.pyc deleted file mode 100644 index 4d762d5dd2005efa779fa27426ff1bbd2552313b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1838 zcmbVM*={3M5UpO^UNTDv@DL44zqxHi78+hN5l+ZRNST1z0ffn@r(<6`ZTDjJy`IF# zc_I7(f52DpLHq&lggVvMM0sMd<#N@j<<_m`I)6TH{r>%%!H6~=hyTCepDvh;iH1xq z8rzgwl-V@2$%5=q>QLs=(5+-w^femRD!E3fM_HYQb;=qvY*5yuVUu+psT$2%G~pn1 z`i1D0=!fAJjThPvH(rKE|pGxQl`NGr`t!K@2ZFc5BaA*W}>)?7AY>CBNcT~QNB6X zDjWnzQ1{rO<@0AzT&Z&3Z_BmY0s%H^=d15#aj&UjH zW#Y44ia0}FgX*N3fHeUgDV3D*~^0gM=(!l_Egf^CSIpo8=c*I>w43?=Qdp_VDC*aMlk)#H*Y+X2?P% zov3&sFpMNyb!}8W4zd0rGLnZ$OteZX+q@VnQ)gYN^fEO%#KRB*2=O9>7|rSy;L<2p zS14J)0twMRbG`GE^K(2u8Z?si@9}E|XI}nX^IMpG%7Xrk30Y0+k=5ew zQ{kRjJJzmU@zCJ=Oy~~VY`X#8J}FHU<#DE>NJwfOMcToJ39_f!%tXye}#X4j}Qr<-5QK%c~3n1G(gFuhEX&wMo|=^UsYews>M|0 z&!yub=1EdUiOOhcl2jT~wMhDk(jW56{W7_h)BaDIQlkB;C{ BW~u-H diff --git a/PythonHome/Lib/lib2to3/fixes/fix_basestring.py b/PythonHome/Lib/lib2to3/fixes/fix_basestring.py new file mode 100644 index 0000000000..a3c9a43649 --- /dev/null +++ b/PythonHome/Lib/lib2to3/fixes/fix_basestring.py @@ -0,0 +1,14 @@ +"""Fixer for basestring -> str.""" +# Author: Christian Heimes + +# Local imports +from .. import fixer_base +from ..fixer_util import Name + +class FixBasestring(fixer_base.BaseFix): + BM_compatible = True + + PATTERN = "'basestring'" + + def transform(self, node, results): + return Name(u"str", prefix=node.prefix) diff --git a/PythonHome/Lib/lib2to3/fixes/fix_basestring.pyc b/PythonHome/Lib/lib2to3/fixes/fix_basestring.pyc deleted file mode 100644 index d76cb745b55a48b61469eaa2aa4aef111e466d69..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 762 zcmbV~!AiqG5Qb-yG-|O>@T$;@n2SB=Rf@LgNrR*XF%;Ie*-A>%lhw1SHr)JeA44BO6u1RL#jfqa;~u~jHz*nge3ssaoNPf( zX52UrK5KxX4D%-Ux&`HFGVw%)&KtQ{A%0X@E%n#ya7w(|uxvYDCy diff --git a/PythonHome/Lib/lib2to3/fixes/fix_buffer.py b/PythonHome/Lib/lib2to3/fixes/fix_buffer.py new file mode 100644 index 0000000000..c6b0928024 --- /dev/null +++ b/PythonHome/Lib/lib2to3/fixes/fix_buffer.py @@ -0,0 +1,22 @@ +# Copyright 2007 Google, Inc. All Rights Reserved. +# Licensed to PSF under a Contributor Agreement. + +"""Fixer that changes buffer(...) into memoryview(...).""" + +# Local imports +from .. import fixer_base +from ..fixer_util import Name + + +class FixBuffer(fixer_base.BaseFix): + BM_compatible = True + + explicit = True # The user must ask for this fixer + + PATTERN = """ + power< name='buffer' trailer< '(' [any] ')' > any* > + """ + + def transform(self, node, results): + name = results["name"] + name.replace(Name(u"memoryview", prefix=name.prefix)) diff --git a/PythonHome/Lib/lib2to3/fixes/fix_buffer.pyc b/PythonHome/Lib/lib2to3/fixes/fix_buffer.pyc deleted file mode 100644 index 7f99caf2255c4eb62f35698bb96cd2e45a2db493..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 919 zcmbVKO>fjN5FIDk0E;U1z=fL;hon8^036GTZUrY;q3lYCu*l@Yp{|?{#SZOC<+S`L z{uh6M8KtW}M8-n>Y4<9L&GJ`?N0M=JE0U0?nKuQ~((wgUSQVpz$E{fKlv& z_Mr(N3os5qdT=p=8b8e78^9jmeHKC$!aBY~#hxL&Qde@|_B^+|JkQ(D((q!eYdOS8 zk{of>+KxA}>4x1GB`@7!qC8BD8G@Z7)Ko$gxslUZfM=_`k@g-sSbyp2{hEdHmT2ZN zg2Y)E5zTyuftzkd(;;JIo33N(W>SPX|KsVqOF5kI7F#`!CejhNL#{L(M{&eI*fX|gC@`RoZdOZ3 zG)9u+RxKN1*bfo~im8z$)d$(@yp$=)kW!+n;Yt{(>#0^($(x_esI5sUJ4TzpJVGzo zzE;IntKy06o^ELehEPmGB>m3Gk8-r8?uO<8rWk4mY|h;J?OhCnAl^c_MGDb$)u<_? zKR3fD?EyN=H=^vCKDVmS(xu6(UaL}BNAm6IX7e&#rL^u_lFs`#rYUXsKAIs)Aq%}Q z2))(Bk~9;d>PlpVF3?5z{oajMX(y)Rvcy}6SI$-ZFD`DplSzjKsbFY{p?}B@{hxq2 By6gY| diff --git a/PythonHome/Lib/lib2to3/fixes/fix_callable.py b/PythonHome/Lib/lib2to3/fixes/fix_callable.py new file mode 100644 index 0000000000..df33d614ba --- /dev/null +++ b/PythonHome/Lib/lib2to3/fixes/fix_callable.py @@ -0,0 +1,37 @@ +# Copyright 2007 Google, Inc. All Rights Reserved. +# Licensed to PSF under a Contributor Agreement. + +"""Fixer for callable(). + +This converts callable(obj) into isinstance(obj, collections.Callable), adding a +collections import if needed.""" + +# Local imports +from lib2to3 import fixer_base +from lib2to3.fixer_util import Call, Name, String, Attr, touch_import + +class FixCallable(fixer_base.BaseFix): + BM_compatible = True + + order = "pre" + + # Ignore callable(*args) or use of keywords. + # Either could be a hint that the builtin callable() is not being used. + PATTERN = """ + power< 'callable' + trailer< lpar='(' + ( not(arglist | argument) any ','> ) + rpar=')' > + after=any* + > + """ + + def transform(self, node, results): + func = results['func'] + + touch_import(None, u'collections', node=node) + + args = [func.clone(), String(u', ')] + args.extend(Attr(Name(u'collections'), Name(u'Callable'))) + return Call(Name(u'isinstance'), args, prefix=node.prefix) diff --git a/PythonHome/Lib/lib2to3/fixes/fix_callable.pyc b/PythonHome/Lib/lib2to3/fixes/fix_callable.pyc deleted file mode 100644 index 9b4f696fec903b006369c0bc302df7337dcfd7b9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1462 zcmbVMO>fgc5FOizQvyhQT;PIMaEODd9N?N(v=y8nLQW-wsbm~`Q#SHPw7Z5@N>7FV z#Q)+4z?)6e76}eu$&>NS?wi>+Zxj5u-T(gX<20v>C&2FuyygQ;L6pFHRQObSRQZ(n zIO_KgKPe;frv5Cog|kUDv&B%T+BQNNRU4btxr`9p#@e!! zxm8VVMh6$mhub163RNGAtbZ*pRJClh6>2VODGOPQ)K5H-hjwfqX3jmOv&_h-%drj& zV>)M&RnmrtOsxjAi|tvf?JZu~wE3rWjc;!vfa7htxg?qE?Bg|0U?fQPn5iUigm;*5 zFbd8=8Ay$%5l_XkS!!tlZ0`#^%jS#JV=>r}GjLJP;ITSWC8x_}rgsL>Z^`u%*htik zjWT^)Dr3b;z-ud6+i_N(iowo6;CFW@=53wtz`b7J5<_6$dchiI90BuhNDg;es~P5_MC^)<h1@SIRZAoW~4@QxHKxZD~!+ZMfbra}(i%oN<~Q9lchwqf*VD+2;8X-v+}r z-6(CeJhcu`XSKoAtsY^!;i}~I{rmm{@3H4@xaBHoTI0&3sk>TfS~W#m@+UWas9R}o z!`Xk6=1sNCtinHlJ87c}+w%ZLKQTJUhmD7V81HX)(Y){yAQ$6Ib*<8+Oc%*Iex~ Nrr{HW!5uI1e*rSSK>z>% diff --git a/PythonHome/Lib/lib2to3/fixes/fix_dict.py b/PythonHome/Lib/lib2to3/fixes/fix_dict.py new file mode 100644 index 0000000000..f681e4d713 --- /dev/null +++ b/PythonHome/Lib/lib2to3/fixes/fix_dict.py @@ -0,0 +1,107 @@ +# Copyright 2007 Google, Inc. All Rights Reserved. +# Licensed to PSF under a Contributor Agreement. + +"""Fixer for dict methods. + +d.keys() -> list(d.keys()) +d.items() -> list(d.items()) +d.values() -> list(d.values()) + +d.iterkeys() -> iter(d.keys()) +d.iteritems() -> iter(d.items()) +d.itervalues() -> iter(d.values()) + +d.viewkeys() -> d.keys() +d.viewitems() -> d.items() +d.viewvalues() -> d.values() + +Except in certain very specific contexts: the iter() can be dropped +when the context is list(), sorted(), iter() or for...in; the list() +can be dropped when the context is list() or sorted() (but not iter() +or for...in!). Special contexts that apply to both: list(), sorted(), tuple() +set(), any(), all(), sum(). + +Note: iter(d.keys()) could be written as iter(d) but since the +original d.iterkeys() was also redundant we don't fix this. And there +are (rare) contexts where it makes a difference (e.g. when passing it +as an argument to a function that introspects the argument). +""" + +# Local imports +from .. import pytree +from .. import patcomp +from ..pgen2 import token +from .. import fixer_base +from ..fixer_util import Name, Call, LParen, RParen, ArgList, Dot +from .. import fixer_util + + +iter_exempt = fixer_util.consuming_calls | set(["iter"]) + + +class FixDict(fixer_base.BaseFix): + BM_compatible = True + + PATTERN = """ + power< head=any+ + trailer< '.' method=('keys'|'items'|'values'| + 'iterkeys'|'iteritems'|'itervalues'| + 'viewkeys'|'viewitems'|'viewvalues') > + parens=trailer< '(' ')' > + tail=any* + > + """ + + def transform(self, node, results): + head = results["head"] + method = results["method"][0] # Extract node for method name + tail = results["tail"] + syms = self.syms + method_name = method.value + isiter = method_name.startswith(u"iter") + isview = method_name.startswith(u"view") + if isiter or isview: + method_name = method_name[4:] + assert method_name in (u"keys", u"items", u"values"), repr(method) + head = [n.clone() for n in head] + tail = [n.clone() for n in tail] + special = not tail and self.in_special_context(node, isiter) + args = head + [pytree.Node(syms.trailer, + [Dot(), + Name(method_name, + prefix=method.prefix)]), + results["parens"].clone()] + new = pytree.Node(syms.power, args) + if not (special or isview): + new.prefix = u"" + new = Call(Name(u"iter" if isiter else u"list"), [new]) + if tail: + new = pytree.Node(syms.power, [new] + tail) + new.prefix = node.prefix + return new + + P1 = "power< func=NAME trailer< '(' node=any ')' > any* >" + p1 = patcomp.compile_pattern(P1) + + P2 = """for_stmt< 'for' any 'in' node=any ':' any* > + | comp_for< 'for' any 'in' node=any any* > + """ + p2 = patcomp.compile_pattern(P2) + + def in_special_context(self, node, isiter): + if node.parent is None: + return False + results = {} + if (node.parent.parent is not None and + self.p1.match(node.parent.parent, results) and + results["node"] is node): + if isiter: + # iter(d.iterkeys()) -> iter(d.keys()), etc. + return results["func"].value in iter_exempt + else: + # list(d.keys()) -> list(d.keys()), etc. + return results["func"].value in fixer_util.consuming_calls + if not isiter: + return False + # for ... in d.iterkeys() -> for ... in d.keys(), etc. + return self.p2.match(node.parent, results) and results["node"] is node diff --git a/PythonHome/Lib/lib2to3/fixes/fix_dict.pyc b/PythonHome/Lib/lib2to3/fixes/fix_dict.pyc deleted file mode 100644 index ed946b194217684647d4962ead233b159470e1be..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3709 zcmbVPTW=f36+X+G#1(akb8&^H@${u!It`0B0SdUWTi^2J2*%1lQP#g z=F`USuke_EU`U827(Gf_lzEi5Xwo8&*KJw1Y0`G<4rLw6yEN&#byxU3n)KYdN7)AD zn>5*^yib!pbR^`l1{D4wLK{lGxq&te5Nl= zFj61gS6OOoup*4WO0CYX^BM{>U&h&7U+1n!Bi4(p^;$Qt-qc-R(ckbJN^^LBm_wr zkH=~83lWkWjQs05)pzS;4J)lGIGS5klyHEfJ@T(;|M6(74%v-3d+h}djID~RD!Wv+ zR7a&fx%(}q+If{}XfxWf<#BN-KUu~3at_o}TJ3TJ#n@Z<4%|s1X zhh+hv!ehX}6jS-I=@0RkXBadv&m#?}YYYB$82^ATKsKNt@QeXzlhFrI1Rw(x0>~Po zFT^cMIwCTl@GxL+&AW(u)BbpKBBz8?8vHvS(g?>r$oyhEjo1S z(Q<RN(LT z9?h_!O^?64K}(+&KAl26(N`_{`cDMwnBDzW_FsvO?9!n8m)HtJJvQQ1iva2yz&@RR7sq8zth{0Q$}KCXWqsdNCdbdq~)UG#3}N zG^V>_Q!rc?bJFMB#axmyk!oU!thm7E+#^!rbMAguUJgfU4QOyvDX=;CPEf84uAcv{ zCfLOmG0|M+#_~y`A2CO<*|@d_SLO-A1SByA5COP*QrEb$*v48{wFphKve5PhNNEwt z%@}7z7K~~7Anbz^vZ9b`2H4piqchoTGw4l7p5S4sbK&5L*W0LX2t5l>>n9Mxe6L=K*$*4CWSQ;}=iUqZe6v zbjOyTykJN+JVyNPGzOxxFYv1{xV!V8V_`nUK%VdI;OXPLi|@eO_CD}#;k%DjPpI#B z?}FaHNW!|9Q+xdl>UI%Jj_ zro~l}yF!J)8lM1>3*3%*6+!5`Mcp}TF~KL!A6MEVJm&8h(91xdgy;-?^)}fS9irkH zu7uI>05;!9^S9{~u(D#I`O#6#LN5a4z+g34gPIE!h=+DZGJ#8nysaS!W-yIAwngTT zax`OMe|?10U;gd7{=tX+&eH_ZGjdL)sa8XAPfd57K;pEcev7KfZ|$%;cC z=7x+DA*%>EI1Zb}m + """ + + def transform(self, node, results): + syms = self.syms + + tail = [n.clone() for n in results["tail"]] + + try_cleanup = [ch.clone() for ch in results["cleanup"]] + for except_clause, e_suite in find_excepts(try_cleanup): + if len(except_clause.children) == 4: + (E, comma, N) = except_clause.children[1:4] + comma.replace(Name(u"as", prefix=u" ")) + + if N.type != token.NAME: + # Generate a new N for the except clause + new_N = Name(self.new_name(), prefix=u" ") + target = N.clone() + target.prefix = u"" + N.replace(new_N) + new_N = new_N.clone() + + # Insert "old_N = new_N" as the first statement in + # the except body. This loop skips leading whitespace + # and indents + #TODO(cwinter) suite-cleanup + suite_stmts = e_suite.children + for i, stmt in enumerate(suite_stmts): + if isinstance(stmt, pytree.Node): + break + + # The assignment is different if old_N is a tuple or list + # In that case, the assignment is old_N = new_N.args + if is_tuple(N) or is_list(N): + assign = Assign(target, Attr(new_N, Name(u'args'))) + else: + assign = Assign(target, new_N) + + #TODO(cwinter) stopgap until children becomes a smart list + for child in reversed(suite_stmts[:i]): + e_suite.insert_child(0, child) + e_suite.insert_child(i, assign) + elif N.prefix == u"": + # No space after a comma is legal; no space after "as", + # not so much. + N.prefix = u" " + + #TODO(cwinter) fix this when children becomes a smart list + children = [c.clone() for c in node.children[:3]] + try_cleanup + tail + return pytree.Node(node.type, children) diff --git a/PythonHome/Lib/lib2to3/fixes/fix_except.pyc b/PythonHome/Lib/lib2to3/fixes/fix_except.pyc deleted file mode 100644 index 72a727d0d2b402a911e95a3672b6f22e1f905f0b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2949 zcmbVOTW{P%6h7mT-FU`L zBH2&n34Q?*zkpxBU*MPY2k^uj=bUkRK_#Mf?1|_2T)uOit^GCA`D5qD?EtE)hX239 zNB@jV2r$G|KA!fC(di716-vbM_%uq7WZ-K>ym2fKlnln{ zGnE+?-tBZgmTQ&Lt=n>NcTJuit4zs(jI{JwF)~TKF1Vzxk?(TBbZjc&+tTEdSV_bl zN7_`n{;dz`M7p>J^1d|I>fji0;2n-rh0p^(*Gd}n&G^}oGID$<{q(|xH5tUrkmTBs zqdu#p=wL)H_w)^zh}EdfkKY0A2IA43$ibZTFlAtxxJ=GXrj*?`h&X<#QoE((9#USt z1I$g2xLIUV>*y#ob=+?nlkrO*9WX7VMA~DVX3B0Tq|Bku6CIFQs%5ei;G++4IokyT zP+(;Vc(nf*_8ce$lnxXQj06~5Yw*;8Y=$XyD*e?_gUX+%L!zQ|!40sodg#D+;$#RX zGj#7@w`}(aYd^vTa&p5Kij4%j)h1$^Cm2zq7_K>=D3=^EGcN@^n>+S1IF8~l!}=yy zp80XEdgK^y({ZS@Azve2(;mJ8FZu?)ZR~v;9qh%?!5uUHe2+q`Y4t3u4NS>2aver# zSdsJxxYvXR#Hv^jSA`+O*mPUmZ4^qr$mTRjMKo~?ok=& z&rpC1&}8SHHi@|>*YR~-uHRjkJsl<37)+Oi)Hzn%tv9;Bc0&*=Kg}oidlr8crT!Y_QF@6-^@9nNz9hU&ue~Ylifx@v??Lu<7}ey^0cIhHG$RuLflY$}W`CP;>!11=}{ne!-RW36vDY zG>oPIOL^3Wr!~m_6v#wAbO`B7))IRTIT?OAOD8}v3tpFr4Jc*^g}{Fm2XeOwTR8`3 zp8}R~F=riER(7q5DG6aP#pS%z!dw};2Wmu4#VHYH45Unk}mchRTCT^u@z)HDXc}fDPX_>5S z_o%=7cFthk^Q^48D56mnQ6J~jp}yvkJINFdh@8kW#|3g?qj}ClEuxC-QAyg7#p5-` z^T@q|G^`kaSfwsmWm}n=#D1V$;&W-tyQG=%^fw=G@qkO!sYl0>yG-9{+!*4Fbd=)R zo}x7FDjA%2F3nMwI>IG$F5zQ6nZkoytB_|J%HpZ+@$h84Y*VZFkY8wURseM#8_nLh z^Q3Q)^if2DW7DN~99UJzT;7vuoK-ZWc<65NC=SL+;`6?5M>BfW=aAadnRT%ck2&qm zk!}J{(~uc`d)#qMY3Q@IfP?wYbDhJO`KiWVO35c=*2M7cA zV2g!fI5|@39j-T*(#e?V2+X|PMDeTQvBmkSs>o4W&Xnng_=^OOKSuCg*ts_E*-$;8 R64%rn&HB8czYV9|{0H7fZqxt( diff --git a/PythonHome/Lib/lib2to3/fixes/fix_exec.py b/PythonHome/Lib/lib2to3/fixes/fix_exec.py new file mode 100644 index 0000000000..50e1854454 --- /dev/null +++ b/PythonHome/Lib/lib2to3/fixes/fix_exec.py @@ -0,0 +1,40 @@ +# Copyright 2006 Google, Inc. All Rights Reserved. +# Licensed to PSF under a Contributor Agreement. + +"""Fixer for exec. + +This converts usages of the exec statement into calls to a built-in +exec() function. + +exec code in ns1, ns2 -> exec(code, ns1, ns2) +""" + +# Local imports +from .. import pytree +from .. import fixer_base +from ..fixer_util import Comma, Name, Call + + +class FixExec(fixer_base.BaseFix): + BM_compatible = True + + PATTERN = """ + exec_stmt< 'exec' a=any 'in' b=any [',' c=any] > + | + exec_stmt< 'exec' (not atom<'(' [any] ')'>) a=any > + """ + + def transform(self, node, results): + assert results + syms = self.syms + a = results["a"] + b = results.get("b") + c = results.get("c") + args = [a.clone()] + args[0].prefix = "" + if b is not None: + args.extend([Comma(), b.clone()]) + if c is not None: + args.extend([Comma(), c.clone()]) + + return Call(Name(u"exec"), args, prefix=node.prefix) diff --git a/PythonHome/Lib/lib2to3/fixes/fix_exec.pyc b/PythonHome/Lib/lib2to3/fixes/fix_exec.pyc deleted file mode 100644 index 60dd9f7fa72ac33bf6c61c5d54fb5cdba71c8a5a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1387 zcmbVLUuzRV5TCtEE=_2)2!chW`*s&-3)a^fY)gI8AlHDHR?f?1lU}?(<#r<}q%XE# z!O!8V-@%XL7w|WGEk#5SFYGTfvoo_Zznyh|u64e@`*@tt&FA9(C6wy@VE<(LsVv3u%O2yoS#6nA16M*(oX>j zObb#V*tM)Tn02rPKEvaH3(*TeN8;lyB5iWBCw-QE8NY~&3+bnYFGp59@wa@Lu=qjt zY|!#Ap+Qj^8JjZS^8;U=*a*Mt_qsPp>*$0#3L>!xXR8vnjz0u$oFF%<7%n{C}crzLfScfosLekbhK;A=chcn znla*rb}-p(j;-QC;|=DIq3A~d604#uI^w?ltwG!54w0)rk!hTDpwyd2Ln zR=JNsHCJX0!oiy;Df9E#q@%3v;O+ika1{2#huFQV^qobZ6ouSWh()1&#CMN&Zqlsgo2j;>TVfCJnDI<)`u`})GO|~5(BsoIQ{=hpVqH9O Fe*wEc8rc8< diff --git a/PythonHome/Lib/lib2to3/fixes/fix_execfile.py b/PythonHome/Lib/lib2to3/fixes/fix_execfile.py new file mode 100644 index 0000000000..2f29d3b281 --- /dev/null +++ b/PythonHome/Lib/lib2to3/fixes/fix_execfile.py @@ -0,0 +1,52 @@ +# Copyright 2006 Google, Inc. All Rights Reserved. +# Licensed to PSF under a Contributor Agreement. + +"""Fixer for execfile. + +This converts usages of the execfile function into calls to the built-in +exec() function. +""" + +from .. import fixer_base +from ..fixer_util import (Comma, Name, Call, LParen, RParen, Dot, Node, + ArgList, String, syms) + + +class FixExecfile(fixer_base.BaseFix): + BM_compatible = True + + PATTERN = """ + power< 'execfile' trailer< '(' arglist< filename=any [',' globals=any [',' locals=any ] ] > ')' > > + | + power< 'execfile' trailer< '(' filename=any ')' > > + """ + + def transform(self, node, results): + assert results + filename = results["filename"] + globals = results.get("globals") + locals = results.get("locals") + + # Copy over the prefix from the right parentheses end of the execfile + # call. + execfile_paren = node.children[-1].children[-1].clone() + # Construct open().read(). + open_args = ArgList([filename.clone()], rparen=execfile_paren) + open_call = Node(syms.power, [Name(u"open"), open_args]) + read = [Node(syms.trailer, [Dot(), Name(u'read')]), + Node(syms.trailer, [LParen(), RParen()])] + open_expr = [open_call] + read + # Wrap the open call in a compile call. This is so the filename will be + # preserved in the execed code. + filename_arg = filename.clone() + filename_arg.prefix = u" " + exec_str = String(u"'exec'", u" ") + compile_args = open_expr + [Comma(), filename_arg, Comma(), exec_str] + compile_call = Call(Name(u"compile"), compile_args, u"") + # Finally, replace the execfile call with an exec call. + args = [compile_call] + if globals is not None: + args.extend([Comma(), globals.clone()]) + if locals is not None: + args.extend([Comma(), locals.clone()]) + return Call(Name(u"exec"), args, prefix=node.prefix) diff --git a/PythonHome/Lib/lib2to3/fixes/fix_execfile.pyc b/PythonHome/Lib/lib2to3/fixes/fix_execfile.pyc deleted file mode 100644 index 9475b53c252bcca3d3cf1b97ab3d8df31612c645..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2028 zcmbVNTW{k;6h7lPHz#Q-cwm>S5z@wspbzj`Dz;1asZ=Ys62f$4oOqHt_!4=>&`Qn= z<%u7{3x9zB#Seh*jN`T|UI0fvIWyl3og_?UQ=RD;5TGkTcpOMiGCK$Bgx0x4s&aR z$y-5NyIppOmtCp_t)Xhu%+dg*|-B^PeFaTkx?$gSm zTZ^`XRyt%*z!dBBS*KChorQE{q+_Oy2y{E7dO&bj59zI~b05KWMDc*?5rq@ddlV0O z$^OPvJEW&<1=1Zerj?EJP~A8F5eQ69D2C4tZTG0&V<+1w)c^z04?`+LQBP_8Mr*=u zQ%72YL=N-aR`u7{RlEOC-MK|>aEl?Gm^x1ousHYj(62L8g$Jeqk%9RRKL+LvbdtaD zn02|~NvU{@ip`EGWfWJ8bGPDQGKig3JTQwQ+rV-KmdqIjv$3-&C5F^{69N2x%4??pB?yj<88*p=MgeF>}JL1fP9YD=hHqT z)gLn9czt%W8}VG4xa75#dF-)XGutv<8YXWqfl{g})yf~Ufe90i-z3qFYG{h2*$)>f z#H_0O6<=w_B-ibJTV8KU%|_c^@G(;WHXAD4NOvV|Y_fX0ac7pjc@U5x>LYLmm#4}6 zGEL^6>EiQCz8w|QunqWNb7KNQ)pCVPJ9~sf>SHz{#=;R(F}2^e-VyKP_o0|{#$t%Q zcf})X2>A!*^|;g~-Z13*C=AV29EMpDS1B*K4Hso4HCOHU>yRUlbTUty+x6wMi;ENg z%zpyuef<9^37>D_DPG0F^hB@Mv(B1kGFrkgE*1y`Ecr|xd@L%Rqzxz-Lk1ZSaARO( m05@Q%L6CtS?;YbigR9>-|DS=Ix*ax^I${@10@l8GVgC(XM6Ch< diff --git a/PythonHome/Lib/lib2to3/fixes/fix_exitfunc.py b/PythonHome/Lib/lib2to3/fixes/fix_exitfunc.py new file mode 100644 index 0000000000..89fb3db533 --- /dev/null +++ b/PythonHome/Lib/lib2to3/fixes/fix_exitfunc.py @@ -0,0 +1,72 @@ +""" +Convert use of sys.exitfunc to use the atexit module. +""" + +# Author: Benjamin Peterson + +from lib2to3 import pytree, fixer_base +from lib2to3.fixer_util import Name, Attr, Call, Comma, Newline, syms + + +class FixExitfunc(fixer_base.BaseFix): + keep_line_order = True + BM_compatible = True + + PATTERN = """ + ( + sys_import=import_name<'import' + ('sys' + | + dotted_as_names< (any ',')* 'sys' (',' any)* > + ) + > + | + expr_stmt< + power< 'sys' trailer< '.' 'exitfunc' > > + '=' func=any > + ) + """ + + def __init__(self, *args): + super(FixExitfunc, self).__init__(*args) + + def start_tree(self, tree, filename): + super(FixExitfunc, self).start_tree(tree, filename) + self.sys_import = None + + def transform(self, node, results): + # First, find a the sys import. We'll just hope it's global scope. + if "sys_import" in results: + if self.sys_import is None: + self.sys_import = results["sys_import"] + return + + func = results["func"].clone() + func.prefix = u"" + register = pytree.Node(syms.power, + Attr(Name(u"atexit"), Name(u"register")) + ) + call = Call(register, [func], node.prefix) + node.replace(call) + + if self.sys_import is None: + # That's interesting. + self.warning(node, "Can't find sys import; Please add an atexit " + "import at the top of your file.") + return + + # Now add an atexit import after the sys import. + names = self.sys_import.children[1] + if names.type == syms.dotted_as_names: + names.append_child(Comma()) + names.append_child(Name(u"atexit", u" ")) + else: + containing_stmt = self.sys_import.parent + position = containing_stmt.children.index(self.sys_import) + stmt_container = containing_stmt.parent + new_import = pytree.Node(syms.import_name, + [Name(u"import"), Name(u"atexit", u" ")] + ) + new = pytree.Node(syms.simple_stmt, [new_import]) + containing_stmt.insert_child(position + 1, Newline()) + containing_stmt.insert_child(position + 2, new) diff --git a/PythonHome/Lib/lib2to3/fixes/fix_exitfunc.pyc b/PythonHome/Lib/lib2to3/fixes/fix_exitfunc.pyc deleted file mode 100644 index 8c4fbe1939d7ec0d1f3578068c4bef21911c314a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2682 zcmbVO-)|d55T3j9?<6D?+B7^=hY^HOD%-Z{FtM|wEKOT;0_3`-sSNt_o z775Xar9+8JnM1itBbRcIMjkoPdXzONZ_=nqd5cCZ%G)$*Q{JIbhw?6sx|H{5)MM)g zDUW6wG~sPc`kCmQ=!elJB`rD(+BonF7QKVA_(^H&&yDiSiEkEWpiWaenHOWvOOM7(o?0Qqu8hbE4IO680Sg`53JQPIEb^% zHhJlw%=6d+&QP6XX;IsmMQ-c{D<7w)k5*_d66Ub}A%D&1EEFfqA;o#}L^dRaO{9=R z<^*vfF=!)q7<4E+3;@df%8q*eE1%%f9E+ThD9x)<+k5rDsNit+`}L%M#SZKW`n>OT zi_6z+N=j>062(T2F#CQG7Yo0Cr+@onU;MG#JAI#(thoOgC%3QAU$(spfI6*oWNdEt zuW*2ns`5nX{S^?a<1~}$pzrtBjOqLLuf)~A*Z0Awdx+;Un9G32xL{BVmGL!h>OB^g z{~TH}ja{0#v~=hfVwMw=8TP{f)+>j($cA_UEE@z($(Ib)o>{vJU85sQE0UAn*y$Q(r^ zL|tP?C4^lFfsF%)m|g+u6E+T&Y0Cpz;`iA#?n z54dMdbdXsacV)YjH0a!sK@$Vc7yq3#h(ljCuxrXkJ2dm?+@rImj5la0#?C8H{uE@J zu;7ljO8jAMGTWl0O?zi8TJqU%34(1pc1brKXm-fH4Xlh{Jr`(6M-Z{L_-z&V>>8c5 zY1t(7NjwnFHc+T8G(t$?`fadk7ZcbAass1}!^)y=!*` z8&m0px<|Xqjf*G)kYX5avlMEe^yWOFIj*s8<#SL)t7&Si(&ihU9K=Q6`jfOs(DVGd zzkTUH$rLwpKTZ;EJnMI$UgVjN$HA5r-i}2%*Sw$KhZH3_hw$ad+B`+Q1UFd-wD2t+ zNyUycup8Jat+?7k9@WT)Wuij74q_)ADD-$5!c_>C%G;q;mBnKv#{{1vubEp%xs|3bmPM)`Zt^+{@P?aL4N>618ju__!==%-yV*)~8`lRhrbMynt+? zeMc)R#(;iNsFT(6Wsx|Z{{Ozfg~EU-AU|z*GJ<94dK6&u;>7#HcZ8?NVc!$M{C}s4Yn>)ave2jEGr{%P^TW;6uHiiLw z%f&@eQjQrch`D+ygt8$RZ*iR~?Envmj^;MaYQ_q85u), list(<>), tuple(<>), sorted(<>), ...join(<>), or +for V in <>:. + +NOTE: This is still not correct if the original code was depending on +filter(F, X) to return a string if X is a string and a tuple if X is a +tuple. That would require type inference, which we don't do. Let +Python 2.6 figure it out. +""" + +# Local imports +from ..pgen2 import token +from .. import fixer_base +from ..fixer_util import Name, Call, ListComp, in_special_context + +class FixFilter(fixer_base.ConditionalFix): + BM_compatible = True + + PATTERN = """ + filter_lambda=power< + 'filter' + trailer< + '(' + arglist< + lambdef< 'lambda' + (fp=NAME | vfpdef< '(' fp=NAME ')'> ) ':' xp=any + > + ',' + it=any + > + ')' + > + > + | + power< + 'filter' + trailer< '(' arglist< none='None' ',' seq=any > ')' > + > + | + power< + 'filter' + args=trailer< '(' [any] ')' > + > + """ + + skip_on = "future_builtins.filter" + + def transform(self, node, results): + if self.should_skip(node): + return + + if "filter_lambda" in results: + new = ListComp(results.get("fp").clone(), + results.get("fp").clone(), + results.get("it").clone(), + results.get("xp").clone()) + + elif "none" in results: + new = ListComp(Name(u"_f"), + Name(u"_f"), + results["seq"].clone(), + Name(u"_f")) + + else: + if in_special_context(node): + return None + new = node.clone() + new.prefix = u"" + new = Call(Name(u"list"), [new]) + new.prefix = node.prefix + return new diff --git a/PythonHome/Lib/lib2to3/fixes/fix_filter.pyc b/PythonHome/Lib/lib2to3/fixes/fix_filter.pyc deleted file mode 100644 index 58e3986b084632bab0342ec3ae28d58d420be0dc..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2225 zcmbVNUr*yk5FaNYfgH3as;gSv%eIwjM?!g^Y9A0my+iQCrKf;;*ObaN_BvT`);{n0 z0Ev5|->5J5-Y-Ur)weI^@zaGXkf0}rIk7Xo4LNo^S zC}~jU(X2t^26>D(DQnWKMdMbDw_;}u9Ok!;avmr|&< z={KTlqMyc(DCy8)u*~k>dqn%{LYBf#BP-%*q$kpdRAp9{!TyGL-4jaNTx81F;4Zn> z?{;5F5xvb-0%a*|8EKQ|gM_Rbb!8vby!wMrJW+3 zoBi)ll}QCnWkp`uepfY6!2ks$yTl+rle$K`KvS-2coG>Iw3y3a7|o>H?4lT!8{hzC z-OXo(T?e9cXbKstC=0nb^1|8`kkKFet{-9`?qQ$LvCLNh=-9DG5>484o!jEh9WQb7 zqT|q+qr;%d!hb@oEAZ6G4YO!=l0<_dKbPgUV=&XNx&DHHzEas;2`3fY3NRj(6YkJk zGfd>iIg#nM@N0MX)oPhJ4ANpSeD-2bT#2`7kvOHm7dKSD=kJJ~@V9(%Q4At|xrp$_ z%FY9dzwywYvJaH+E5gyjP|c~~m81UGbO|4^-=qaMK+AzY1oQ=h5=Oq^D8!C{H}TRikWU~^Ch;A0L+v}P-xCnF=DQh zpGfQGN1VaXhz*V0IAH;97|Zo3N{N9oV*9t_#K@7;pe?sD+`%pbJCGxeUWuo>Up5e4?YWk}kW?Utq}13Vf_ivO4&e&yJ4v zMniWHPEnZa5x4K{DL&vRBhK0rEVB&I_S#R|jdo)gtO9c$!Z68W1jV^7CQ@&Xup!G} z#Pih!&p9f?3Lmk$Fr0r^xw=Fj0o~2<(c&*|l@v4q=W2%y*MT=5dyl;@ G8-D{Brt^^i diff --git a/PythonHome/Lib/lib2to3/fixes/fix_funcattrs.py b/PythonHome/Lib/lib2to3/fixes/fix_funcattrs.py new file mode 100644 index 0000000000..9e45c02857 --- /dev/null +++ b/PythonHome/Lib/lib2to3/fixes/fix_funcattrs.py @@ -0,0 +1,21 @@ +"""Fix function attribute names (f.func_x -> f.__x__).""" +# Author: Collin Winter + +# Local imports +from .. import fixer_base +from ..fixer_util import Name + + +class FixFuncattrs(fixer_base.BaseFix): + BM_compatible = True + + PATTERN = """ + power< any+ trailer< '.' attr=('func_closure' | 'func_doc' | 'func_globals' + | 'func_name' | 'func_defaults' | 'func_code' + | 'func_dict') > any* > + """ + + def transform(self, node, results): + attr = results["attr"][0] + attr.replace(Name((u"__%s__" % attr.value[5:]), + prefix=attr.prefix)) diff --git a/PythonHome/Lib/lib2to3/fixes/fix_funcattrs.pyc b/PythonHome/Lib/lib2to3/fixes/fix_funcattrs.pyc deleted file mode 100644 index c6d704bb5e98f6f5d1035fba6df7ccbbe65797bf..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1083 zcmbVL&5G1O5Ux%#Q3qER55fv!ACzPj=ir`%b|k|EvESr|{_ zL-{s7gfC!KXLY;?YC~75x~nQ*)mQC*KNx>~`+iZt#2ZR>KHt>buGUstnPlBS;o8{mOhpG3L0|?I+ot@~pXd$ZeM?O;$9C9Pp=c z1f{I9UR$$2DcVy0OTJPSHag~0 zs^bBlIwS=#Or0CyCX&q)6kCs)afCb{efDAN!#Vcc@k}~i25|Qll1r8kJH~bli3j92 z#OS%DgpO1ELQiKx+&4lf`imud-AUvxCPzy%(aE*W3Yj=|$?IdLdzsMv;6$2{x^lT2 zto$;}P)`!7BE~%ka}Tx2>Xph@TIG*zd$OWoF(d_X<;G&NzOdKO5eaQf)pqqwGz@_Q zc7xq!t`>V0O(BR1A>7yrQMYBU$s|n6u9x-zmDy`iwDmf(D%S(JH_w;Lm&rV#Vcmms z+Fv6~Xb=gd0~WF{486H~MXr7!aL5n|IzU3=x0lgdrH6h}gJ<|o@KLyY{|m-7<8&y0 NN=yx)f""" + + # This should be run last -- some things check for the import + run_order = 10 + + def transform(self, node, results): + new = BlankLine() + new.prefix = node.prefix + return new diff --git a/PythonHome/Lib/lib2to3/fixes/fix_future.pyc b/PythonHome/Lib/lib2to3/fixes/fix_future.pyc deleted file mode 100644 index f8ca6dc2aaba0ba731a4790d9089fcc60e297209..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 888 zcmbVK!EV$r5FIDkKm(O3apGpmVRPC894Qsuik`{}Wmh1gl}vWy2p1=gY=?HGa)OWI zzxV-WoE1gl1d-<1j>qHo-Z=hwnEiPFak+*47vuN}!<{4403{-WIs(n0ji8Kx(K-el zLz_UE;5q>r!PNvB+?c?3fNuaF$`tApmiav@_70(tt@$Fk5Y6BRD}~^y?Tz&=%NlFi zzc+Ye3|Ed@+3RX6YksZ#Cth`2w!PnRtvWf&RD`8-hTt=VM%_p&HkFg(zXSX?*H!oV z60<$6F4WCMAn;o<9iC&jrw9@yGtyJWL4HE=%LzGv!cbJP%wtM^fiMaXME`_OX_)fX z)Pt6yt6KT;_)hFGpN`p6RIuZxir8+cQi4Gu&N19$1Ro6i8pADvD+aeQh=9u=X^~TM z5frC5>#ao5IaTolPUeZ4hE_g9ubsc98xMljd*4*0g=) z)kcrx-kz;iuZu;v#15S>wwAV_f_FUsfowtMJiu^NB4ufm#%Z(|X_6U2)Mkq;aS8>& lAJ1m+N{_};<{TdpK9*4NzqkZjPDUe6Lu<&lG&y2N(Jzjh!V>@h diff --git a/PythonHome/Lib/lib2to3/fixes/fix_getcwdu.py b/PythonHome/Lib/lib2to3/fixes/fix_getcwdu.py new file mode 100644 index 0000000000..82233c8993 --- /dev/null +++ b/PythonHome/Lib/lib2to3/fixes/fix_getcwdu.py @@ -0,0 +1,19 @@ +""" +Fixer that changes os.getcwdu() to os.getcwd(). +""" +# Author: Victor Stinner + +# Local imports +from .. import fixer_base +from ..fixer_util import Name + +class FixGetcwdu(fixer_base.BaseFix): + BM_compatible = True + + PATTERN = """ + power< 'os' trailer< dot='.' name='getcwdu' > any* > + """ + + def transform(self, node, results): + name = results["name"] + name.replace(Name(u"getcwd", prefix=name.prefix)) diff --git a/PythonHome/Lib/lib2to3/fixes/fix_getcwdu.pyc b/PythonHome/Lib/lib2to3/fixes/fix_getcwdu.pyc deleted file mode 100644 index a5d6d6a82ae7506c0f9f60f57b6e66aaca2f1cf4..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 895 zcmbVK!EV$r5FI<&0Ff${BL^glOVS=90oQf~iwYN5RoRsg(Ml$pc-vIYI*J{&mC9-P zDE^BdV8&UszzJc=FEg=c=FRg2KM&#`pT90D*slP;Z*bdp2sJ=~$e`w+8MGV<4vhQ& zbO3D#MTmX~io?|eHh3_B?*Kc1FGU1(1dH?$C3}ewzi)0-FWhD6M0HtiFO(I=W*5p; z*Y%Jd31=Ss^eBrPj!`K?a52J$!sWWOYWx@Czj@gze~7t1jEU|$p}-k#`y4@GCyZzo zf$u7$u8?UlfqaotA)6z_;*ZstYt^5K#Mnf*zHBskwQ;9OmWVCZK27%Y6EPL#_V!pz z|4LDjphR_on>4k@2zQ+7Kl>KIT>w|upqCg`C6~jFu^mHU0rm53IzlQqL}-jP9hqIP zP?wa7I8wS-oh~btQ}a0m`FJ00mEMebOs)2p?Vz2_DLTbHf_;Hjw))ttSGrlha_04l zq_>1}-)`33x+i!IMcLYo>D#C1SgHpsW+^dqj}fFK(o*_2lCm}Rpvk41%YIPq0FBuv zS(&ygU9;9BvGcdf@Z~Y^?oSu}X#uAr^MPbC}einV_Qr4zI9(V@y?!Qmi h;2Q1q^EYQWZ#Y~&-~UnZLY$1PPf6;LQh3M?`7iGjwZs4b diff --git a/PythonHome/Lib/lib2to3/fixes/fix_has_key.py b/PythonHome/Lib/lib2to3/fixes/fix_has_key.py new file mode 100644 index 0000000000..bead4cb51c --- /dev/null +++ b/PythonHome/Lib/lib2to3/fixes/fix_has_key.py @@ -0,0 +1,110 @@ +# Copyright 2006 Google, Inc. All Rights Reserved. +# Licensed to PSF under a Contributor Agreement. + +"""Fixer for has_key(). + +Calls to .has_key() methods are expressed in terms of the 'in' +operator: + + d.has_key(k) -> k in d + +CAVEATS: +1) While the primary target of this fixer is dict.has_key(), the + fixer will change any has_key() method call, regardless of its + class. + +2) Cases like this will not be converted: + + m = d.has_key + if m(k): + ... + + Only *calls* to has_key() are converted. While it is possible to + convert the above to something like + + m = d.__contains__ + if m(k): + ... + + this is currently not done. +""" + +# Local imports +from .. import pytree +from ..pgen2 import token +from .. import fixer_base +from ..fixer_util import Name, parenthesize + + +class FixHasKey(fixer_base.BaseFix): + BM_compatible = True + + PATTERN = """ + anchor=power< + before=any+ + trailer< '.' 'has_key' > + trailer< + '(' + ( not(arglist | argument) arg=any ','> + ) + ')' + > + after=any* + > + | + negation=not_test< + 'not' + anchor=power< + before=any+ + trailer< '.' 'has_key' > + trailer< + '(' + ( not(arglist | argument) arg=any ','> + ) + ')' + > + > + > + """ + + def transform(self, node, results): + assert results + syms = self.syms + if (node.parent.type == syms.not_test and + self.pattern.match(node.parent)): + # Don't transform a node matching the first alternative of the + # pattern when its parent matches the second alternative + return None + negation = results.get("negation") + anchor = results["anchor"] + prefix = node.prefix + before = [n.clone() for n in results["before"]] + arg = results["arg"].clone() + after = results.get("after") + if after: + after = [n.clone() for n in after] + if arg.type in (syms.comparison, syms.not_test, syms.and_test, + syms.or_test, syms.test, syms.lambdef, syms.argument): + arg = parenthesize(arg) + if len(before) == 1: + before = before[0] + else: + before = pytree.Node(syms.power, before) + before.prefix = u" " + n_op = Name(u"in", prefix=u" ") + if negation: + n_not = Name(u"not", prefix=u" ") + n_op = pytree.Node(syms.comp_op, (n_not, n_op)) + new = pytree.Node(syms.comparison, (arg, n_op, before)) + if after: + new = parenthesize(new) + new = pytree.Node(syms.power, (new,) + tuple(after)) + if node.parent.type in (syms.comparison, syms.expr, syms.xor_expr, + syms.and_expr, syms.shift_expr, + syms.arith_expr, syms.term, + syms.factor, syms.power): + new = parenthesize(new) + new.prefix = prefix + return new diff --git a/PythonHome/Lib/lib2to3/fixes/fix_has_key.pyc b/PythonHome/Lib/lib2to3/fixes/fix_has_key.pyc deleted file mode 100644 index e8f7f94b29c03434a79852611e0d0b351d687a5e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3153 zcmbtW?`|7K5TCOh|GC6%2&8Q&4NDQ6U5XJ!;zN~0q@h(MAfQX2A}Snb-#R|~{+Qi$ z8zcJ*;T8DCWAK5u;8_qaz|5>;Cr}kZ6Ww@sc6a7Cznh)8;-7W*w@2R{bYS*Z#NUtb z(J_h$;0UDyQ2`PM(gGY6z@d2&k|LxfI4aqBiPx9lXvxl(ASpvyfujnfRXD1mwhVF! z`Zeg{@e2F|a0>ACkqc234jMIb`E~)|L3|>W=;liFLLCg`xY2C6?p~NAT9{n4=30?T z)5{|*LM4Sf87ir@j6|FXBUP$J-W8@Ng%@X@n-8T5O|I^`uE4)&Ze`FE@9u~Jor=)Q z?pODB4-f9T?>EJxUYtm_FjR3GsY$IJ~jZ_^p_V%ML>Ng_JE zFguna%*KnLX7EJ^BfBk>JPuWqU_0Q;qV+*rRFIU^c z{Hau1tReQ>64P65V>-Mu*BKRJzNszYwLIa?-h(H0{;^@MAWL4uyD)DMMGef;B-Tbu z@M;{7QjBhkQqSA=CAIqb^KbP`|Ss7oKI~SD3nxp_|$n?ByAF3SouE zb(WV{US_!p-3koKpsqURB|1wH)X0umgGrU9*tsbD4;`Fh=h{H1**ch)q5le-Sm%8O z3ITf=ZVGB(u0T|Sh`ZaV<4h4s3DhqR>6g#xk@vZst1v;7%g`;rDOy`*5c5^EfRv!D zLbu2pFc_rd55`?*-1T$T5LKOet+__qFpR5Yw9X8jf47#T4UXhhme*On#_|TsO_r~- zT!(Ir342%|!pd1?Hi>v4(OI%Z;JJ%_SnHdP|=l zFrtwdQPGYwTj`a=YCfVfRO$r&8cOJ0Z2pQW$bF@9#T8zUQ*F<1g=d`^52eL4t23s8 zhlioT%9JsJG&G%_?GV^$7#wzef0-N+!cIbJx<8#f#oiHXY-bc@m_=N<*kZ2im^uxW zGgc;H+Kyz`?w(aDj4;s8Xh?8+PzBsX>fd4rS8iK}LXxEBwqFB}V&o9Q)LJebQQf z=xt>_k>OJ#^~te4eTF#;@U1banS9#7WniIi;;8lb)42UOiQ9Kf{=sAF*_vc9Ylbas z@?;h3d8V;}rVnwVAD{qd#i=>#&U&%rTy|U>zv-;vsO;Qyt~qbuXw9h?)=|HPx;1AL z|I2vhE$2GQ6+C$v*BTTIvls*!ejEe=zvUoE^JtXNl$bhHBWWo1d!ONl3?_h~Pa$UJ zi`~P+`~JTF9 isinstance(x, T) + type(x) is T -> isinstance(x, T) + type(x) != T -> not isinstance(x, T) + type(x) is not T -> not isinstance(x, T) + +* Change "while 1:" into "while True:". + +* Change both + + v = list(EXPR) + v.sort() + foo(v) + +and the more general + + v = EXPR + v.sort() + foo(v) + +into + + v = sorted(EXPR) + foo(v) +""" +# Author: Jacques Frechet, Collin Winter + +# Local imports +from .. import fixer_base +from ..fixer_util import Call, Comma, Name, Node, BlankLine, syms + +CMP = "(n='!=' | '==' | 'is' | n=comp_op< 'is' 'not' >)" +TYPE = "power< 'type' trailer< '(' x=any ')' > >" + +class FixIdioms(fixer_base.BaseFix): + explicit = True # The user must ask for this fixer + + PATTERN = r""" + isinstance=comparison< %s %s T=any > + | + isinstance=comparison< T=any %s %s > + | + while_stmt< 'while' while='1' ':' any+ > + | + sorted=any< + any* + simple_stmt< + expr_stmt< id1=any '=' + power< list='list' trailer< '(' (not arglist) any ')' > > + > + '\n' + > + sort= + simple_stmt< + power< id2=any + trailer< '.' 'sort' > trailer< '(' ')' > + > + '\n' + > + next=any* + > + | + sorted=any< + any* + simple_stmt< expr_stmt< id1=any '=' expr=any > '\n' > + sort= + simple_stmt< + power< id2=any + trailer< '.' 'sort' > trailer< '(' ')' > + > + '\n' + > + next=any* + > + """ % (TYPE, CMP, CMP, TYPE) + + def match(self, node): + r = super(FixIdioms, self).match(node) + # If we've matched one of the sort/sorted subpatterns above, we + # want to reject matches where the initial assignment and the + # subsequent .sort() call involve different identifiers. + if r and "sorted" in r: + if r["id1"] == r["id2"]: + return r + return None + return r + + def transform(self, node, results): + if "isinstance" in results: + return self.transform_isinstance(node, results) + elif "while" in results: + return self.transform_while(node, results) + elif "sorted" in results: + return self.transform_sort(node, results) + else: + raise RuntimeError("Invalid match") + + def transform_isinstance(self, node, results): + x = results["x"].clone() # The thing inside of type() + T = results["T"].clone() # The type being compared against + x.prefix = u"" + T.prefix = u" " + test = Call(Name(u"isinstance"), [x, Comma(), T]) + if "n" in results: + test.prefix = u" " + test = Node(syms.not_test, [Name(u"not"), test]) + test.prefix = node.prefix + return test + + def transform_while(self, node, results): + one = results["while"] + one.replace(Name(u"True", prefix=one.prefix)) + + def transform_sort(self, node, results): + sort_stmt = results["sort"] + next_stmt = results["next"] + list_call = results.get("list") + simple_expr = results.get("expr") + + if list_call: + list_call.replace(Name(u"sorted", prefix=list_call.prefix)) + elif simple_expr: + new = simple_expr.clone() + new.prefix = u"" + simple_expr.replace(Call(Name(u"sorted"), [new], + prefix=simple_expr.prefix)) + else: + raise RuntimeError("should not have reached here") + sort_stmt.remove() + + btwn = sort_stmt.prefix + # Keep any prefix lines between the sort_stmt and the list_call and + # shove them right after the sorted() call. + if u"\n" in btwn: + if next_stmt: + # The new prefix should be everything from the sort_stmt's + # prefix up to the last newline, then the old prefix after a new + # line. + prefix_lines = (btwn.rpartition(u"\n")[0], next_stmt[0].prefix) + next_stmt[0].prefix = u"\n".join(prefix_lines) + else: + assert list_call.parent + assert list_call.next_sibling is None + # Put a blank line after list_call and set its prefix. + end_line = BlankLine() + list_call.parent.append_child(end_line) + assert list_call.next_sibling is end_line + # The new prefix should be everything up to the first new line + # of sort_stmt's prefix. + end_line.prefix = btwn.rpartition(u"\n")[0] diff --git a/PythonHome/Lib/lib2to3/fixes/fix_idioms.pyc b/PythonHome/Lib/lib2to3/fixes/fix_idioms.pyc deleted file mode 100644 index dcfe1b6f7d2e510d6ee4cef31dbe2ecad5d872fc..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4432 zcmds4-EJGl6+X*faV1wm61!28qGJOADJKKAl=lx=_B-_?@{zw`WAhGe&1P2Bn795b6H9|J3r@~IX~YyGh6-7J^!EI{OM>Q zvtJeO-{5fxnnY*-ijnG z>9s%&B3~j9txD7oTanS4oI*rX{wnfTr?sdm_)G(bN^jWr;P}I5LNq z#V||FQxivVmN-*nrWo2dH%S)RJT-%Cnie*n^z*`P`~G9IKkTPxwiHlYPAn)Ati~=& zl{WY3ku$?V4=#R&4$2a(qwsWy%x?OW@e!gcG=q|o6$6HH8vHKoG4`-6ntoTl8 zq|t5PNjx{}(VJmBw&uysBNM0a#cX_>Pwmd5Mf*>(V(6>R=ca4Mu`4<+{&*OaW}I)k zEH66c;55rR=UcwtPb0b(j?Jw(v#HJdVOI_x)6mFx1{bpOl6-2p%AWPw+ zIgKxD9-j1_?KC)7L$i;76m@p8BV`KY=56+6FHA+`Nmm1OXM=z14ySVB+!8go~5O*p{0tEf`}jCi!gl zIC@fsquahiM4_|aESN-lx6SrWL_5r`etyQKU249!MSX5!d`Ixys#1LWRl2O zC4M@s!Q4~j7T`nM|Ihq5VA12r%4Z*s`z@LR|DIgo5X6~Skt_Y6i%q_&viTb8&pCG#i5&6WsX^R9!3tUiso+LPm)ZNN5@=0z(}~T4CbwtZLVXztKRv~ds7+kW+ReDZ1>pFAzHU%p};cWlG*jNYDH25X@D zJs!u7cpuk3@ILZt_#1GWn`fUCFl52tPwAAA&?B%8-Z_Hx=+PO!(lsp1*Qz&b$GWDT zobkba)Ks|jFSu~PSsmJZpeN6~8mc3-q6I5d<{p}_()0c}j*R-J^xj99M&hOJG|Q84 zfqi{xK?M~*TAE`}3VI>HMI}z`i#*SAb#_3)KqW9HxpmWVp@-7@xLOaUTitMF6Gyq? zt$7h|mY>^}nM7M*(S@@b+7gYjq`|HXGLnxT~s!a9>TXYU~shpu<_cSFXAMpQEPoHkG$7XBu6wq#EoI1S&DwqYh(npwPR}_IQd3 znG%a;>Z4r<0VmUGm2Flirv`N}&Tv7X&6C^$oB`BcMRZ zpu>Sxn8IFFu5nju$<>NhqTB=M^QMR4Naw*5`KZ!J8oWS$igduGt|cQdwJ3A8295p< zcIfYmd*BtTx*3LR1jy?Zai7m7QAn`;wXeqdGFq1_pMsQmjRR7@yb*C%6`#fE#uUZIBlb8B+j9}I0|hBmjF znSKl^>1?1;6rI^3Fc{1M7f?=_h!04`y>gpm=T^(Ie#ON_oTaMHD8pw3N$~k*(?aX& zGv{nh3N52rS7}G+;*)Wlo&~Jm0aHkq`jd%Gqi}$4rbu0I7wr1k35Vz9M|#hX<3D=SS1O;Ac$R=7Jy@10HeX#%(8hYhpI_tw4j zO2hk^*U*~riMLT%^ZZJyy5==%#@no{d-p3X)Rp_y4v!n%KMYfRJ%ypVHw^L3JjGQz zRIOPdN+mBQ<9HC47&v};_(F}_|J`B1s&V-2`1nO|peK6pF($N@1x)vVTFy;-pK3wL zpW)H7s^K--4=SzImfu=y)ebs5zjW^~jIsgL#aIG13*U{?A|97e(sHhaov_yEYhe$5 p&EXE&xZQJnXyOA-?>|3CX?50a>BGHGAkpz8YScEoZ3L!K`7ac$mqq{p diff --git a/PythonHome/Lib/lib2to3/fixes/fix_import.py b/PythonHome/Lib/lib2to3/fixes/fix_import.py new file mode 100644 index 0000000000..88e9d10334 --- /dev/null +++ b/PythonHome/Lib/lib2to3/fixes/fix_import.py @@ -0,0 +1,99 @@ +"""Fixer for import statements. +If spam is being imported from the local directory, this import: + from spam import eggs +Becomes: + from .spam import eggs + +And this import: + import spam +Becomes: + from . import spam +""" + +# Local imports +from .. import fixer_base +from os.path import dirname, join, exists, sep +from ..fixer_util import FromImport, syms, token + + +def traverse_imports(names): + """ + Walks over all the names imported in a dotted_as_names node. + """ + pending = [names] + while pending: + node = pending.pop() + if node.type == token.NAME: + yield node.value + elif node.type == syms.dotted_name: + yield "".join([ch.value for ch in node.children]) + elif node.type == syms.dotted_as_name: + pending.append(node.children[0]) + elif node.type == syms.dotted_as_names: + pending.extend(node.children[::-2]) + else: + raise AssertionError("unknown node type") + + +class FixImport(fixer_base.BaseFix): + BM_compatible = True + + PATTERN = """ + import_from< 'from' imp=any 'import' ['('] any [')'] > + | + import_name< 'import' imp=any > + """ + + def start_tree(self, tree, name): + super(FixImport, self).start_tree(tree, name) + self.skip = "absolute_import" in tree.future_features + + def transform(self, node, results): + if self.skip: + return + imp = results['imp'] + + if node.type == syms.import_from: + # Some imps are top-level (eg: 'import ham') + # some are first level (eg: 'import ham.eggs') + # some are third level (eg: 'import ham.eggs as spam') + # Hence, the loop + while not hasattr(imp, 'value'): + imp = imp.children[0] + if self.probably_a_local_import(imp.value): + imp.value = u"." + imp.value + imp.changed() + else: + have_local = False + have_absolute = False + for mod_name in traverse_imports(imp): + if self.probably_a_local_import(mod_name): + have_local = True + else: + have_absolute = True + if have_absolute: + if have_local: + # We won't handle both sibling and absolute imports in the + # same statement at the moment. + self.warning(node, "absolute and local imports together") + return + + new = FromImport(u".", [imp]) + new.prefix = node.prefix + return new + + def probably_a_local_import(self, imp_name): + if imp_name.startswith(u"."): + # Relative imports are certainly not local imports. + return False + imp_name = imp_name.split(u".", 1)[0] + base_path = dirname(self.filename) + base_path = join(base_path, imp_name) + # If there is no __init__.py next to the file its not in a package + # so can't be a relative import. + if not exists(join(dirname(base_path), "__init__.py")): + return False + for ext in [".py", sep, ".pyc", ".so", ".sl", ".pyd"]: + if exists(base_path + ext): + return True + return False diff --git a/PythonHome/Lib/lib2to3/fixes/fix_import.pyc b/PythonHome/Lib/lib2to3/fixes/fix_import.pyc deleted file mode 100644 index 6bde2782f45d68dcd4499c7f8a7963c6f2d748e3..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3163 zcmbVOTW=dh6h33GuSuIUks1OOUCPAz<18tO-p&8SlYAWnKNh3r~|1eEK#f|DN(0HDlAjzP+X?Op^igIg*p{Vs?@1cQlm}{8rV^xxK2rf zIt@yi)M-*OL!B9{Rp|lD&Qe$-U80>+)Q5JRCy$9f>zt;rK^yHR`|uEAEjrM-+s|@0 zN`_f(U1I~Q6P;SK(!AMs%`iyZ$hch{rGtr%4&8p9C9d7pZk+Xk*bSpx_iUCQUc@A{ z3tR6rUHn9~FjJhM2Lsc*rh8eU&0{JnPw6yQ)9`6~Q$OL@zgc+{2d_sZgxFRPmLu+S zuzoi%I{FL0w!;fG2>71{iMBkklSQemVxSKqV~ypK89i+CTdb@h_L~xl=$pgD*a|OZ zyE^UhVQhwHdU(w55M!c&q9a8IztC7w{wvEJDalcZ#;B7b3t6V!66Np8j6Rd%#x^$AT74@)R9F zQIxuY8)nw(&<~7XtfpD0SHysYC5l+AM}MMT<_w0TbT`fRQ&zCb1#TT+G8K>48-JIKGb8F*g8aSJBq^`=x3u(dM20%hC`i(cJ8TF zGl7idW!}7MjLvP8r8n|C%L}M6CL~A!9a}vxLVj*#_3o`~{F1 zsPbdQ3u*jIK)I$08>NIAJg_-7z&$X!f`(r_Tpd#{nFxxap43 zA?PoROFU-g;1VYcdf0k>>lHeZ#IwPwSo@Ki5!!p-$)Li6 z&2feD-)QVm{!l^z5y_RuB}~zm2#Wbf+yJj)`UqYixYIPQkuP$CwSG-4sVBnyRiB}b{=e^x{akAQtrgKvoB zGR`m;Aqb@7sAg%QvY^g@aOTx~sj8}KQO&7Fsfkgwyr`Vg0;s9S?Z zsZm{EZjt+WgQo<`1y}{6fHQCnh&rr@%M_^u;GxQ>z~3s*unqtY5J61_rY|NB-sWoz zxx;r8zL@Z#gwLZv6;OSiFIDVjV`W-mFYfalv9WibHrX5bhFUL>6fvFzS%$9`-;dJB z`aam%l<}Y693bAkV!~vTcRXDP+sw!(MV*nSAGEnKaWD! zl^|2j_T^;Xm#};vU>n8S_r*;CX-T533r3+vL*(lEXsW<5Am=Y#MRZIqc6&XJ^Bz70+?ERpanockji s#nO~Q2=c*EbT4<}H6$9>tGMvLoR|DvDKd7IK~)4%o>v#txpHIiZ$rDKjsO4v diff --git a/PythonHome/Lib/lib2to3/fixes/fix_imports.py b/PythonHome/Lib/lib2to3/fixes/fix_imports.py new file mode 100644 index 0000000000..93c9e6787b --- /dev/null +++ b/PythonHome/Lib/lib2to3/fixes/fix_imports.py @@ -0,0 +1,145 @@ +"""Fix incompatible imports and module references.""" +# Authors: Collin Winter, Nick Edds + +# Local imports +from .. import fixer_base +from ..fixer_util import Name, attr_chain + +MAPPING = {'StringIO': 'io', + 'cStringIO': 'io', + 'cPickle': 'pickle', + '__builtin__' : 'builtins', + 'copy_reg': 'copyreg', + 'Queue': 'queue', + 'SocketServer': 'socketserver', + 'ConfigParser': 'configparser', + 'repr': 'reprlib', + 'FileDialog': 'tkinter.filedialog', + 'tkFileDialog': 'tkinter.filedialog', + 'SimpleDialog': 'tkinter.simpledialog', + 'tkSimpleDialog': 'tkinter.simpledialog', + 'tkColorChooser': 'tkinter.colorchooser', + 'tkCommonDialog': 'tkinter.commondialog', + 'Dialog': 'tkinter.dialog', + 'Tkdnd': 'tkinter.dnd', + 'tkFont': 'tkinter.font', + 'tkMessageBox': 'tkinter.messagebox', + 'ScrolledText': 'tkinter.scrolledtext', + 'Tkconstants': 'tkinter.constants', + 'Tix': 'tkinter.tix', + 'ttk': 'tkinter.ttk', + 'Tkinter': 'tkinter', + 'markupbase': '_markupbase', + '_winreg': 'winreg', + 'thread': '_thread', + 'dummy_thread': '_dummy_thread', + # anydbm and whichdb are handled by fix_imports2 + 'dbhash': 'dbm.bsd', + 'dumbdbm': 'dbm.dumb', + 'dbm': 'dbm.ndbm', + 'gdbm': 'dbm.gnu', + 'xmlrpclib': 'xmlrpc.client', + 'DocXMLRPCServer': 'xmlrpc.server', + 'SimpleXMLRPCServer': 'xmlrpc.server', + 'httplib': 'http.client', + 'htmlentitydefs' : 'html.entities', + 'HTMLParser' : 'html.parser', + 'Cookie': 'http.cookies', + 'cookielib': 'http.cookiejar', + 'BaseHTTPServer': 'http.server', + 'SimpleHTTPServer': 'http.server', + 'CGIHTTPServer': 'http.server', + #'test.test_support': 'test.support', + 'commands': 'subprocess', + 'UserString' : 'collections', + 'UserList' : 'collections', + 'urlparse' : 'urllib.parse', + 'robotparser' : 'urllib.robotparser', +} + + +def alternates(members): + return "(" + "|".join(map(repr, members)) + ")" + + +def build_pattern(mapping=MAPPING): + mod_list = ' | '.join(["module_name='%s'" % key for key in mapping]) + bare_names = alternates(mapping.keys()) + + yield """name_import=import_name< 'import' ((%s) | + multiple_imports=dotted_as_names< any* (%s) any* >) > + """ % (mod_list, mod_list) + yield """import_from< 'from' (%s) 'import' ['('] + ( any | import_as_name< any 'as' any > | + import_as_names< any* >) [')'] > + """ % mod_list + yield """import_name< 'import' (dotted_as_name< (%s) 'as' any > | + multiple_imports=dotted_as_names< + any* dotted_as_name< (%s) 'as' any > any* >) > + """ % (mod_list, mod_list) + + # Find usages of module members in code e.g. thread.foo(bar) + yield "power< bare_with_attr=(%s) trailer<'.' any > any* >" % bare_names + + +class FixImports(fixer_base.BaseFix): + + BM_compatible = True + keep_line_order = True + # This is overridden in fix_imports2. + mapping = MAPPING + + # We want to run this fixer late, so fix_import doesn't try to make stdlib + # renames into relative imports. + run_order = 6 + + def build_pattern(self): + return "|".join(build_pattern(self.mapping)) + + def compile_pattern(self): + # We override this, so MAPPING can be pragmatically altered and the + # changes will be reflected in PATTERN. + self.PATTERN = self.build_pattern() + super(FixImports, self).compile_pattern() + + # Don't match the node if it's within another match. + def match(self, node): + match = super(FixImports, self).match + results = match(node) + if results: + # Module usage could be in the trailer of an attribute lookup, so we + # might have nested matches when "bare_with_attr" is present. + if "bare_with_attr" not in results and \ + any(match(obj) for obj in attr_chain(node, "parent")): + return False + return results + return False + + def start_tree(self, tree, filename): + super(FixImports, self).start_tree(tree, filename) + self.replace = {} + + def transform(self, node, results): + import_mod = results.get("module_name") + if import_mod: + mod_name = import_mod.value + new_name = unicode(self.mapping[mod_name]) + import_mod.replace(Name(new_name, prefix=import_mod.prefix)) + if "name_import" in results: + # If it's not a "from x import x, y" or "import x as y" import, + # marked its usage to be replaced. + self.replace[mod_name] = new_name + if "multiple_imports" in results: + # This is a nasty hack to fix multiple imports on a line (e.g., + # "import StringIO, urlparse"). The problem is that I can't + # figure out an easy way to make a pattern recognize the keys of + # MAPPING randomly sprinkled in an import statement. + results = self.match(node) + if results: + self.transform(node, results) + else: + # Replace usage of the module. + bare_name = results["bare_with_attr"][0] + new_name = self.replace.get(bare_name.value) + if new_name: + bare_name.replace(Name(new_name, prefix=bare_name.prefix)) diff --git a/PythonHome/Lib/lib2to3/fixes/fix_imports.pyc b/PythonHome/Lib/lib2to3/fixes/fix_imports.pyc deleted file mode 100644 index 1f50f80f354c50d828d7e789c108519ed89dccdf..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5230 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 GQSc43#e^9E diff --git a/PythonHome/Lib/lib2to3/fixes/fix_input.py b/PythonHome/Lib/lib2to3/fixes/fix_input.py new file mode 100644 index 0000000000..fbf4c72f5c --- /dev/null +++ b/PythonHome/Lib/lib2to3/fixes/fix_input.py @@ -0,0 +1,26 @@ +"""Fixer that changes input(...) into eval(input(...)).""" +# Author: Andre Roberge + +# Local imports +from .. import fixer_base +from ..fixer_util import Call, Name +from .. import patcomp + + +context = patcomp.compile_pattern("power< 'eval' trailer< '(' any ')' > >") + + +class FixInput(fixer_base.BaseFix): + BM_compatible = True + PATTERN = """ + power< 'input' args=trailer< '(' [any] ')' > > + """ + + def transform(self, node, results): + # If we're already wrapped in a eval() call, we're done. + if context.match(node.parent.parent): + return + + new = node.clone() + new.prefix = u"" + return Call(Name(u"eval"), [new], prefix=node.prefix) diff --git a/PythonHome/Lib/lib2to3/fixes/fix_input.pyc b/PythonHome/Lib/lib2to3/fixes/fix_input.pyc deleted file mode 100644 index affdba7317bdb0b44dbacdfe037cf7e2317f60de..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1103 zcmbVL!EVz)5S_Ihw+WP1LLhNK@`<>Y9Drk6K`M}t+6Xz75T`minZAacUZ6!FB zkK(`h0p4sVrJN9!_IY-8Jp1O&*#EIL`2OzGG^byWkM|2Kvj7xCDNs=1krq^WlzJq1 z@00ea3MdVz>QUNTdjl60QW}y_AuTtk=+Tv+bd!pZlt;@x&GGdHeIvRedY=xc*raLP z=Nq2`UY8fDjqD<`QNGCPGi9Q(UUfDejYhjLZ4;@_nT~IqyQ9*>hp__7Xq<)LWcaO2mV}OEaf{RUkCt$z=qF#uUOdTb2gs?$$>$$$(6^1L@GqZn-#0RkW zcunK4k8|!C*V)55#4^VKOSBa9MbHw$d)$Zi5i^>y%V+(+f*~S&k^$Ks*^nEJIC#!n zlQ}Y=D^E;gPCw}Y)UnAjAs)K53W~=pr)9{S+NukSbVL>OU96+BR@G}~uA5pVe4Mau ziR&JxbPX~}&z(^>g>ng7Wjbw*S%Sn|kZ zww&oTzqc<>PF^LG sys.intern(s)""" + +# Local imports +from .. import pytree +from .. import fixer_base +from ..fixer_util import Name, Attr, touch_import + + +class FixIntern(fixer_base.BaseFix): + BM_compatible = True + order = "pre" + + PATTERN = """ + power< 'intern' + trailer< lpar='(' + ( not(arglist | argument) any ','> ) + rpar=')' > + after=any* + > + """ + + def transform(self, node, results): + syms = self.syms + obj = results["obj"].clone() + if obj.type == syms.arglist: + newarglist = obj.clone() + else: + newarglist = pytree.Node(syms.arglist, [obj.clone()]) + after = results["after"] + if after: + after = [n.clone() for n in after] + new = pytree.Node(syms.power, + Attr(Name(u"sys"), Name(u"intern")) + + [pytree.Node(syms.trailer, + [results["lpar"].clone(), + newarglist, + results["rpar"].clone()])] + after) + new.prefix = node.prefix + touch_import(None, u'sys', node) + return new diff --git a/PythonHome/Lib/lib2to3/fixes/fix_intern.pyc b/PythonHome/Lib/lib2to3/fixes/fix_intern.pyc deleted file mode 100644 index f3d5dff5e9736c549b9b60264fb19b44fe212dff..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1574 zcmbVM-;diw5FXo!lk;6^)t9PORk`pG2hl@n->SQa9;FfzM3wIlB04ZmvN@dkN7&t{ zjpRHXPyLJdzxoH1Z)S7XBEbV#@_2S;cfQ$gW*oe`5&ik&uctHGJpsO7;WZh=oM-~+ z(cGufqspg=PadxWSqC%;+`2<$hpH}3x>SWU390JQqz7M@R6xr);gJFd zfe_PSVsKw@gKOc+>8XQb%#~K=J-$(lXVtt``Y0Z_{0CxVJ07d^qGV^e%JuOe`J2;i zflT7Mu}Q8k%EH*VjiIe8RokPy-o%6BL5%Nc7&p`9F|?24Ux$csO#Cj$QG$s77Du9f zF&M?ee+;E1)!`r>eeBK`C>+CoE>`E8F&E4&zhC1u`{1-CS`uvoYJKML?$YC~*mkJx z(9)+C4HM8SpY&6)IB%Eg2VBZ!cejBzi|Yc?r!DLV=hNM7NNq^^EnNUAq~|~1rfrYf z-fsIZKK{F?jQ^^J5dw}~iRgyaUC zvND^>$l+Pp)UMC%W~Fc?#B&u-q3%YZnJd{WeVH;+$^#|4cMa+0N-K;~%Hty_W5iCl zk`7aq3sGv0$4Kb;b!kny4?Sgr#G!a-YpMREjNZI!Gc7XhtLkszbmHaWifqh znE!TVb?Ck8DbeuBahrIto z@+p`16TF7=36W int / unicode -> str conversion. + +eg. isinstance(x, (int, long)) -> isinstance(x, (int, int)) + -> isinstance(x, int) +""" + +from .. import fixer_base +from ..fixer_util import token + + +class FixIsinstance(fixer_base.BaseFix): + BM_compatible = True + PATTERN = """ + power< + 'isinstance' + trailer< '(' arglist< any ',' atom< '(' + args=testlist_gexp< any+ > + ')' > > ')' > + > + """ + + run_order = 6 + + def transform(self, node, results): + names_inserted = set() + testlist = results["args"] + args = testlist.children + new_args = [] + iterator = enumerate(args) + for idx, arg in iterator: + if arg.type == token.NAME and arg.value in names_inserted: + if idx < len(args) - 1 and args[idx + 1].type == token.COMMA: + iterator.next() + continue + else: + new_args.append(arg) + if arg.type == token.NAME: + names_inserted.add(arg.value) + if new_args and new_args[-1].type == token.COMMA: + del new_args[-1] + if len(new_args) == 1: + atom = testlist.parent + new_args[0].prefix = atom.prefix + atom.replace(new_args[0]) + else: + args[:] = new_args + node.changed() diff --git a/PythonHome/Lib/lib2to3/fixes/fix_isinstance.pyc b/PythonHome/Lib/lib2to3/fixes/fix_isinstance.pyc deleted file mode 100644 index b79a0d5298d9c39eb94c930f4432f48dcbd3336d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1807 zcmbVMUvC>l5TCuX&(5_ep&*q=AT2`34upU}eM_Szp-4z1ASbB83OX)#YiFJF-F0`b zbtL<#d2}rWODSHFD52kOQ5P zMOBXFCwo!@&8M;{bynqy1=bmvRV7rduF9P_R%2X$i?%=8mVH=ldly?<-pNfYx2I6q z+KT1!)0W&U*EXMAn+d>A7I%JKoklo zxJtv&7q!Jj9k#iyC>KgKIO&J1{0oSOR#!;!?lnr;y9L?15jvCV0$Q@y?{NhSZQZU+ z%PZO2hQL)*e{`eI5kt*Ba>_bZPR43hdy9|d-i=yst0(vH^Z#DDJkt@tWeoEURtxJ8 z%YKhYo$t9tNb`Ur+g!A0-lB=1MVrP%i-=r6^ESPNq(igcY2KkPfBcos0$Oxwu}1SX znuO$F)27RS%x_*2(LAKf$g^E?os|n@?VU>^^NRU-m$Ud_b7kK3<~ZrlWQ_+wJbOsb zUJ>X#qDjntfkOQILL7%QxwE>KHQ4SUJ%yDK0u(d%`X$%WMTiHJ z-!#g(E|}~>7dd9kt$|S`=Gml9d3$$NtATH4_IA8~^u)3A=V{R>@1uYjOAfz1I@QoTqx5uVX_n9$+IRbQO(KwGBC?Og5DS3Yx?s?v@sGkp(c_9J#9);r8d`ZGFC5eAOl4M%tO~EYZ|I{Gs{Bj%|C0RACQ>XDp z`lNife|q|4aO{DYrc5f6D>GmuxAFYPpa%SwakJPiNF<_e6hy)C5-Qg%N%ATKG;C?W p (map|filter|zip) and + itertools.ifilterfalse --> itertools.filterfalse (bugs 2360-2363) + + imports from itertools are fixed in fix_itertools_import.py + + If itertools is imported as something else (ie: import itertools as it; + it.izip(spam, eggs)) method calls will not get fixed. + """ + +# Local imports +from .. import fixer_base +from ..fixer_util import Name + +class FixItertools(fixer_base.BaseFix): + BM_compatible = True + it_funcs = "('imap'|'ifilter'|'izip'|'izip_longest'|'ifilterfalse')" + PATTERN = """ + power< it='itertools' + trailer< + dot='.' func=%(it_funcs)s > trailer< '(' [any] ')' > > + | + power< func=%(it_funcs)s trailer< '(' [any] ')' > > + """ %(locals()) + + # Needs to be run after fix_(map|zip|filter) + run_order = 6 + + def transform(self, node, results): + prefix = None + func = results['func'][0] + if ('it' in results and + func.value not in (u'ifilterfalse', u'izip_longest')): + dot, it = (results['dot'], results['it']) + # Remove the 'itertools' + prefix = it.prefix + it.remove() + # Replace the node which contains ('.', 'function') with the + # function (to be consistent with the second part of the pattern) + dot.remove() + func.parent.replace(func) + + prefix = prefix or func.prefix + func.replace(Name(func.value[1:], prefix=prefix)) diff --git a/PythonHome/Lib/lib2to3/fixes/fix_itertools.pyc b/PythonHome/Lib/lib2to3/fixes/fix_itertools.pyc deleted file mode 100644 index e82a6c9d24017be4c6fc9c7acee00a38463954b0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1760 zcmbVM{c7As5TBLqboLR)fzW^D5KmomQ81R$8H5 zB~6ea;Jiy;ArIC6`U0I<$#=#rq*Q1}v-9!OeC_&w?TkPD^xN?g`p3ubceuo+=}p&qmcbcA99> ztPFp6@aVxll7q>(gDEOqTf_5O7aL5T)`I64X2xYnOtQvIr1O|o?>c}N`4u;5c&A3k z)NrE-(tg|LG^NZVQ>DdMT&z}RGT{WFGrmlfGW@MnikI5* zm9Sla)6Ubw>PA>xuwx_?dYvp%BRbgtWwR8KZXko@e{os&b-T&`2$y+)L}0ra^>XgJ z)(@!lVo2@0L+wPxh+2;wo^L^X91*_x8c7sVAHz26n?f9B)PEAC%at&8qj#+dC+1J| zb%{`GyQk7`Mg16S^CVmsKfGo`mbOl%Ld$QnyGhF5mBpJZD53NTv-@{Vx zon!f(;B^4Cg?0dEc)qsb^~i0}Fn~R>_hHXFAHsP6Z2)JUgF(ipzOi<=<`4kiAt7Bb zU?o87L-oNScV13y5vTjt2<~NDWOTt8d0>dg5zX1mQs=1-62D++ill95%C4TuPJnZ8 zIRKV2$JR(Uu~dty7C5vK0es%w-6ihVGhGTx<$IH=M#O}KVFT2n&~JoeD?H1kwN&R? zR4QGHnEtxKFhb=Htkjw4?M$Prad0t(8q+Ug$~D5(5py58>FE!0ajN9vq16YcbnFb# z&2@qIgxy9%oQ%@ol~>%wjk$vaSio+w8*G<-;cc_AKW4YRT^2dxEmS8-i6=Hm+<{J# zLT8PlEk$usH^S~9bM!J<>Y_@mTqt45?Q+6h?n>jeVO&l>K0P`4KAyQ?>ZVL|oryZ$ zMUPENj{DDf#nh~uxD1U#fawII9Y649U1_P{Ns{R$#*8e)M6TRUjg`uE!i9H)cNJbt Z4)gy8`VQ3Tr{}#LD{S5-yo!I~Y diff --git a/PythonHome/Lib/lib2to3/fixes/fix_itertools_imports.py b/PythonHome/Lib/lib2to3/fixes/fix_itertools_imports.py new file mode 100644 index 0000000000..28610cfcb9 --- /dev/null +++ b/PythonHome/Lib/lib2to3/fixes/fix_itertools_imports.py @@ -0,0 +1,57 @@ +""" Fixer for imports of itertools.(imap|ifilter|izip|ifilterfalse) """ + +# Local imports +from lib2to3 import fixer_base +from lib2to3.fixer_util import BlankLine, syms, token + + +class FixItertoolsImports(fixer_base.BaseFix): + BM_compatible = True + PATTERN = """ + import_from< 'from' 'itertools' 'import' imports=any > + """ %(locals()) + + def transform(self, node, results): + imports = results['imports'] + if imports.type == syms.import_as_name or not imports.children: + children = [imports] + else: + children = imports.children + for child in children[::2]: + if child.type == token.NAME: + member = child.value + name_node = child + elif child.type == token.STAR: + # Just leave the import as is. + return + else: + assert child.type == syms.import_as_name + name_node = child.children[0] + member_name = name_node.value + if member_name in (u'imap', u'izip', u'ifilter'): + child.value = None + child.remove() + elif member_name in (u'ifilterfalse', u'izip_longest'): + node.changed() + name_node.value = (u'filterfalse' if member_name[1] == u'f' + else u'zip_longest') + + # Make sure the import statement is still sane + children = imports.children[:] or [imports] + remove_comma = True + for child in children: + if remove_comma and child.type == token.COMMA: + child.remove() + else: + remove_comma ^= True + + while children and children[-1].type == token.COMMA: + children.pop().remove() + + # If there are no imports left, just get rid of the entire statement + if (not (imports.children or getattr(imports, 'value', None)) or + imports.parent is None): + p = node.prefix + node = BlankLine() + node.prefix = p + return node diff --git a/PythonHome/Lib/lib2to3/fixes/fix_itertools_imports.pyc b/PythonHome/Lib/lib2to3/fixes/fix_itertools_imports.pyc deleted file mode 100644 index f64c67ae65a22831f810e0fa6e55f1ded0d09332..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1985 zcmbtV&2Jk;6o0ep@7RfxqKcr1`hdtHP=ty&rLAz9RI1cCXl*INO0}%Lv+3IV)tPaL zk$s_X=D&b{fg4xO+!22RLY(2fw~iY)fK(jM^P8FX_501diT!)4@x%G&{V}XQHvWEs zL!Y4t0EQ?91Qx^s5(|bF2%6gv+mMuCSc0Ss!!jfl7*=qv1k!>@6+$#B!`A>W0X`en zAgDm!sZ!uBiq50xN~%tnsZNySnKHVQg`LPqWwI>R2Tqju`63FV7?&2&m(h9>`mvVp zb)rA<;|L688Yn^v=Z$!04UexgJ}#dI)8rnpOED@;N2pX9{goxYiJLI7UC>ou=eF}VDsIufAdscA3?^1Y6Ax$c!)#)f!G%oRj|9XVPV4rp$V8+FttFx%PTfC)m_pq z1uRRD)>o^jU;P4$5`m$w1>e}Pd;Ih#Se9W?=1?V=lqr;&^GXGl6;hT}NDpt=RN3ZR z3e#VCu8a5{ObxygY>mWW3iMu7VS>SGu)sU91=9+sU&$MtJWgLn{9niIhzRwTE`PGNyuf7vRUki4LcI2w?;u(LYmllQzw#HBi3^g1HUL2ACZRvPAM4gx%XF*(a8rZ9M*-p;lV8PDEEP!U3}q zuljkRVB5^tuIQs#lXeT8+o)JTD=*H{OQ}sn4K*VX&giz?w59n?Q))nNs26@bE86bg z({qRXcMT4;Cbz7a=h7u?W)sD#k9_T=ej@Q^0gRtTaiC=C+Se|7C*%428oaG8tj9v_n8WcBFX4 zMuDDAvMAgeXG!8?=VN^i3Sgl>K<(h-Ni@2MqtRWHeRM%jq$cUDA0KaZfe!LH=QGMr zHNMFS@vV<3nrMhU(X{H~EwLl&__t$~tT#mqwI+@h%7(Zt+V(9`!5QvYo7NrihP@}Y z*uF0K)#vl_xOmUwC)@LqESSa8^V~KjGA$HGrvxYWO*D#&(}}Y&KKM-gr`^He#O=9v z(C`(~*MsZQ6{z9RbOkD+Vz;cG!>2(F<9R_g#yUw~@#msSUAbO3AVQTlGf~WE&NsEV hiR5;K|BD{sb)ZE5w^}CeUP0FbI_aWnyDj$YzW^b%vjzYF diff --git a/PythonHome/Lib/lib2to3/fixes/fix_long.py b/PythonHome/Lib/lib2to3/fixes/fix_long.py new file mode 100644 index 0000000000..5dddde0d08 --- /dev/null +++ b/PythonHome/Lib/lib2to3/fixes/fix_long.py @@ -0,0 +1,19 @@ +# Copyright 2006 Google, Inc. All Rights Reserved. +# Licensed to PSF under a Contributor Agreement. + +"""Fixer that turns 'long' into 'int' everywhere. +""" + +# Local imports +from lib2to3 import fixer_base +from lib2to3.fixer_util import is_probably_builtin + + +class FixLong(fixer_base.BaseFix): + BM_compatible = True + PATTERN = "'long'" + + def transform(self, node, results): + if is_probably_builtin(node): + node.value = u"int" + node.changed() diff --git a/PythonHome/Lib/lib2to3/fixes/fix_long.pyc b/PythonHome/Lib/lib2to3/fixes/fix_long.pyc deleted file mode 100644 index 70e572f80f0f07a833e9c1a5b211a3f73d8e7ec6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 810 zcmbVKU2oGc6unN;!m3TG*fS#91I<&B;1wb01W%(vX(dEd$>hUbGdW3RJA+ERjUUDT z;sx)<)IA3fr0uFYaOf$v6>mqS1jzq!|-BW;+ZQdv;y~$EG zUDazIGLy9d#}g!r&$8^AeeUW)50t)qSg${(%altz^7?0TDf@Yh@SMg1U$FE~#d{)U z)s-N@mw7KRMN013), list(<>), +tuple(<>), sorted(<>), ...join(<>), or for V in <>:. + +NOTE: This is still not correct if the original code was depending on +map(F, X, Y, ...) to go on until the longest argument is exhausted, +substituting None for missing values -- like zip(), it now stops as +soon as the shortest argument is exhausted. +""" + +# Local imports +from ..pgen2 import token +from .. import fixer_base +from ..fixer_util import Name, Call, ListComp, in_special_context +from ..pygram import python_symbols as syms + +class FixMap(fixer_base.ConditionalFix): + BM_compatible = True + + PATTERN = """ + map_none=power< + 'map' + trailer< '(' arglist< 'None' ',' arg=any [','] > ')' > + > + | + map_lambda=power< + 'map' + trailer< + '(' + arglist< + lambdef< 'lambda' + (fp=NAME | vfpdef< '(' fp=NAME ')'> ) ':' xp=any + > + ',' + it=any + > + ')' + > + > + | + power< + 'map' trailer< '(' [arglist=any] ')' > + > + """ + + skip_on = 'future_builtins.map' + + def transform(self, node, results): + if self.should_skip(node): + return + + if node.parent.type == syms.simple_stmt: + self.warning(node, "You should use a for loop here") + new = node.clone() + new.prefix = u"" + new = Call(Name(u"list"), [new]) + elif "map_lambda" in results: + new = ListComp(results["xp"].clone(), + results["fp"].clone(), + results["it"].clone()) + else: + if "map_none" in results: + new = results["arg"].clone() + else: + if "arglist" in results: + args = results["arglist"] + if args.type == syms.arglist and \ + args.children[0].type == token.NAME and \ + args.children[0].value == "None": + self.warning(node, "cannot convert map(None, ...) " + "with multiple arguments because map() " + "now truncates to the shortest sequence") + return + if in_special_context(node): + return None + new = node.clone() + new.prefix = u"" + new = Call(Name(u"list"), [new]) + new.prefix = node.prefix + return new diff --git a/PythonHome/Lib/lib2to3/fixes/fix_map.pyc b/PythonHome/Lib/lib2to3/fixes/fix_map.pyc deleted file mode 100644 index 63e0f39e7928de3ddf3b3e84e905b344e8df7b17..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3009 zcmb7G&2k$>5bl*^+1}WRD*=iCMNPp$t13qapg4rYMF`1>7)o|Qq9nDfc1P0KyEDtq ztSwW{feI&Hgje7RIPfN%c>%tjl^h#GRZwYr=clKCzV7MX_FtRfZ{K~tm(t?b#`|+T zwg$NN8X zXaT>>nlXZUV3ckqFrCf+mSx=8xeefVzutdvTP!d{v=r28gVZn;D_$C9Dm7J_V`DNY zjuRLrOQ|!Zr^0BD8xrX8ws^8gBfvE^*h1n!rgtnioNNw(nAS~3SRv;#gbK!PhqfL= zy{nNzQ^7&-rWVRtUO*ITWGZ5nt3xS%Q~+rkIKbFrm~Bb~*oM|XBaHK4&lrXO(l-cI z3pXMPK->xwb0~E)4KbbYEs4j-kEp}DOm>m5esCYbacfxl3isf?DN1)86Q$!t2FDyM zId_e?tJo_~+{|GAq!^prx-OP*4<99Eijn`ZAz$FJAA(4fh=3$2L)({&4wsA33RetV zYm|fGUesphKXEJ+_#taz4bbkE=2%vD{2H(Ku+cl4xhhdPwnZ=MaUA%bW5Q_nL~q-# z-A(j~c#6q$u_Jo@p4jon8+v-CEKiDYmb{+2GyUG8=#@P@Uz%}&i8s6kIe~qRu8YT* z2R^K&1M{RwGtN^}4k(93|T8=OXa zm>l5WBG;ya4js0rnt8qz=0l3TL?dFRF1L;s$h{VwwkcjEWV>7E1_fbQnR-?*==C7$ z&}oYfyHx#3F642xLN^-`Jn5dFtS%=n+bm!I!OdxL{C9tLeaXSwzfk5Svh+^^mKM^@ z7f^^k*LZQodx1TyY*2Our?Ig~2Ujm|T%&Abxe9O^r#HRRjE=@N-&z9pWv~S7wXtB} zRu^~yqrHeP{;qu=^ogm3otZk%1UII{m$uxPQgA=zj{>SYAbcNzArW8aChHxSsd?#N zljfzIFFwmFk6;oZaolS2W+4j0MbX0Dwnzj@6WtVceI%Riyl8d4?H?;Q6Ge>%jxKUm zqU~8Pg)(#{F1D_!b&95rDr+tlT8nlmbt)sShVBYT<8y2eRq1P9i6*R_uc7XwY>Fvr zqHUP*-H^-Jy25!^j+08G^!w_ZqIt+hL?uz1hwSr^p&2r6Lx$RelFn3~LCFvc3jk0T zybRw$hI~hc*FYj3c~h*+Cw`#O+`Q^aT0mhvviL6Wn?Tq`I6|KIunwMmrN+;4HU7w% zkDqbNuuNlsH9*DZPcB^V=8NDnOzfw8KDZWiT5kqh!A7tiybHP&YzA+&Hi8>?!r*#v zGk7c5YOi9a<9Xf&jX1d8!#L&-r#SX`632zfYM>T-8~3YPBKgrt9-#*nB|byOdE?SI z_xAT640pYI9FN%Op#bMAmtNPeA)E3Z9=it84Z81iTiw=f#Grcdah#bH7BRr(RO*kK zU|>c=-)~ (metaclass=X) methods. + + The various forms of classef (inherits nothing, inherits once, inherints + many) don't parse the same in the CST so we look at ALL classes for + a __metaclass__ and if we find one normalize the inherits to all be + an arglist. + + For one-liner classes ('class X: pass') there is no indent/dedent so + we normalize those into having a suite. + + Moving the __metaclass__ into the classdef can also cause the class + body to be empty so there is some special casing for that as well. + + This fixer also tries very hard to keep original indenting and spacing + in all those corner cases. + +""" +# Author: Jack Diederich + +# Local imports +from .. import fixer_base +from ..pygram import token +from ..fixer_util import Name, syms, Node, Leaf + + +def has_metaclass(parent): + """ we have to check the cls_node without changing it. + There are two possiblities: + 1) clsdef => suite => simple_stmt => expr_stmt => Leaf('__meta') + 2) clsdef => simple_stmt => expr_stmt => Leaf('__meta') + """ + for node in parent.children: + if node.type == syms.suite: + return has_metaclass(node) + elif node.type == syms.simple_stmt and node.children: + expr_node = node.children[0] + if expr_node.type == syms.expr_stmt and expr_node.children: + left_side = expr_node.children[0] + if isinstance(left_side, Leaf) and \ + left_side.value == '__metaclass__': + return True + return False + + +def fixup_parse_tree(cls_node): + """ one-line classes don't get a suite in the parse tree so we add + one to normalize the tree + """ + for node in cls_node.children: + if node.type == syms.suite: + # already in the preferred format, do nothing + return + + # !%@#! oneliners have no suite node, we have to fake one up + for i, node in enumerate(cls_node.children): + if node.type == token.COLON: + break + else: + raise ValueError("No class suite and no ':'!") + + # move everything into a suite node + suite = Node(syms.suite, []) + while cls_node.children[i+1:]: + move_node = cls_node.children[i+1] + suite.append_child(move_node.clone()) + move_node.remove() + cls_node.append_child(suite) + node = suite + + +def fixup_simple_stmt(parent, i, stmt_node): + """ if there is a semi-colon all the parts count as part of the same + simple_stmt. We just want the __metaclass__ part so we move + everything after the semi-colon into its own simple_stmt node + """ + for semi_ind, node in enumerate(stmt_node.children): + if node.type == token.SEMI: # *sigh* + break + else: + return + + node.remove() # kill the semicolon + new_expr = Node(syms.expr_stmt, []) + new_stmt = Node(syms.simple_stmt, [new_expr]) + while stmt_node.children[semi_ind:]: + move_node = stmt_node.children[semi_ind] + new_expr.append_child(move_node.clone()) + move_node.remove() + parent.insert_child(i, new_stmt) + new_leaf1 = new_stmt.children[0].children[0] + old_leaf1 = stmt_node.children[0].children[0] + new_leaf1.prefix = old_leaf1.prefix + + +def remove_trailing_newline(node): + if node.children and node.children[-1].type == token.NEWLINE: + node.children[-1].remove() + + +def find_metas(cls_node): + # find the suite node (Mmm, sweet nodes) + for node in cls_node.children: + if node.type == syms.suite: + break + else: + raise ValueError("No class suite!") + + # look for simple_stmt[ expr_stmt[ Leaf('__metaclass__') ] ] + for i, simple_node in list(enumerate(node.children)): + if simple_node.type == syms.simple_stmt and simple_node.children: + expr_node = simple_node.children[0] + if expr_node.type == syms.expr_stmt and expr_node.children: + # Check if the expr_node is a simple assignment. + left_node = expr_node.children[0] + if isinstance(left_node, Leaf) and \ + left_node.value == u'__metaclass__': + # We found a assignment to __metaclass__. + fixup_simple_stmt(node, i, simple_node) + remove_trailing_newline(simple_node) + yield (node, i, simple_node) + + +def fixup_indent(suite): + """ If an INDENT is followed by a thing with a prefix then nuke the prefix + Otherwise we get in trouble when removing __metaclass__ at suite start + """ + kids = suite.children[::-1] + # find the first indent + while kids: + node = kids.pop() + if node.type == token.INDENT: + break + + # find the first Leaf + while kids: + node = kids.pop() + if isinstance(node, Leaf) and node.type != token.DEDENT: + if node.prefix: + node.prefix = u'' + return + else: + kids.extend(node.children[::-1]) + + +class FixMetaclass(fixer_base.BaseFix): + BM_compatible = True + + PATTERN = """ + classdef + """ + + def transform(self, node, results): + if not has_metaclass(node): + return + + fixup_parse_tree(node) + + # find metaclasses, keep the last one + last_metaclass = None + for suite, i, stmt in find_metas(node): + last_metaclass = stmt + stmt.remove() + + text_type = node.children[0].type # always Leaf(nnn, 'class') + + # figure out what kind of classdef we have + if len(node.children) == 7: + # Node(classdef, ['class', 'name', '(', arglist, ')', ':', suite]) + # 0 1 2 3 4 5 6 + if node.children[3].type == syms.arglist: + arglist = node.children[3] + # Node(classdef, ['class', 'name', '(', 'Parent', ')', ':', suite]) + else: + parent = node.children[3].clone() + arglist = Node(syms.arglist, [parent]) + node.set_child(3, arglist) + elif len(node.children) == 6: + # Node(classdef, ['class', 'name', '(', ')', ':', suite]) + # 0 1 2 3 4 5 + arglist = Node(syms.arglist, []) + node.insert_child(3, arglist) + elif len(node.children) == 4: + # Node(classdef, ['class', 'name', ':', suite]) + # 0 1 2 3 + arglist = Node(syms.arglist, []) + node.insert_child(2, Leaf(token.RPAR, u')')) + node.insert_child(2, arglist) + node.insert_child(2, Leaf(token.LPAR, u'(')) + else: + raise ValueError("Unexpected class definition") + + # now stick the metaclass in the arglist + meta_txt = last_metaclass.children[0].children[0] + meta_txt.value = 'metaclass' + orig_meta_prefix = meta_txt.prefix + + if arglist.children: + arglist.append_child(Leaf(token.COMMA, u',')) + meta_txt.prefix = u' ' + else: + meta_txt.prefix = u'' + + # compact the expression "metaclass = Meta" -> "metaclass=Meta" + expr_stmt = last_metaclass.children[0] + assert expr_stmt.type == syms.expr_stmt + expr_stmt.children[1].prefix = u'' + expr_stmt.children[2].prefix = u'' + + arglist.append_child(last_metaclass) + + fixup_indent(suite) + + # check for empty suite + if not suite.children: + # one-liner that was just __metaclass_ + suite.remove() + pass_leaf = Leaf(text_type, u'pass') + pass_leaf.prefix = orig_meta_prefix + node.append_child(pass_leaf) + node.append_child(Leaf(token.NEWLINE, u'\n')) + + elif len(suite.children) > 1 and \ + (suite.children[-2].type == token.INDENT and + suite.children[-1].type == token.DEDENT): + # there was only one line in the class body and it was __metaclass__ + pass_leaf = Leaf(text_type, u'pass') + suite.insert_child(-1, pass_leaf) + suite.insert_child(-1, Leaf(token.NEWLINE, u'\n')) diff --git a/PythonHome/Lib/lib2to3/fixes/fix_metaclass.pyc b/PythonHome/Lib/lib2to3/fixes/fix_metaclass.pyc deleted file mode 100644 index 7463ff4a0af5758d53ad8eacfbc59d310eb62df4..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6469 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 method.__?__). +""" +# Author: Christian Heimes + +# Local imports +from .. import fixer_base +from ..fixer_util import Name + +MAP = { + "im_func" : "__func__", + "im_self" : "__self__", + "im_class" : "__self__.__class__" + } + +class FixMethodattrs(fixer_base.BaseFix): + BM_compatible = True + PATTERN = """ + power< any+ trailer< '.' attr=('im_func' | 'im_self' | 'im_class') > any* > + """ + + def transform(self, node, results): + attr = results["attr"][0] + new = unicode(MAP[attr.value]) + attr.replace(Name(new, prefix=attr.prefix)) diff --git a/PythonHome/Lib/lib2to3/fixes/fix_methodattrs.pyc b/PythonHome/Lib/lib2to3/fixes/fix_methodattrs.pyc deleted file mode 100644 index 30fe38e207254066bfba4ca034a53b50369bd239..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1107 zcmbVLO>fgc5S_IXr%h?8Kpc8N@`<=0awt+Sl#~|1iA0rCgor8@$GZ`({1JKAw3XUZ z`BD5Y{s3>*fpP^~`*vo>JNx#{*#EiN|MBt5G^N$!V}6ZcJ_8id3@Au>lnW|6nt3GH z_bK{;W%?PuipNfEL)ZLEnjPi9XGGr0&r)+T?Ry z0^Vhp;k;@}6&BiltyGv;TW9meY7<87(l9IJVfcKs`eG>Mp_IGBe&%6+BmlM#SY(&F zmh;5ucCCZ8NrDt>Fr-{GWh$lZ!9hOuRso~)#a)0s^T6$B12`_t6JziRC&FIm+ATOB zKX$B{wD}_>Q#!^lj{zD&3YKC9tzbhg!D>LFcpC8)%m+X}#Ivj}bbSye<<+y$)=8GL zHy93_D6gWyiufSB4%udczimfqup5qe_tS9X@}*qT?rOZ@qmBUA9#hysVRvqPvXD>E zwNK~pZw1|SoPz)ikoBG0rCT8o6}ZAQa?&DB3lUoyW4P3rbUqrCUfq4RJc=kS< zpXJ$n&sHzaxE&0mY`e&nXt=zxd=kVh&7!J{M{o@DC9x$Qik3Q`A!Ui)LD9Ljq%11c zi@=Od8_CK2RP9&ehGA{OZxwuT=yTeI*eS~@*fa%w#ByRiyq#-{|f=a B?aKfF diff --git a/PythonHome/Lib/lib2to3/fixes/fix_ne.py b/PythonHome/Lib/lib2to3/fixes/fix_ne.py new file mode 100644 index 0000000000..7025980b48 --- /dev/null +++ b/PythonHome/Lib/lib2to3/fixes/fix_ne.py @@ -0,0 +1,23 @@ +# Copyright 2006 Google, Inc. All Rights Reserved. +# Licensed to PSF under a Contributor Agreement. + +"""Fixer that turns <> into !=.""" + +# Local imports +from .. import pytree +from ..pgen2 import token +from .. import fixer_base + + +class FixNe(fixer_base.BaseFix): + # This is so simple that we don't need the pattern compiler. + + _accept_type = token.NOTEQUAL + + def match(self, node): + # Override + return node.value == u"<>" + + def transform(self, node, results): + new = pytree.Leaf(token.NOTEQUAL, u"!=", prefix=node.prefix) + return new diff --git a/PythonHome/Lib/lib2to3/fixes/fix_ne.pyc b/PythonHome/Lib/lib2to3/fixes/fix_ne.pyc deleted file mode 100644 index 5844647f913d6236990990457a94ce9751dc72a6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 941 zcmb7CO>fgc5S{fp4ymXF2X25;xcHPqxuy{RWP143Al7RR2@r2dG!YoJm&l^@0b z;tw!yUFZ=t(LT@Y?9RM5v-mpR@1w0vL6vP*%2C>2yx1XL=j0!jl?@HLg1 zs*uvK_d_2aP&yEQKs=ybL>oC6(NCglqEG3NiXkoIdr1CR;LY|sw_|snxv}fo+K#8Q z@wRr&_~>M^4dg(q1Y9JrzjQ5g?+>uqTyWjH2jXs!$*eQW4pB+G;D3UUpf37^op2UOFd|BpF-qrvzv~rl9|~M4+WB@|1R@0CMF*VDZmE6E%8q@^g}BG% z#v650a4Z|-!9EddvYKz#t8%+OcFl_wL|CAyc_M`={!k2yG8E)m5NQ$gw4RCK zh<1vc7uC-SL_@j`)DKNpTDam~&-Lh}?`X?XDn_0}7I}_y&Nhi}I)=1(`~LO252y14 zPK>IFKaPR8p+L*FE1h*nUh}s*sT(0lo7HyHwACYVEDDf%s$!&esA)`{RcwsIjE$+9 zqASJq3={0R`v_!t&U next(it), per PEP 3114.""" +# Author: Collin Winter + +# Things that currently aren't covered: +# - listcomp "next" names aren't warned +# - "with" statement targets aren't checked + +# Local imports +from ..pgen2 import token +from ..pygram import python_symbols as syms +from .. import fixer_base +from ..fixer_util import Name, Call, find_binding + +bind_warning = "Calls to builtin next() possibly shadowed by global binding" + + +class FixNext(fixer_base.BaseFix): + BM_compatible = True + PATTERN = """ + power< base=any+ trailer< '.' attr='next' > trailer< '(' ')' > > + | + power< head=any+ trailer< '.' attr='next' > not trailer< '(' ')' > > + | + classdef< 'class' any+ ':' + suite< any* + funcdef< 'def' + name='next' + parameters< '(' NAME ')' > any+ > + any* > > + | + global=global_stmt< 'global' any* 'next' any* > + """ + + order = "pre" # Pre-order tree traversal + + def start_tree(self, tree, filename): + super(FixNext, self).start_tree(tree, filename) + + n = find_binding(u'next', tree) + if n: + self.warning(n, bind_warning) + self.shadowed_next = True + else: + self.shadowed_next = False + + def transform(self, node, results): + assert results + + base = results.get("base") + attr = results.get("attr") + name = results.get("name") + + if base: + if self.shadowed_next: + attr.replace(Name(u"__next__", prefix=attr.prefix)) + else: + base = [n.clone() for n in base] + base[0].prefix = u"" + node.replace(Call(Name(u"next", prefix=node.prefix), base)) + elif name: + n = Name(u"__next__", prefix=name.prefix) + name.replace(n) + elif attr: + # We don't do this transformation if we're assigning to "x.next". + # Unfortunately, it doesn't seem possible to do this in PATTERN, + # so it's being done here. + if is_assign_target(node): + head = results["head"] + if "".join([str(n) for n in head]).strip() == u'__builtin__': + self.warning(node, bind_warning) + return + attr.replace(Name(u"__next__")) + elif "global" in results: + self.warning(node, bind_warning) + self.shadowed_next = True + + +### The following functions help test if node is part of an assignment +### target. + +def is_assign_target(node): + assign = find_assign(node) + if assign is None: + return False + + for child in assign.children: + if child.type == token.EQUAL: + return False + elif is_subtree(child, node): + return True + return False + +def find_assign(node): + if node.type == syms.expr_stmt: + return node + if node.type == syms.simple_stmt or node.parent is None: + return None + return find_assign(node.parent) + +def is_subtree(root, node): + if root == node: + return True + return any(is_subtree(c, node) for c in root.children) diff --git a/PythonHome/Lib/lib2to3/fixes/fix_next.pyc b/PythonHome/Lib/lib2to3/fixes/fix_next.pyc deleted file mode 100644 index d0be9925a116c858f73049ff915fe2f01004516a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3435 zcmb7G?QYyu5S{DYc(X~`gaU<16*U!Vwgm#Tm5}-o^(z&ic2&HEidBp8uAS6duf6rX zt0q$V2M{3f173o6KtkdfcnV&C7vP-nri}^`VH1z<=iHeyXXd)`*P(@9?|s!9%Iw#` z`wAZWGejcNhcuFSk{cO&()Yx$-;lf^V8vlU&bxzx9a|!PivLp-ISdnB=8!t(+B)!fdTDAsp zGuuw9V6&`(%&isaw(Fb@-dzv0mATXJ1QSf(*|-y&`{0A~Yng{F9RuO!D9T4^QFjlc zJK1p$%ObKn<3X9*dVB%nn>-^L#5U~^71xC5#^Y2Q*W)~QOS-B^qCr+9S+Qj=Vt_L? zaAh!EFv`f8Xo%& zL<)3_qzFVqqtj$`5CjB>!1;^}8!ZWY9U5$Z$Nq%?zX{H)E(P@Ga$M}Z9k?paat^Jo ztp>4k)#X*b+{0Bl{**I^>%%<@-7wdk@0l z-^eaf$di#LyJ&lC8*BqN&`0NKLv|ZdeZqC4Cfi5^UF35pYDv)+H$Q79f>dM5bf-K{ zld8?5m^^lh)CzrenIzW5m5W@JrlF=58T=%!3S@((2bmr14N%+NYMMID<5?O+)UT>< z#yN70i!{Y-nr~`@+F=|sGEW&bI1IBo5Te4KKx^&(t!!{V&jx2*dG0=w*HWtbwaHFM z58lFKnYCh$dCSH(D`v@4T&bQ;DXu?3KTyOBVIzpualt!Th(pnSQ1)6oYp|f)e z^lu8ZC)JkhHf033k*N5`EV_W+807V-sUbHW9FeC8g)bwYweU+%9v3_c^%B#l zm&YRPHL9wm+U8XoMpPRXA)M4%{2{w@QvJE_$hp}fo`5#EfJ3;dU%H= z9j86=rTXz78{J_gqbD;BTKc<62Uaj`ux4q4oR~6#kw!a;97BneLHws^Nk;LE%({og z3(>{!B19C;s`YGdosykpOu-V7tJbEK%gSP-s>(_;aw~Nqd8|ddN+)?dOv45S!lN8z zHVpH!NJAy`3c8t%Q0TI)B0|z&yV@}-vqJS*IHL*Xs%#Q6w?bMLlCB*(7pgVXR+LFP zJJwEfXTz5{{R+ja6h|mtgV5|yagY>on&eenSX`{*HSE{BR*)mh27jJ!+UA6J!W=Rk z2L{7R-6`vT2&5W(gx|s%9&Kfw%xr`VvLsGMVP+szX`kTL02x?C zkzmevXI)I!*>uSgl|B_r+6%>1Oni%>8+R}2=lU;H;N!pjaSPw(-ZKyid`MXSCj#6|S}1o!J%1D459u)lJFcJOU$9@!7F4S*=VQ~T>9KR)~~%iUZ&Z=K4{gf zlNdk9scJtWFP3a2! __bool__ methods.""" +# Author: Collin Winter + +# Local imports +from .. import fixer_base +from ..fixer_util import Name, syms + +class FixNonzero(fixer_base.BaseFix): + BM_compatible = True + PATTERN = """ + classdef< 'class' any+ ':' + suite< any* + funcdef< 'def' name='__nonzero__' + parameters< '(' NAME ')' > any+ > + any* > > + """ + + def transform(self, node, results): + name = results["name"] + new = Name(u"__bool__", prefix=name.prefix) + name.replace(new) diff --git a/PythonHome/Lib/lib2to3/fixes/fix_nonzero.pyc b/PythonHome/Lib/lib2to3/fixes/fix_nonzero.pyc deleted file mode 100644 index 93ce354ad1e1d0021e58aa3a956e2a048feb0724..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1055 zcmbVL-HOvd6h4!rtyUI9Q1C(s-XyMAMDLbb+{y}q8zfy2Lm{Tg1heF)WF}~(d$m54 z@8P5P0)A)G>auvF19Rq_IVazI=O^~hgYozG9~UX@mW}fzwt54R5k-)KGK)$IZ zwoM$nPi8PzO;bXzr2f=oYEoDT_XUI=L*)Enyh@bx*`XbXAVDxIYEvl_1^A#x{hbjb z%sJ)(ghWPyiAJ``&f)C96&ZvJ1FU`^Z0usCWujCj^Qr3@)pL`2^Vs!{Jmcn&eyOg| za?0MrYo1*|-qmRj1nIdoXut5TIcL$` zfVuCS9>Q3+5}oq-v5+et@{^j|-^z8Fq|!GR45MV3_ef19cOj}PwF=p*8KRb-eH>(j zdI)W@d|RxRWwCmuo99a&3dM3iOOy3R-$a;hlUiZQsyi?g6C*JecZJWY?pbpJacssW zj;ki?N;diJv$m7^0LuI{PMd0-=wem&6yF`6ot=b1cnjV?)c%EE$cZrnLu)98qoEb} zd|_%3$61qt2W$#iT$%n(7iC{n^9yiQ=lCHo^ak|*_?T);`}}9zvYwZ7TimmL0c^|H A7ytkO diff --git a/PythonHome/Lib/lib2to3/fixes/fix_numliterals.py b/PythonHome/Lib/lib2to3/fixes/fix_numliterals.py new file mode 100644 index 0000000000..b0c23f8041 --- /dev/null +++ b/PythonHome/Lib/lib2to3/fixes/fix_numliterals.py @@ -0,0 +1,28 @@ +"""Fixer that turns 1L into 1, 0755 into 0o755. +""" +# Copyright 2007 Georg Brandl. +# Licensed to PSF under a Contributor Agreement. + +# Local imports +from ..pgen2 import token +from .. import fixer_base +from ..fixer_util import Number + + +class FixNumliterals(fixer_base.BaseFix): + # This is so simple that we don't need the pattern compiler. + + _accept_type = token.NUMBER + + def match(self, node): + # Override + return (node.value.startswith(u"0") or node.value[-1] in u"Ll") + + def transform(self, node, results): + val = node.value + if val[-1] in u'Ll': + val = val[:-1] + elif val.startswith(u'0') and val.isdigit() and len(set(val)) > 1: + val = u"0o" + val[1:] + + return Number(val, prefix=node.prefix) diff --git a/PythonHome/Lib/lib2to3/fixes/fix_numliterals.pyc b/PythonHome/Lib/lib2to3/fixes/fix_numliterals.pyc deleted file mode 100644 index b39e8a0a67c7c298d570ec3477a5839bee6fe687..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1205 zcmbVLO>fgc5S_Ihx2Y(!2ZVaU0;$RYsj=gD}uI

1}e3u z@}u})`~Y~fPAOL!WuIr(GqdyFc>Q0S8$UmNnPjy3`FOs@vJ*f~GzBWkJu-?)kER|e z@qIErl>tqI&JW1+s0?Wu!tap|Xt73f1cvm3=$h#Bbe-}wnhe&Z_;bMf;=67lK1(^` zwyA8iKZ=Tq>uCR3G<iYEiD85vjAk@}jNRTo3Rh2X+_M-pQz#otR>F!1dvYs9^<@>X!B1^1>ZbrktH^Bge||5lj=cvU)mK|;Qyr>p&-Kf4 z4U(ivOPwTc=1Ef4d28UtlHdrAKYloV7qe7I(k#Ev`T~qKVcDL~M+O=F5C#)0k7?%+D&6U4 hasattr(obj, '__call__') +operator.sequenceIncludes(obj) -> operator.contains(obj) +operator.isSequenceType(obj) -> isinstance(obj, collections.Sequence) +operator.isMappingType(obj) -> isinstance(obj, collections.Mapping) +operator.isNumberType(obj) -> isinstance(obj, numbers.Number) +operator.repeat(obj, n) -> operator.mul(obj, n) +operator.irepeat(obj, n) -> operator.imul(obj, n) +""" + +# Local imports +from lib2to3 import fixer_base +from lib2to3.fixer_util import Call, Name, String, touch_import + + +def invocation(s): + def dec(f): + f.invocation = s + return f + return dec + + +class FixOperator(fixer_base.BaseFix): + BM_compatible = True + order = "pre" + + methods = """ + method=('isCallable'|'sequenceIncludes' + |'isSequenceType'|'isMappingType'|'isNumberType' + |'repeat'|'irepeat') + """ + obj = "'(' obj=any ')'" + PATTERN = """ + power< module='operator' + trailer< '.' %(methods)s > trailer< %(obj)s > > + | + power< %(methods)s trailer< %(obj)s > > + """ % dict(methods=methods, obj=obj) + + def transform(self, node, results): + method = self._check_method(node, results) + if method is not None: + return method(node, results) + + @invocation("operator.contains(%s)") + def _sequenceIncludes(self, node, results): + return self._handle_rename(node, results, u"contains") + + @invocation("hasattr(%s, '__call__')") + def _isCallable(self, node, results): + obj = results["obj"] + args = [obj.clone(), String(u", "), String(u"'__call__'")] + return Call(Name(u"hasattr"), args, prefix=node.prefix) + + @invocation("operator.mul(%s)") + def _repeat(self, node, results): + return self._handle_rename(node, results, u"mul") + + @invocation("operator.imul(%s)") + def _irepeat(self, node, results): + return self._handle_rename(node, results, u"imul") + + @invocation("isinstance(%s, collections.Sequence)") + def _isSequenceType(self, node, results): + return self._handle_type2abc(node, results, u"collections", u"Sequence") + + @invocation("isinstance(%s, collections.Mapping)") + def _isMappingType(self, node, results): + return self._handle_type2abc(node, results, u"collections", u"Mapping") + + @invocation("isinstance(%s, numbers.Number)") + def _isNumberType(self, node, results): + return self._handle_type2abc(node, results, u"numbers", u"Number") + + def _handle_rename(self, node, results, name): + method = results["method"][0] + method.value = name + method.changed() + + def _handle_type2abc(self, node, results, module, abc): + touch_import(None, module, node) + obj = results["obj"] + args = [obj.clone(), String(u", " + u".".join([module, abc]))] + return Call(Name(u"isinstance"), args, prefix=node.prefix) + + def _check_method(self, node, results): + method = getattr(self, "_" + results["method"][0].value.encode("ascii")) + if callable(method): + if "module" in results: + return method + else: + sub = (unicode(results["obj"]),) + invocation_str = unicode(method.invocation) % sub + self.warning(node, u"You should use '%s' here." % invocation_str) + return None diff --git a/PythonHome/Lib/lib2to3/fixes/fix_operator.pyc b/PythonHome/Lib/lib2to3/fixes/fix_operator.pyc deleted file mode 100644 index c0f492fa02339343c106601a6a7dda40054597b9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4925 zcmb_g>u%e~6&~v5NO2M;PVBn3WxH!g#%@(0{nH;wuuXaecGWHwV6j3_mL|tG9g0*r zzEFYw=v(wf3iJWm?>j?^vXX6GuVrvNJeqT6&gDDjjN1RYHTc`7zng}t z`n2)?Lpmxi1)FgT+MvnReSSOA=k3xn@~8Kx{q^7K=DN zUKQj14>=Xf1u>IyeyH;cQr;#em1SmZm#;|3^+E@QJ#$*ykP?=bn3qZY^@<(d%D2iE zukywJ#%BcIs$ziQh#vM21EWVB(m2qUGMNN(UGzYi7C8)5Y;r|bh9`bJUu1a^QcSCQ z7@%ew!=E7)QRS#VDfQY>XAUBYizc$XX5mV63&UTOI#bG*aViI!G{=k6&$BRKyjdE# zkD93&;a!<`F^pe)6d%4w;=_kU_M;b6%W(9U##_89c*IDD_sBy|v?aJi7@}{G2KxuKtBG=}x zco|d~qxy%aJISKQqhXU*hG)a|Ofg*Js+iBfRl}TM1m^{a%X@>>uash8#nsj9U~NBh z2PYqnhAxuZ;~;(I4iARr?{8|e$iC3|BX^!fWuhMs>wtW7<022@giD9xp}Rk_Rxk&~ zec~>^+L!!D(v!90oUOfA+pfyFgp`6HsCE_?LAj8)Azt|Z86NXP3;^vZMgY8}&Rgnr zTb)VxzU-^~ea@F(O(SHG3fW8q1!3=pCpvuT+pTQ2$j0CWVoN zWZ5iEA?)%gpwIpDAT=mz^8<1cipsg?Y&zxvX0?09%d)d?4#Wbr6~qEeU#k`XV$a)k zqAQt1mi){k#cd4!NsvZ~_H&&gv5qLuV+?s)9GEz+pb**ob!d!1G&HqpnO%%^8QwP+ zs<5cVq{TNFa?J&K}2|BCdtK=;_YCNC2OXWjU-@# z{Mgn7vF2ryx1?&nNjML&kByDi!1gXNDmkAx$&`oEOEnim-{AKJ>|kAX*>dj@&!6Iv!mgYl`oB%5)7o~non2?d zPEgM6`|Q+u!`; z`SYK76OTQl*udj<9 + [any] + > + > + | + testlist_gexp< any + comp_for< + 'for' NAME 'in' + target=testlist_safe< any (',' any)+ [','] + > + [any] + > + >) + (']' | ')') > + """ + + def transform(self, node, results): + target = results["target"] + + lparen = LParen() + lparen.prefix = target.prefix + target.prefix = u"" # Make it hug the parentheses + target.insert_child(0, lparen) + target.append_child(RParen()) diff --git a/PythonHome/Lib/lib2to3/fixes/fix_paren.pyc b/PythonHome/Lib/lib2to3/fixes/fix_paren.pyc deleted file mode 100644 index e962769304250b2e2ad00a0c32fb0315c53d327d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1512 zcmds1T}vB56urBf#2OTQ5=tq|OW6$-q4qVEnqr}#LDoQNqD(f~iCMc}-I=rz;*9&bSQQybtrSG z?~=o|N2y0yjrujp>eR2pTO;MtWrHRN*XcXa4bi9m8pRDd4c0j24B~w4;DutlB67Y&jeVHYdikr>eG|^&QFkCs&T8ZakL{mwW;+p6ljXuFET~e7J)zT#X|Uj-@1$Ngdk0{$)eAyYKthp zT8VLdTx6xhuGk#@-(lz@h=t1+ z>FKpc#zuYFl55W{RhO>zyQ$?-HvW9x{@Qswc|5n3|wT2umJl}@aZ7qK$T^GfMiYIMj^ zTR62G4`7lNT0q-9J4!}pX)@X~#p^Ssq-H7Y+}-lZtYea?qFm!77`9=aN|{HQlG4&!%B+ZIDVq$TSIv~!gwi>d%%R96qjZV%>x, ...' into 'print(..., file=x)' + +No changes are applied if print_function is imported from __future__ + +""" + +# Local imports +from .. import patcomp +from .. import pytree +from ..pgen2 import token +from .. import fixer_base +from ..fixer_util import Name, Call, Comma, String, is_tuple + + +parend_expr = patcomp.compile_pattern( + """atom< '(' [atom|STRING|NAME] ')' >""" + ) + + +class FixPrint(fixer_base.BaseFix): + + BM_compatible = True + + PATTERN = """ + simple_stmt< any* bare='print' any* > | print_stmt + """ + + def transform(self, node, results): + assert results + + bare_print = results.get("bare") + + if bare_print: + # Special-case print all by itself + bare_print.replace(Call(Name(u"print"), [], + prefix=bare_print.prefix)) + return + assert node.children[0] == Name(u"print") + args = node.children[1:] + if len(args) == 1 and parend_expr.match(args[0]): + # We don't want to keep sticking parens around an + # already-parenthesised expression. + return + + sep = end = file = None + if args and args[-1] == Comma(): + args = args[:-1] + end = " " + if args and args[0] == pytree.Leaf(token.RIGHTSHIFT, u">>"): + assert len(args) >= 2 + file = args[1].clone() + args = args[3:] # Strip a possible comma after the file expression + # Now synthesize a print(args, sep=..., end=..., file=...) node. + l_args = [arg.clone() for arg in args] + if l_args: + l_args[0].prefix = u"" + if sep is not None or end is not None or file is not None: + if sep is not None: + self.add_kwarg(l_args, u"sep", String(repr(sep))) + if end is not None: + self.add_kwarg(l_args, u"end", String(repr(end))) + if file is not None: + self.add_kwarg(l_args, u"file", file) + n_stmt = Call(Name(u"print"), l_args) + n_stmt.prefix = node.prefix + return n_stmt + + def add_kwarg(self, l_nodes, s_kwd, n_expr): + # XXX All this prefix-setting may lose comments (though rarely) + n_expr.prefix = u"" + n_argument = pytree.Node(self.syms.argument, + (Name(s_kwd), + pytree.Leaf(token.EQUAL, u"="), + n_expr)) + if l_nodes: + l_nodes.append(Comma()) + n_argument.prefix = u" " + l_nodes.append(n_argument) diff --git a/PythonHome/Lib/lib2to3/fixes/fix_print.pyc b/PythonHome/Lib/lib2to3/fixes/fix_print.pyc deleted file mode 100644 index 2b3287d43c237ddf3561693c67d12bff4a5b0fff..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2683 zcmbVO-EJF26h5E50uK0ri544=A6bVxD^QR5Ym9 zprT2=CKU_RTcBc*dW)pAN5dsb=jcpPZ<*40(g6)uXn^|~^b^q;(Ko$SN}JSeEwGIX zis(UhqD?p$nQ&~f(rq=HyGKcRsP8sIJe#t($z=6FWHeiC-Q2t+6K-v7&Ezi2VD&Ar z@RkU^A$BX&WxBl)Zv0!m-9EWh>3&OokmY*&1mexkDC~>XHcX5TlkqsubQ)%Z%BgrT zDf=!Pm0@PXtQe1s!|uS0iZI5Wn;0F(&1U8yC@sW<+#IHH;`*avTrC8=@X8sjE56QB zqhnoGY!mE&BN-ngR<~r=$66;Tv}0m7$#cicyQ88=9INX(1pLs=gUoE~CgWV&4KRrt z75Bo;)@JxElhf{g^tkhI+Sz%!_afZ9xf!w8QBvye#&H zf<9|zkg=z`81^=zJN3vek|X+2F+Bt_6~pzkM$;OZFL)k$T@=yKI=;B1R?V)A%MdMFR}t`V2PDt_@{M@ zfKKI%`9p*P+_J#s!>7-eLTE;@LAHcrKAAgerqC^NA-ZKQK2+hEC+F^{*LF1MxK8#1 zHH!ok)oFdW%2!kuqej_sXomk#`}vDCI-RE}>=vo-JbHOoox+C(nIn}hFu~5mbukB7 zhP4f{KdULibV1L}XtU%^&t=T-YDzS`A}WxbHFEC}b`cl;M~7ku&$XC8FG<78N;-H$ z`tm&&x|eB+<^+8&mprJvoMl*#Fr7Au^IE5Ali&#EZfgbD=|~AN0w-KT(vzfw#zv#+ zGOSU?@X!9nxoVV5gYBenM98tKHBd-di-EtPWE#ga1CrEX&N8@keI`Wdz2`HSwjAfg;k6Y^Op7X!{q`;ZMZjuzX|sSw5q-JS>r zB`JcD*JR#@D=Dy%>Uah()EOogbc*s5T_e(inv)y@-%KfYz=P~W?0Of61QqwH7`C}3*;PzIZ52W1zg8_!4gVh* C6A%^v diff --git a/PythonHome/Lib/lib2to3/fixes/fix_raise.py b/PythonHome/Lib/lib2to3/fixes/fix_raise.py new file mode 100644 index 0000000000..b958ba0129 --- /dev/null +++ b/PythonHome/Lib/lib2to3/fixes/fix_raise.py @@ -0,0 +1,90 @@ +"""Fixer for 'raise E, V, T' + +raise -> raise +raise E -> raise E +raise E, V -> raise E(V) +raise E, V, T -> raise E(V).with_traceback(T) +raise E, None, T -> raise E.with_traceback(T) + +raise (((E, E'), E''), E'''), V -> raise E(V) +raise "foo", V, T -> warns about string exceptions + + +CAVEATS: +1) "raise E, V" will be incorrectly translated if V is an exception + instance. The correct Python 3 idiom is + + raise E from V + + but since we can't detect instance-hood by syntax alone and since + any client code would have to be changed as well, we don't automate + this. +""" +# Author: Collin Winter + +# Local imports +from .. import pytree +from ..pgen2 import token +from .. import fixer_base +from ..fixer_util import Name, Call, Attr, ArgList, is_tuple + +class FixRaise(fixer_base.BaseFix): + + BM_compatible = True + PATTERN = """ + raise_stmt< 'raise' exc=any [',' val=any [',' tb=any]] > + """ + + def transform(self, node, results): + syms = self.syms + + exc = results["exc"].clone() + if exc.type == token.STRING: + msg = "Python 3 does not support string exceptions" + self.cannot_convert(node, msg) + return + + # Python 2 supports + # raise ((((E1, E2), E3), E4), E5), V + # as a synonym for + # raise E1, V + # Since Python 3 will not support this, we recurse down any tuple + # literals, always taking the first element. + if is_tuple(exc): + while is_tuple(exc): + # exc.children[1:-1] is the unparenthesized tuple + # exc.children[1].children[0] is the first element of the tuple + exc = exc.children[1].children[0].clone() + exc.prefix = u" " + + if "val" not in results: + # One-argument raise + new = pytree.Node(syms.raise_stmt, [Name(u"raise"), exc]) + new.prefix = node.prefix + return new + + val = results["val"].clone() + if is_tuple(val): + args = [c.clone() for c in val.children[1:-1]] + else: + val.prefix = u"" + args = [val] + + if "tb" in results: + tb = results["tb"].clone() + tb.prefix = u"" + + e = exc + # If there's a traceback and None is passed as the value, then don't + # add a call, since the user probably just wants to add a + # traceback. See issue #9661. + if val.type != token.NAME or val.value != u"None": + e = Call(exc, args) + with_tb = Attr(e, Name(u'with_traceback')) + [ArgList([tb])] + new = pytree.Node(syms.simple_stmt, [Name(u"raise")] + with_tb) + new.prefix = node.prefix + return new + else: + return pytree.Node(syms.raise_stmt, + [Name(u"raise"), Call(exc, args)], + prefix=node.prefix) diff --git a/PythonHome/Lib/lib2to3/fixes/fix_raise.pyc b/PythonHome/Lib/lib2to3/fixes/fix_raise.pyc deleted file mode 100644 index 25f690ae9dd487a13f15705703ebdf25c49d60e1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2467 zcmbVNUys{F5TA9Ne~zzr91>N9fW4C-E?iHdeM6<{wFHFJMwJs?McQH9ONDLSmz-V8CxCV&{BeUF_`o0dMdbzJd+<>GBqb4LR7_}g2!>A331tSZR z4vad;*8ow6xeXIk*o0pJ&H;WHZ9&+Afzu`fN-y#s!Hz=vJS zD)+ql?mXc7pgQiobIf~hFHoND-tzOFbA0>K9qPV%cX%49nWu6;5Mw_$afX+;`&lZk z3S7foDR&$PZSQq&6R9Xo$5-Jh?)^!Y?U$}rp1hsV@KZleCHKc!p}16eluo%g3&cW2 zSt>2ddVF-;I~oqYvc9~{_cvkN=ciE|^ReJj8f1Ac0u?VgdX~!AS0d!m1g(isbGp%I zA#RjP<)?u--Rb`=kW zLK7~u-+Huf|;LA z(Gy=HOdKB&SeOx*U#KiWFG-D>Me@*!FulNGNK^yKVySW=%6**Ku>mlFA+=E#6YIOIo2 z1lAk_fu&Z{^=DH3VQpY#xdVp`mc*+At%K}Im8knwadhd~zNR3(=pJ5b&)zqpDn+urgt8fU3dVgcAeu9yNt^T?-&( zu&Tp3bq9a}Mibf38RWmg+2<78YP;5In$$mT&2cg>0lXf<^AI(e;I$ydwu4dzoHQZ- z15_L47OW7w1Ingufy$9{Y7picIT_4buxgMj(g9iDxKQ5ICTO92n@!QnCJ;PExCMLP zyxN5|inXA0_D2I={|)Olq`MHdiIu~=mJHBBg@ ztd4L%K`XBHU_KU9J34WrfAA}aLs43*aY2Pd4YeTTt4+5o&|F{WgIN@Zxkz0bPh1?O>OM9XMODA4 zF_$8tLHb8edm5Mg5iXhHk{K?QlIkFlQG(^JOVgnmE6o-0L@!cOP8Q@s7O|2pvAFcd z(@{#~RL`k6b;$%p{sdam&!^HQ0DV>}DFZcj@DwzW99M@gpG4!AaWuZGvU@M7cS)k2 z_U8~=ora^%kH6OBGn9}IkpOEOJ8YLV*bXyWHruX!%xuFp_L$8~ys_DV(MBE{@7qSh z+(X_^*}lHD*@w*0A)ub;c_}tW&(l%#yd(Qvmc u`$9#re)xA@xlAB3_!0gPsHGF`|1nr+;r%i^4?aL8lF%FG4n}x~ImW+U@)+;{ diff --git a/PythonHome/Lib/lib2to3/fixes/fix_raw_input.py b/PythonHome/Lib/lib2to3/fixes/fix_raw_input.py new file mode 100644 index 0000000000..3a73b81864 --- /dev/null +++ b/PythonHome/Lib/lib2to3/fixes/fix_raw_input.py @@ -0,0 +1,17 @@ +"""Fixer that changes raw_input(...) into input(...).""" +# Author: Andre Roberge + +# Local imports +from .. import fixer_base +from ..fixer_util import Name + +class FixRawInput(fixer_base.BaseFix): + + BM_compatible = True + PATTERN = """ + power< name='raw_input' trailer< '(' [any] ')' > any* > + """ + + def transform(self, node, results): + name = results["name"] + name.replace(Name(u"input", prefix=name.prefix)) diff --git a/PythonHome/Lib/lib2to3/fixes/fix_raw_input.pyc b/PythonHome/Lib/lib2to3/fixes/fix_raw_input.pyc deleted file mode 100644 index b7c5443e2ecc1597c0b9f06971c0d1f1007dfb62..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 905 zcma)4O>fjN5FI<&0E;Sm<$&Y^QqmrBDA%%rMIa%;3S}1|!Xo2Myfl^bq1aKWR8Gr} z;(zf6m~qM$IMtG0X5#sH^X%Z)!Sv^cFUtb1SAgGVxa|vs5+FxpP;xK~Y7RLEMt%S$ zfI5UcL_Y-0;d}yHJea@_fE~ccJc2TUWpam#oglobzUf}LGv!2arkbzXie6pFs_6!o zq-lC2s>ZblfBdxKn3gaEH$~V|0l86DkN-maw@|fq_tC)WnYwsQ$@^I-bB^0SLeMx1 zBcgfW=L%^qAkR*yd@xryC2`tIE(xoW$ajYA!#E_$U@L zf#$K8{a2+RRf+BdHwkNx5w18^cG0*dHIb%exZpfX-3 z7opYl8l_37ha$EW*jtIc*S)0X-=*bc_ojItBlBiP4irRz7x#|b) z4$zptl|@^3%2gXPQhWD&wR)K?GHP){&0DwTm(j%%2TN=s9t9C!_&4dNm$GaNWP)dq q5&ZSg23Hxcp^u#7v!gfWpCm=zFuFAvFUILO{)}#CBo!XAL;f31u(_oG diff --git a/PythonHome/Lib/lib2to3/fixes/fix_reduce.py b/PythonHome/Lib/lib2to3/fixes/fix_reduce.py new file mode 100644 index 0000000000..6bd785c1cd --- /dev/null +++ b/PythonHome/Lib/lib2to3/fixes/fix_reduce.py @@ -0,0 +1,35 @@ +# Copyright 2008 Armin Ronacher. +# Licensed to PSF under a Contributor Agreement. + +"""Fixer for reduce(). + +Makes sure reduce() is imported from the functools module if reduce is +used in that module. +""" + +from lib2to3 import fixer_base +from lib2to3.fixer_util import touch_import + + + +class FixReduce(fixer_base.BaseFix): + + BM_compatible = True + order = "pre" + + PATTERN = """ + power< 'reduce' + trailer< '(' + arglist< ( + (not(argument) any ',' + not(argument + > + """ + + def transform(self, node, results): + touch_import(u'functools', u'reduce', node) diff --git a/PythonHome/Lib/lib2to3/fixes/fix_reduce.pyc b/PythonHome/Lib/lib2to3/fixes/fix_reduce.pyc deleted file mode 100644 index de60d08574b34bf91fa532fc202f7a9f4b8db806..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1231 zcmcgr&2G~`5FXo!0gFO~cz^{Cb|jPoTtie+(G!i3Qwd>3GLF5b3${1xk7%Xd%0uy9 zJOIqBO`=|q=z*1Hc6N4tzMYv3ejY?W-hW(`FsuOgBP4x{tOCf8drnw)wU~*l#OPstZc)Xs0Rlg=pMOvRBeYp*}T2n;A=Xwxp(&bkZbv zZ(H7(S z$H>f|3BK~+I>2!SoJz7~in)too_9sd^W4pC zp7#@vM@oODEH?)zEKc)Mw%fvpO~cI?HBwbvIcV=*pPju)mnp&A sys.maxsize +""" +# Author: Christian Heimes +# based on Collin Winter's fix_import + +# Local imports +from .. import fixer_base +from ..fixer_util import Name, attr_chain + +MAPPING = {"sys": {"maxint" : "maxsize"}, + } +LOOKUP = {} + +def alternates(members): + return "(" + "|".join(map(repr, members)) + ")" + + +def build_pattern(): + #bare = set() + for module, replace in MAPPING.items(): + for old_attr, new_attr in replace.items(): + LOOKUP[(module, old_attr)] = new_attr + #bare.add(module) + #bare.add(old_attr) + #yield """ + # import_name< 'import' (module=%r + # | dotted_as_names< any* module=%r any* >) > + # """ % (module, module) + yield """ + import_from< 'from' module_name=%r 'import' + ( attr_name=%r | import_as_name< attr_name=%r 'as' any >) > + """ % (module, old_attr, old_attr) + yield """ + power< module_name=%r trailer< '.' attr_name=%r > any* > + """ % (module, old_attr) + #yield """bare_name=%s""" % alternates(bare) + + +class FixRenames(fixer_base.BaseFix): + BM_compatible = True + PATTERN = "|".join(build_pattern()) + + order = "pre" # Pre-order tree traversal + + # Don't match the node if it's within another match + def match(self, node): + match = super(FixRenames, self).match + results = match(node) + if results: + if any(match(obj) for obj in attr_chain(node, "parent")): + return False + return results + return False + + #def start_tree(self, tree, filename): + # super(FixRenames, self).start_tree(tree, filename) + # self.replace = {} + + def transform(self, node, results): + mod_name = results.get("module_name") + attr_name = results.get("attr_name") + #bare_name = results.get("bare_name") + #import_mod = results.get("module") + + if mod_name and attr_name: + new_attr = unicode(LOOKUP[(mod_name.value, attr_name.value)]) + attr_name.replace(Name(new_attr, prefix=attr_name.prefix)) diff --git a/PythonHome/Lib/lib2to3/fixes/fix_renames.pyc b/PythonHome/Lib/lib2to3/fixes/fix_renames.pyc deleted file mode 100644 index d02c097ca62c2ed7a6eed062013070ced1f2849d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2366 zcmbVN>uwuG6h5=QBz78_Ms2D9g5^@|L?QwzDui4^(^7=mxM7_VVWlkV-Ep(luGife z(*!xcinu%nFTs290(|GJoj{czDNgq6oVlFaeBas9-^=yC_J8b#H2anD{t}OwKtx16 zNJWuDiK5h@oBM=NBkipkFXpq-aqF zHHvDa9U9hYfD?6|d_nYmZ;7HM>NYR2`!68w$472F3bS+^*tnl)H`k*e)uvv@iZ-9u zU3b$p$7U-Hj^dGZKWxu66aTF1u>%`T1!3zD1DwhIeqeNy7c6JmfjLA8 z$u=d9VFnkhrNLMxay`zA&?Ow5_H}NW*gzu8yBKX9JdFDXN!E|bhgv8El83^2iPpYTfKD-kWvI_Sp#5jdv>y>}nltX0KOu3IFaP3noaNRZ zS!758{O98(Xl-=$ePoW+$8Hx+nm_H@Z>I|7})3)%w#0Vk5RUb$9x8%!G6Vz@0GZv49lb|3^5P{O#+bNCgIGRL}}I} zyn;6#mqWNQ&UMIk88uuNew)V-z$^$=kZ$PEA4IV7V<}YWq93xjkCcL+K&SmiqgzynQr4@MZ@$^-Q0xTHN1&b@OqQQ*JAj{J> z9~4%q%j$CZl6q4$Sru=-`0{<>sqfDc_T{Gc@`<)g^6ee}>?7-OAv~tKB)fZOZ|^Iw zBY9?d1WYlUybXx6xL*avg2_!Bmzb+S#i~;+)s{Q*-4~y}A7vq8#wPMuNc8-H%l(Os zlcLIuWRKA$7vXUtXJK#SGtX^_3Gn~ol=8KTg0&f`g5+vtMXfnkovKqS*RK5o%1zVw diff --git a/PythonHome/Lib/lib2to3/fixes/fix_repr.py b/PythonHome/Lib/lib2to3/fixes/fix_repr.py new file mode 100644 index 0000000000..f34365647f --- /dev/null +++ b/PythonHome/Lib/lib2to3/fixes/fix_repr.py @@ -0,0 +1,23 @@ +# Copyright 2006 Google, Inc. All Rights Reserved. +# Licensed to PSF under a Contributor Agreement. + +"""Fixer that transforms `xyzzy` into repr(xyzzy).""" + +# Local imports +from .. import fixer_base +from ..fixer_util import Call, Name, parenthesize + + +class FixRepr(fixer_base.BaseFix): + + BM_compatible = True + PATTERN = """ + atom < '`' expr=any '`' > + """ + + def transform(self, node, results): + expr = results["expr"].clone() + + if expr.type == self.syms.testlist1: + expr = parenthesize(expr) + return Call(Name(u"repr"), [expr], prefix=node.prefix) diff --git a/PythonHome/Lib/lib2to3/fixes/fix_repr.pyc b/PythonHome/Lib/lib2to3/fixes/fix_repr.pyc deleted file mode 100644 index 32262db56619e0dd5593827999fb6f00ca639fe1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 985 zcmbVKOOMkq5FXoYb}1~ZkT@WL$Zf-=h=;^wSwUBDf`ZaYh^UgAHZGguJY+jkQN1JnQuOi_;xh-`hGrH!jDhj|2dj{i;w{%hzv3gnnA%K;lOAu zKno~(ko2JFL(+#LfF!`Z9w-j$16bjqK70Y#1AIshAq!v<9Z=#22(R*uGNHRjUFb|& z+Erx=8_qZFcH7RwymVD)RBa+3xIfG}-ia838z8Lcwp^rEMMT&25YAJry)#Y=<*s3* zPK_$vg|hipIjW3BV@&$1RmwL)vv&~`w#tZmB7ECDY8&ZeYw;wa`t~WpApGM?T~&mq z;mQ0YRGZp7OUu?T&i*>LB%VaGk9Lk`CkQ)EMQ*RXNS_7l1gshC0M;m>fKMFE6Y37* zdj@!*#Af^80(uXOVEm(hiyb4$_nb{4Dl+y$5TS;aq$J)!MT|n}qC<2s4Zu=YrSfN8 zTX&9a3+t}X0cD-et$P>~^_aAZNrjja`6~XRReI%}vdTJ@jk1k)Hl_j*S_k$Xdc)c4 zd@ + | + single=any) ']' > + | + atom< '(' items=testlist_gexp< any ((',' any)* [',']) > ')' > + ) + ')' > > + """ + + def transform(self, node, results): + single = results.get("single") + if single: + # Make a fake listmaker + fake = pytree.Node(syms.listmaker, [single.clone()]) + single.replace(fake) + items = fake + else: + items = results["items"] + + # Build the contents of the literal + literal = [pytree.Leaf(token.LBRACE, u"{")] + literal.extend(n.clone() for n in items.children) + literal.append(pytree.Leaf(token.RBRACE, u"}")) + # Set the prefix of the right brace to that of the ')' or ']' + literal[-1].prefix = items.next_sibling.prefix + maker = pytree.Node(syms.dictsetmaker, literal) + maker.prefix = node.prefix + + # If the original was a one tuple, we need to remove the extra comma. + if len(maker.children) == 4: + n = maker.children[2] + n.remove() + maker.children[-1].prefix = n.prefix + + # Finally, replace the set call with our shiny new literal. + return maker diff --git a/PythonHome/Lib/lib2to3/fixes/fix_set_literal.pyc b/PythonHome/Lib/lib2to3/fixes/fix_set_literal.pyc deleted file mode 100644 index b2b2347bc43bd3cf3b96e6a270b3462cc1aaf8ff..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1944 zcmbVNZExH}5T3Q~e94gz+Nyz41QtlxK`27-4J8pxX(gnPA}0cIO=KKR=ap3%rj#wA7C4r(&;ucc5_(%jW71#!wo^iJUz*v z6kt2ObgkCiai4XXGhMqLID1)Hw+iNYd2yiKUgz*SY=x6uR{IDGlumi4L8+w3=tj-$JL-r;BgI*!5)v(wfw?(|e& zOz*}WMjLnDv~fFRvG^CdoO^Q_i|hFm%RWZ_XJ|L+(JMuBpJqO_-;h%@@yPi!>9J(e z=Qcc5bmh^!lLR#D5lj?*=6$M%>W00+f@&OB=0 zR-L3+0>&kp0o{F$N--yPP+$13fp36$<7Dm2V04vtJQGs9b8h(GbEZ5?yezNBATy%l zdo)*qNCxzEJU%o2Fij8@t&245=fkV-ONzKW6dKUU_n4%9GDs^TiR5 ztYw;FWYWcCZ%!{Qqun~yHM*(YiLkNkGa$h_m%%T&^d*bq2Ouag%Bo$$x5}9BH-%1E z>e$=$R3-fKI3}&0nk?6%yr;8q!pYReOY>5{W)s}Y{#v!cu$!j#b#v}WO|)m8JWmI`(6lQv^vYDBO=YR`?c ziM(SR_ZaU(!gtH@B5_g%ai4I+ua$Yp)%E+!Enq(cA+@Fg?|rqZmc60>j(S(U=RHsl z)r$WRvY}e{g2I!)zKPSdI>&JAxF_hEak<>}r1HqD!AnmOc3iy2C7%Di+E z(RWV{51%Fb$p^4`703T=qlB;I)LSlJ-~}oe2Ht*`Y3_hDEt(wAm|yf{0+zZay8lYL s$(`D!=dLu;C0$>!*)INXo|hML)$1db3~Y6&+TotHT->0yuGV}102w8VaR2}S diff --git a/PythonHome/Lib/lib2to3/fixes/fix_standarderror.py b/PythonHome/Lib/lib2to3/fixes/fix_standarderror.py new file mode 100644 index 0000000000..6cad51116d --- /dev/null +++ b/PythonHome/Lib/lib2to3/fixes/fix_standarderror.py @@ -0,0 +1,18 @@ +# Copyright 2007 Google, Inc. All Rights Reserved. +# Licensed to PSF under a Contributor Agreement. + +"""Fixer for StandardError -> Exception.""" + +# Local imports +from .. import fixer_base +from ..fixer_util import Name + + +class FixStandarderror(fixer_base.BaseFix): + BM_compatible = True + PATTERN = """ + 'StandardError' + """ + + def transform(self, node, results): + return Name(u"Exception", prefix=node.prefix) diff --git a/PythonHome/Lib/lib2to3/fixes/fix_standarderror.pyc b/PythonHome/Lib/lib2to3/fixes/fix_standarderror.pyc deleted file mode 100644 index b432fa2facc23acefd6ba675cd641550dd4d7e4d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 822 zcmbtSO>5gg5S^7|wRH%%^jz?zM3?x`UPDM7+*4|bWC#_8tt_oUK_6y!1u68F{;2-1 z{DHn1$7!2e$-+F%?9R@L@7TUOG;3h}*wxl2Grlmiu20X2%+fbxJ8$00Q# zwGrhJ;)qN@HzV5OU_?KO?ufqTF;y{T$qO#_4)CeIHFmn~?KJa6R~5EeSc~ZNe7d+T z&Cb_-H>(3=CJNxkfGywAo5Gp>UWC16(HcL2gMx=jhATbxz}M$6_ZDE#gJObtDE&m- z4>;x{O0$HYbEkmu^q+Nds4N^$o}8Af5*zcmgt<2We~{{jq8mkbN@WQrEr(aY#~yu* zXlD(2ljl>Wn{uLLd#>qBvlXZ7E8|&0YuwOym%t?facAqRdb4io&3oT}ShHG=QM(6) zMVHy`yJrU87M+9s?P~;%J13Pe8UGTXbq8U!7TvXO`)X)7WI8K57=H|B{#loOyDNOX zY4*Ind|a&-=`v-Gf5`nm!<6|P!5lM+RUF2_Qiey`*ShLUu)!In41bNs;Oj<2l*~DX Z1(PB5o sys.exc_info()[0] +sys.exc_value -> sys.exc_info()[1] +sys.exc_traceback -> sys.exc_info()[2] +""" + +# By Jeff Balogh and Benjamin Peterson + +# Local imports +from .. import fixer_base +from ..fixer_util import Attr, Call, Name, Number, Subscript, Node, syms + +class FixSysExc(fixer_base.BaseFix): + # This order matches the ordering of sys.exc_info(). + exc_info = [u"exc_type", u"exc_value", u"exc_traceback"] + BM_compatible = True + PATTERN = """ + power< 'sys' trailer< dot='.' attribute=(%s) > > + """ % '|'.join("'%s'" % e for e in exc_info) + + def transform(self, node, results): + sys_attr = results["attribute"][0] + index = Number(self.exc_info.index(sys_attr.value)) + + call = Call(Name(u"exc_info"), prefix=sys_attr.prefix) + attr = Attr(Name(u"sys"), call) + attr[1].children[0].prefix = results["dot"].prefix + attr.append(Subscript(index)) + return Node(syms.power, attr, prefix=node.prefix) diff --git a/PythonHome/Lib/lib2to3/fixes/fix_sys_exc.pyc b/PythonHome/Lib/lib2to3/fixes/fix_sys_exc.pyc deleted file mode 100644 index 6c25f28ebf722a99636370fbd01dc541ed5451e9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1661 zcmbVM-HzK-5T0Wv&TiW6Rst$TD$bZ&7=4)z2IRH&PI`4>9L3qgiaUgl;=n zduDATgXeLc%U}{0+IrZUw8cy}_7KBqJ2Od>)pn~Z)@Fj0zWu71(YnLh*xLuMt*d74)C>F{*u$G{?+wN^hJJv5K}u|Iyp+%lBw zge4=(MaK!70mPc<>Xf%OsopO0p80^6 zFTc!Ymw7gOVyjOsnK;8TLf{c{KCM@V(?7e`rC!#}_+2(+e;y?q7MErhAER&nfLJ>m z%m5uR*tldR-i4xtLu;27E+dY2(;*OR!G^4W8Q%48(3A{*}E$_AV`sL>b-@0lYhEI$~-kQcQaqGAz-ab8Zl+%ev8k zqUAIJhvh#Q%$SwYJ&1s@w!2ahGln87Q@uoLL{cyTqZP1mz@-yNm#|UtLzbtFF6FGa zu63CPY!z@%1PrV=ky5(tBct=V^hC+c!CH+rZElSO!nAQ(!F@L8_>x__@$!ErUvNVG zmIjwj@c{k|XHM##I&n_ad+J2JqXbepK8i{-bri`h5Jg3mwmGK3F-#B32Qu6uw*~P_+U=o}_?KWT;{mYUK7+#Lk@W6A9mFK?iOh$aL91%rn zl^{&aDPZy1wbj}z7m{8hj)8oW8;1TIR~)V+Iq(04DzKexff_UMhK1L?uReAD2J#zM AR{#J2 diff --git a/PythonHome/Lib/lib2to3/fixes/fix_throw.py b/PythonHome/Lib/lib2to3/fixes/fix_throw.py new file mode 100644 index 0000000000..1468d89a45 --- /dev/null +++ b/PythonHome/Lib/lib2to3/fixes/fix_throw.py @@ -0,0 +1,56 @@ +"""Fixer for generator.throw(E, V, T). + +g.throw(E) -> g.throw(E) +g.throw(E, V) -> g.throw(E(V)) +g.throw(E, V, T) -> g.throw(E(V).with_traceback(T)) + +g.throw("foo"[, V[, T]]) will warn about string exceptions.""" +# Author: Collin Winter + +# Local imports +from .. import pytree +from ..pgen2 import token +from .. import fixer_base +from ..fixer_util import Name, Call, ArgList, Attr, is_tuple + +class FixThrow(fixer_base.BaseFix): + BM_compatible = True + PATTERN = """ + power< any trailer< '.' 'throw' > + trailer< '(' args=arglist< exc=any ',' val=any [',' tb=any] > ')' > + > + | + power< any trailer< '.' 'throw' > trailer< '(' exc=any ')' > > + """ + + def transform(self, node, results): + syms = self.syms + + exc = results["exc"].clone() + if exc.type is token.STRING: + self.cannot_convert(node, "Python 3 does not support string exceptions") + return + + # Leave "g.throw(E)" alone + val = results.get(u"val") + if val is None: + return + + val = val.clone() + if is_tuple(val): + args = [c.clone() for c in val.children[1:-1]] + else: + val.prefix = u"" + args = [val] + + throw_args = results["args"] + + if "tb" in results: + tb = results["tb"].clone() + tb.prefix = u"" + + e = Call(exc, args) + with_tb = Attr(e, Name(u'with_traceback')) + [ArgList([tb])] + throw_args.replace(pytree.Node(syms.power, with_tb)) + else: + throw_args.replace(Call(exc, args)) diff --git a/PythonHome/Lib/lib2to3/fixes/fix_throw.pyc b/PythonHome/Lib/lib2to3/fixes/fix_throw.pyc deleted file mode 100644 index fca3c72266b20aeacf47bb4046c078a73eb5fae9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1965 zcmbVN-EJF26h6CN|0ZorkU&L343&`A5PZ=}T%~~&T7*=rXl)hMO}ebtV`rWHF*D;P z5%yJ(cn_X}SKtMB5gq`(Gn+puE-Ea|**P=kocZQE=Zq_V-D&;)!;gcQE`Jq#zrxTz zLrjQ9kPb~;N*&5v8oA`KUZJ!?nMWh9)IGajrBSuitCZF#tJA1XS%XFm%9=E4Qr4nT zi?R(GZNRQZvP$z!nj&DGej&ObdNH~~lLig^CWH7B;%Rawm6#Sv%w#TAWD3 zpX`X|J7U=FwOX^QrLHJ{pYMsAwVQ2tSc}`+{_}44UltrwykXHhP0VpT@P#hD3gXKUq@+b>X_`S*|S6&ySQ(RG7T&yIyB2g zDy;%8hfLjdx*5P@4E-U5M7kZ4$a2M|-s99GEl6rG@ENfF1ER$YFN#yCc14t*3y_ke ztaN%E(XpxNh&^j{nT#6?zat_w(~lrhK;30Z9&wP)PDi|sQagXiiW&3#NbHGD_bOZ& zboF)sZsEeI*XMAsOLQ?8`zD5Ek*{|EK2}6?qIHERio(!O02CNcN0u^@ZH=5yKY&B^D)~odK zH%HsFuF*Klaie2Yw*=I_u79Bk8SgH2)Ki@ZRCEEkJH{YRrL*$;)0aHS@Hjgz87@mRUf#v$jTU|P%1)nW+Hl{*X_1#bW6l>cxbD8eF!-+jEiMg{C z8H;)*%a-cHIp99CtrQ<8=|suAY+ohOqJf9afZI7>)PZePc2IJW;^7D|Es^(&iL{7p z8~I#=_C{K!Q#;Aopmf#C)aZas0)7)MBoJa4eH<{k#tQE1kSPf^c#XHq5G5^R9}8rK z7MS%8pC#kNG#NiI#lu5>U^L6n_HPgGkv&XBxyI9*eE<*rDFiu9x9w~@ZO5x@Ih&5> zZbI(3O{}*tZ{xe=eBylM`b>nSDhzYHRbgmxhGAArmMN=D*HA4bDi5#F_aHr6L?#*I zvEr*A><@=ef_@+{zXAXDHwYSVY-4CfQgdqcn%nm|$u@i#PKp>Ppi`L{&esBeG7oHJ z1h%r6S|&$@OOvE!UTvD$xXiUJ2^Np>K0ien@VWm7uqA7^q-T! + +def func(x, d): + ((a, b), c) = x + ... + +It will also support lambdas: + + lambda (x, y): x + y -> lambda t: t[0] + t[1] + + # The parens are a syntax error in Python 3 + lambda (x): x + y -> lambda x: x + y +""" +# Author: Collin Winter + +# Local imports +from .. import pytree +from ..pgen2 import token +from .. import fixer_base +from ..fixer_util import Assign, Name, Newline, Number, Subscript, syms + +def is_docstring(stmt): + return isinstance(stmt, pytree.Node) and \ + stmt.children[0].type == token.STRING + +class FixTupleParams(fixer_base.BaseFix): + run_order = 4 #use a lower order since lambda is part of other + #patterns + BM_compatible = True + + PATTERN = """ + funcdef< 'def' any parameters< '(' args=any ')' > + ['->' any] ':' suite=any+ > + | + lambda= + lambdef< 'lambda' args=vfpdef< '(' inner=any ')' > + ':' body=any + > + """ + + def transform(self, node, results): + if "lambda" in results: + return self.transform_lambda(node, results) + + new_lines = [] + suite = results["suite"] + args = results["args"] + # This crap is so "def foo(...): x = 5; y = 7" is handled correctly. + # TODO(cwinter): suite-cleanup + if suite[0].children[1].type == token.INDENT: + start = 2 + indent = suite[0].children[1].value + end = Newline() + else: + start = 0 + indent = u"; " + end = pytree.Leaf(token.INDENT, u"") + + # We need access to self for new_name(), and making this a method + # doesn't feel right. Closing over self and new_lines makes the + # code below cleaner. + def handle_tuple(tuple_arg, add_prefix=False): + n = Name(self.new_name()) + arg = tuple_arg.clone() + arg.prefix = u"" + stmt = Assign(arg, n.clone()) + if add_prefix: + n.prefix = u" " + tuple_arg.replace(n) + new_lines.append(pytree.Node(syms.simple_stmt, + [stmt, end.clone()])) + + if args.type == syms.tfpdef: + handle_tuple(args) + elif args.type == syms.typedargslist: + for i, arg in enumerate(args.children): + if arg.type == syms.tfpdef: + # Without add_prefix, the emitted code is correct, + # just ugly. + handle_tuple(arg, add_prefix=(i > 0)) + + if not new_lines: + return + + # This isn't strictly necessary, but it plays nicely with other fixers. + # TODO(cwinter) get rid of this when children becomes a smart list + for line in new_lines: + line.parent = suite[0] + + # TODO(cwinter) suite-cleanup + after = start + if start == 0: + new_lines[0].prefix = u" " + elif is_docstring(suite[0].children[start]): + new_lines[0].prefix = indent + after = start + 1 + + for line in new_lines: + line.parent = suite[0] + suite[0].children[after:after] = new_lines + for i in range(after+1, after+len(new_lines)+1): + suite[0].children[i].prefix = indent + suite[0].changed() + + def transform_lambda(self, node, results): + args = results["args"] + body = results["body"] + inner = simplify_args(results["inner"]) + + # Replace lambda ((((x)))): x with lambda x: x + if inner.type == token.NAME: + inner = inner.clone() + inner.prefix = u" " + args.replace(inner) + return + + params = find_params(args) + to_index = map_to_index(params) + tup_name = self.new_name(tuple_name(params)) + + new_param = Name(tup_name, prefix=u" ") + args.replace(new_param.clone()) + for n in body.post_order(): + if n.type == token.NAME and n.value in to_index: + subscripts = [c.clone() for c in to_index[n.value]] + new = pytree.Node(syms.power, + [new_param.clone()] + subscripts) + new.prefix = n.prefix + n.replace(new) + + +### Helper functions for transform_lambda() + +def simplify_args(node): + if node.type in (syms.vfplist, token.NAME): + return node + elif node.type == syms.vfpdef: + # These look like vfpdef< '(' x ')' > where x is NAME + # or another vfpdef instance (leading to recursion). + while node.type == syms.vfpdef: + node = node.children[1] + return node + raise RuntimeError("Received unexpected node %s" % node) + +def find_params(node): + if node.type == syms.vfpdef: + return find_params(node.children[1]) + elif node.type == token.NAME: + return node.value + return [find_params(c) for c in node.children if c.type != token.COMMA] + +def map_to_index(param_list, prefix=[], d=None): + if d is None: + d = {} + for i, obj in enumerate(param_list): + trailer = [Subscript(Number(unicode(i)))] + if isinstance(obj, list): + map_to_index(obj, trailer, d=d) + else: + d[obj] = prefix + trailer + return d + +def tuple_name(param_list): + l = [] + for obj in param_list: + if isinstance(obj, list): + l.append(tuple_name(obj)) + else: + l.append(obj) + return u"_".join(l) diff --git a/PythonHome/Lib/lib2to3/fixes/fix_tuple_params.pyc b/PythonHome/Lib/lib2to3/fixes/fix_tuple_params.pyc deleted file mode 100644 index 88f89f2cf3357e0945774afcfbf78ae7561e6b79..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5308 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 diff --git a/PythonHome/Lib/lib2to3/fixes/fix_types.py b/PythonHome/Lib/lib2to3/fixes/fix_types.py new file mode 100644 index 0000000000..fc9d495927 --- /dev/null +++ b/PythonHome/Lib/lib2to3/fixes/fix_types.py @@ -0,0 +1,62 @@ +# Copyright 2007 Google, Inc. All Rights Reserved. +# Licensed to PSF under a Contributor Agreement. + +"""Fixer for removing uses of the types module. + +These work for only the known names in the types module. The forms above +can include types. or not. ie, It is assumed the module is imported either as: + + import types + from types import ... # either * or specific types + +The import statements are not modified. + +There should be another fixer that handles at least the following constants: + + type([]) -> list + type(()) -> tuple + type('') -> str + +""" + +# Local imports +from ..pgen2 import token +from .. import fixer_base +from ..fixer_util import Name + +_TYPE_MAPPING = { + 'BooleanType' : 'bool', + 'BufferType' : 'memoryview', + 'ClassType' : 'type', + 'ComplexType' : 'complex', + 'DictType': 'dict', + 'DictionaryType' : 'dict', + 'EllipsisType' : 'type(Ellipsis)', + #'FileType' : 'io.IOBase', + 'FloatType': 'float', + 'IntType': 'int', + 'ListType': 'list', + 'LongType': 'int', + 'ObjectType' : 'object', + 'NoneType': 'type(None)', + 'NotImplementedType' : 'type(NotImplemented)', + 'SliceType' : 'slice', + 'StringType': 'bytes', # XXX ? + 'StringTypes' : 'str', # XXX ? + 'TupleType': 'tuple', + 'TypeType' : 'type', + 'UnicodeType': 'str', + 'XRangeType' : 'range', + } + +_pats = ["power< 'types' trailer< '.' name='%s' > >" % t for t in _TYPE_MAPPING] + +class FixTypes(fixer_base.BaseFix): + BM_compatible = True + PATTERN = '|'.join(_pats) + + def transform(self, node, results): + new_value = unicode(_TYPE_MAPPING.get(results["name"].value)) + if new_value: + return Name(new_value, prefix=node.prefix) + return None diff --git a/PythonHome/Lib/lib2to3/fixes/fix_types.pyc b/PythonHome/Lib/lib2to3/fixes/fix_types.pyc deleted file mode 100644 index 918adbb229a76dc71003788fce7b082b970bd5f4..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2154 zcmbVM>uwuG6h3PwPU1Fg=?w}k43yS(FGgxbC8`q9q%Dfnn#eYSnv`Yj87JfJ?wFl% zE>if_J`_*DBk&@;0N**ACPDl`#MwFbneSX?s(&rlfB)f^-iQwW=0Lx}=a(WPO*Ft7 zk*-i0QC6Wrg(8-#lvXL5qrqG$&rv#0S&arYitHuQ^Q3F^KrfJ91X&_o2RTLhG{`dP zGbK3-a*p(SAm>S60J%u|63AuJ@0ZdCAXi9#2=Wo>t031%e+=>oX$A5r>CZr}ll~m! z2I-q1IImGEn;*FR~1h&yEFXi}#!(z{D< ziQW*s8~}5hdd)AmB!8eJ&+MKl)YuiOFqzx2`Iee_pF+r-o~5Q;ulKi& zH)_`vuO-Cg>AtwV&fRXV@+5<^&Ho*#6e2k!^C}s-9aA4AIXp+{OdlT7R=|+E&{oQt zJ8C^B3t#VNnbERg34*mYo4O)EZ7eVr@OoIUEBuv)60|7Bh06|eIJC9fZFT)!;4MDW zPtC}V?dUL!b9}dv4@oeY$perShS6~;;B0hR3@H7!o26O}jY?o=IAbYk*iM4lPI8^1 zCSX&O_#lalU7EUGuJp*|I0D<3__^54pI)`p-4&HuA2Hm6LS4k;{N_Pc~dD`J)hRM+m#9?bKV}3a6oZCrKEmI8I#>1i&-qL|=v8<{>bU^}N(ER<5NS{2YvUGK%Le-x8q) z!3`${=s551gk_6oF))~p%S}tRU`}iok8NR{ljb=wx)sjD&~Ybqated?sU4M7>oIqv zAMOW(cEh6=3JiuAI2$xqN_njIWrKMVB>O&d;?FrTBLX+{``nJ4K0c*L@~yJ9KX#dA zN8f_u)a{z$k!l21G*l=On~I{{kURZ#;|A0#YDFr57egYCo>-o}Reb&?7K0}?B7>K; z%Fpd&j?6s0iTEMKJNp*a1?u*i920n64@R6PcZt6>eEuseLClj19aK2(%B0Gh;QzNO z9aO3Kk}$kr@Q@!wG~pwn9?t7EdAp8GHa|y!n>#HGu0WH=LS|!D7A7o15%*tiJdIyG z-q=|0d>c3zHIf?dBE4I-80~+D+~v+c zz~{N#HQ+p3=`{J?%Jy-r-3Y+=(CL=R?{&d&i&0v6vv~5k5Jfx-HZ5y@n_a}(m4V>y ut>OuLX7}W{|ASM?_NXk>3SVH)plj805q_0wv~coQ`G<7U64k5MDt`k-O$zb= diff --git a/PythonHome/Lib/lib2to3/fixes/fix_unicode.py b/PythonHome/Lib/lib2to3/fixes/fix_unicode.py new file mode 100644 index 0000000000..2d776f6105 --- /dev/null +++ b/PythonHome/Lib/lib2to3/fixes/fix_unicode.py @@ -0,0 +1,42 @@ +r"""Fixer for unicode. + +* Changes unicode to str and unichr to chr. + +* If "...\u..." is not unicode literal change it into "...\\u...". + +* Change u"..." into "...". + +""" + +from ..pgen2 import token +from .. import fixer_base + +_mapping = {u"unichr" : u"chr", u"unicode" : u"str"} + +class FixUnicode(fixer_base.BaseFix): + BM_compatible = True + PATTERN = "STRING | 'unicode' | 'unichr'" + + def start_tree(self, tree, filename): + super(FixUnicode, self).start_tree(tree, filename) + self.unicode_literals = 'unicode_literals' in tree.future_features + + def transform(self, node, results): + if node.type == token.NAME: + new = node.clone() + new.value = _mapping[node.value] + return new + elif node.type == token.STRING: + val = node.value + if not self.unicode_literals and val[0] in u'\'"' and u'\\' in val: + val = ur'\\'.join([ + v.replace(u'\\u', ur'\\u').replace(u'\\U', ur'\\U') + for v in val.split(ur'\\') + ]) + if val[0] in u'uU': + val = val[1:] + if val == node.value: + return node + new = node.clone() + new.value = val + return new diff --git a/PythonHome/Lib/lib2to3/fixes/fix_unicode.pyc b/PythonHome/Lib/lib2to3/fixes/fix_unicode.pyc deleted file mode 100644 index d3a8edb4d8d942efe92daf6184fe98f9f07ecbfb..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1672 zcmbVM-EP}f4Caw+CH4|D7<#c>3>A!_5qjYQDbTB~Xp{b+z-kO~f})07RgsPpIkKeb z9HlGZT%|XAjXlNoB728j?*;aeQkq?EGb|pGA`i)rq};!@hrhk~FioiYxj3KTF>gRp zq8X^7)S+C_%AuJv6}m$p|k|98sV^ zY@bPau8US2LR@hE(MfD{!@wb@#>2_QfMpdDZ#Fs=>a*;Hs*l@p6G-yo00(%?T@Ve} z6=|UDN(%t4Vh9;mM;MR7X&~2s3;XF&_-gXfU;BFeRaMNM(j7)KFf6xuXF&OgqRVy@%)GEWS(ay`?h>AXZ#J* zs7q^HeF{03+jtCLOlnsN1l$*X1Og9ubD4qy>OXg=-tP*(BD!=5$*@76cGoUNeFB}{ zczELBsMh2XwnWPf+Nyu2wRCG2jRJy@u_{n?JXT_pP7xc-fVbvK(X)5o(Io=(X*uLA z!V+;)z++oBnSbxlPrtA!0u|znF70Bi_|`up;*joqdD$k#CH=`YNZKy%AId`Dn|h?P zyo-|zgc@$$-l*YOoQp8;jz&fqQmZ}g#A6Yg|OYNv0&VjnCJmsqIogKBUZb7#N zT_BlBr4f&C6v;wF(W*?FoJ9uas7Bq}U=ChKNx7) > + """ % (old_module, old_module) + yield """import_from< 'from' mod_member=%r 'import' + ( member=%s | import_as_name< member=%s 'as' any > | + import_as_names< members=any* >) > + """ % (old_module, members, members) + yield """import_from< 'from' module_star=%r 'import' star='*' > + """ % old_module + yield """import_name< 'import' + dotted_as_name< module_as=%r 'as' any > > + """ % old_module + # bare_with_attr has a special significance for FixImports.match(). + yield """power< bare_with_attr=%r trailer< '.' member=%s > any* > + """ % (old_module, members) + + +class FixUrllib(FixImports): + + def build_pattern(self): + return "|".join(build_pattern()) + + def transform_import(self, node, results): + """Transform for the basic import case. Replaces the old + import name with a comma separated list of its + replacements. + """ + import_mod = results.get("module") + pref = import_mod.prefix + + names = [] + + # create a Node list of the replacement modules + for name in MAPPING[import_mod.value][:-1]: + names.extend([Name(name[0], prefix=pref), Comma()]) + names.append(Name(MAPPING[import_mod.value][-1][0], prefix=pref)) + import_mod.replace(names) + + def transform_member(self, node, results): + """Transform for imports of specific module elements. Replaces + the module to be imported from with the appropriate new + module. + """ + mod_member = results.get("mod_member") + pref = mod_member.prefix + member = results.get("member") + + # Simple case with only a single member being imported + if member: + # this may be a list of length one, or just a node + if isinstance(member, list): + member = member[0] + new_name = None + for change in MAPPING[mod_member.value]: + if member.value in change[1]: + new_name = change[0] + break + if new_name: + mod_member.replace(Name(new_name, prefix=pref)) + else: + self.cannot_convert(node, "This is an invalid module element") + + # Multiple members being imported + else: + # a dictionary for replacements, order matters + modules = [] + mod_dict = {} + members = results["members"] + for member in members: + # we only care about the actual members + if member.type == syms.import_as_name: + as_name = member.children[2].value + member_name = member.children[0].value + else: + member_name = member.value + as_name = None + if member_name != u",": + for change in MAPPING[mod_member.value]: + if member_name in change[1]: + if change[0] not in mod_dict: + modules.append(change[0]) + mod_dict.setdefault(change[0], []).append(member) + + new_nodes = [] + indentation = find_indentation(node) + first = True + def handle_name(name, prefix): + if name.type == syms.import_as_name: + kids = [Name(name.children[0].value, prefix=prefix), + name.children[1].clone(), + name.children[2].clone()] + return [Node(syms.import_as_name, kids)] + return [Name(name.value, prefix=prefix)] + for module in modules: + elts = mod_dict[module] + names = [] + for elt in elts[:-1]: + names.extend(handle_name(elt, pref)) + names.append(Comma()) + names.extend(handle_name(elts[-1], pref)) + new = FromImport(module, names) + if not first or node.parent.prefix.endswith(indentation): + new.prefix = indentation + new_nodes.append(new) + first = False + if new_nodes: + nodes = [] + for new_node in new_nodes[:-1]: + nodes.extend([new_node, Newline()]) + nodes.append(new_nodes[-1]) + node.replace(nodes) + else: + self.cannot_convert(node, "All module elements are invalid") + + def transform_dot(self, node, results): + """Transform for calls to module members in code.""" + module_dot = results.get("bare_with_attr") + member = results.get("member") + new_name = None + if isinstance(member, list): + member = member[0] + for change in MAPPING[module_dot.value]: + if member.value in change[1]: + new_name = change[0] + break + if new_name: + module_dot.replace(Name(new_name, + prefix=module_dot.prefix)) + else: + self.cannot_convert(node, "This is an invalid module element") + + def transform(self, node, results): + if results.get("module"): + self.transform_import(node, results) + elif results.get("mod_member"): + self.transform_member(node, results) + elif results.get("bare_with_attr"): + self.transform_dot(node, results) + # Renaming and star imports are not supported for these modules. + elif results.get("module_star"): + self.cannot_convert(node, "Cannot handle star imports.") + elif results.get("module_as"): + self.cannot_convert(node, "This module is now multiple modules") diff --git a/PythonHome/Lib/lib2to3/fixes/fix_urllib.pyc b/PythonHome/Lib/lib2to3/fixes/fix_urllib.pyc deleted file mode 100644 index 582b6e64b41900e4188026c81aa13a08667dbfc1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 7025 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 + """ + + COMMA = pytree.Leaf(token.COMMA, u",") + COLON = pytree.Leaf(token.COLON, u":") + SEPS = (COMMA, COLON) + + def transform(self, node, results): + new = node.clone() + comma = False + for child in new.children: + if child in self.SEPS: + prefix = child.prefix + if prefix.isspace() and u"\n" not in prefix: + child.prefix = u"" + comma = True + else: + if comma: + prefix = child.prefix + if not prefix: + child.prefix = u" " + comma = False + return new diff --git a/PythonHome/Lib/lib2to3/fixes/fix_ws_comma.pyc b/PythonHome/Lib/lib2to3/fixes/fix_ws_comma.pyc deleted file mode 100644 index 6144ad2dc41aed7672a0e92d6782df2d58d0262a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1351 zcmbVM!A{#i5S?`#hqzRw2P6(0R_Y<9jX1P7gis*`wGss6L_$rWu48YAgX0a}wE&Sw zmFSHx=qL0K`d|Hl&a6Rz#G$I?9nZ|Zot=3*>&ly9)VQe|87F3fDMV2ro2` zCC165=2{lfkV`!jxmzf7$^nmLDl@gp`KPCW{0?|NOteswFcO$RVqvx(L!liMlS`co zQQB2<%2Sb*rihZg<;n`#1@vyj>9vd~+v=#Mb`a z-lnOiwZFUH_K73^C5ro^jP|dU`9v0_sz^ANV>{L&TV(TA+x$RGPC*dM2n#?2l!;L) qlM|7>HJSNzZw+z_ZzEnr6ZJncGL)>BEN#$lKoN + rest=any* > + """ + + def start_tree(self, tree, filename): + super(FixXrange, self).start_tree(tree, filename) + self.transformed_xranges = set() + + def finish_tree(self, tree, filename): + self.transformed_xranges = None + + def transform(self, node, results): + name = results["name"] + if name.value == u"xrange": + return self.transform_xrange(node, results) + elif name.value == u"range": + return self.transform_range(node, results) + else: + raise ValueError(repr(name)) + + def transform_xrange(self, node, results): + name = results["name"] + name.replace(Name(u"range", prefix=name.prefix)) + # This prevents the new range call from being wrapped in a list later. + self.transformed_xranges.add(id(node)) + + def transform_range(self, node, results): + if (id(node) not in self.transformed_xranges and + not self.in_special_context(node)): + range_call = Call(Name(u"range"), [results["args"].clone()]) + # Encase the range call in list(). + list_call = Call(Name(u"list"), [range_call], + prefix=node.prefix) + # Put things that were after the range() call after the list call. + for n in results["rest"]: + list_call.append_child(n) + return list_call + + P1 = "power< func=NAME trailer< '(' node=any ')' > any* >" + p1 = patcomp.compile_pattern(P1) + + P2 = """for_stmt< 'for' any 'in' node=any ':' any* > + | comp_for< 'for' any 'in' node=any any* > + | comparison< any 'in' node=any any*> + """ + p2 = patcomp.compile_pattern(P2) + + def in_special_context(self, node): + if node.parent is None: + return False + results = {} + if (node.parent.parent is not None and + self.p1.match(node.parent.parent, results) and + results["node"] is node): + # list(d.keys()) -> list(d.keys()), etc. + return results["func"].value in consuming_calls + # for ... in d.iterkeys() -> for ... in d.keys(), etc. + return self.p2.match(node.parent, results) and results["node"] is node diff --git a/PythonHome/Lib/lib2to3/fixes/fix_xrange.pyc b/PythonHome/Lib/lib2to3/fixes/fix_xrange.pyc deleted file mode 100644 index 55aca33a51fc64d408ad1bb6e557ee4ec81539d4..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2967 zcmbVO+io015UrlQc^xOV69QO?U_eN_&Vx~sH!XP4<- za3uSM@W2D`zz^^n{1-pKIn|q8Cj<${a`*PFx~oo|s+!v0XP5ta@?C!@v%eaCZ==~5 zT`Dp_ZzK(*Ffs~c5QyQtCPhs~bs5xU)Q~|#Mok$s{a#(qwq(%4ydha2`%AI|p{D#S z@?7NWL0i(6^t(%Z=woyb^24kO-Cp9t;a*biW;Q&m_}ksu+S&~B(v8E#d@Bzi(>3Va zGP)f~$J>d`x>VoQ(e;v1rh|J)QMgsC49BINj`DIh9%9LQ@fJ2Fi5reb6W7KVihQLH z%>m(4chRgvmjMt%iv~3Xr%rHS6aWB395jgy2Q5kKI#?2bz!ew`kd`GoBl|0oEz5Hw zgR?|paPGz8IbB?pbV)_lB@{K z0msJG=yYtvfJ@+ZIV}DZOc3Qn}bwSq4E&Gv_YwDD1I2<7$+pvA4!9 zylt~$N4>3Lq}2|rr0HFZMLYWeMq5w6$hV&s`Svw8zW$WNvFv9zZcUy=WW-x&wvJBB zhM8MSCaAS%F@Pbo2&`UM!~>pu<1&lrHq|hqRnZxCD_lc6jYf`=J9(MgJw@eROf8=h zuNw6vP^#Lu7yx##a^turM>W}ps(~B?Qf*SisdL3w@N%efvXFOf$EJjk*73SZho!7FAB8`Adr2uc~pSk5t*D z>hev6(Z4%RGeu*vF0hF%^2pol-UN_n9g-iRSt>vrE_(zxog?rECWv%zk|)$bORC=&?18B(n0xks zh?or z`m$hObA3;PPniH&}G=WC3JDjgdWFA+&CVM(`mseL+EjZG*0F3K16hk z@X3^K7d{C;y7Tz){ivsfGdhPO(L3yTt@2eZd2}`6HM0+~(FD~w#w9MR%BaH)BJt>2 z#1Dyx`Yw#r(f=&oOjC?a%P4J{W}_Lj>+M>*-EOv5nr5|u7WBHy*wqXh$LV+o6ET;F y-HGqXsmlwWdNmEuDc%NFp1b(i#J8e;wY-t4iuetW@hw7Q>4Ii$&0IEXwSNH7_dlrs diff --git a/PythonHome/Lib/lib2to3/fixes/fix_xreadlines.py b/PythonHome/Lib/lib2to3/fixes/fix_xreadlines.py new file mode 100644 index 0000000000..f50b9a2755 --- /dev/null +++ b/PythonHome/Lib/lib2to3/fixes/fix_xreadlines.py @@ -0,0 +1,25 @@ +"""Fix "for x in f.xreadlines()" -> "for x in f". + +This fixer will also convert g(f.xreadlines) into g(f.__iter__).""" +# Author: Collin Winter + +# Local imports +from .. import fixer_base +from ..fixer_util import Name + + +class FixXreadlines(fixer_base.BaseFix): + BM_compatible = True + PATTERN = """ + power< call=any+ trailer< '.' 'xreadlines' > trailer< '(' ')' > > + | + power< any+ trailer< '.' no_call='xreadlines' > > + """ + + def transform(self, node, results): + no_call = results.get("no_call") + + if no_call: + no_call.replace(Name(u"__iter__", prefix=no_call.prefix)) + else: + node.replace([x.clone() for x in results["call"]]) diff --git a/PythonHome/Lib/lib2to3/fixes/fix_xreadlines.pyc b/PythonHome/Lib/lib2to3/fixes/fix_xreadlines.pyc deleted file mode 100644 index b66d6938395151e88f61c19e6b600608f0c259e7..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1121 zcmbVL&5qMB5FRIKfT9&EIB`H&l~7X6Ta{Kez>@yvW<|K~yT$Jl#rXqnt3+u!YIobby{o*DORfGTz%st$7PhY9YsaBIm zwmdqefiQ$($47T@Zm*#w@>Lj|)%+F;hAIGd!wcD6FQN);T~mSMBZQkSA@VX?Y7!~A zQMIfGtN&W0WxhzPn&>*qH_t|+lXwu**zNNB$0TE#x9hkJr4zES5qbmn)LbWo$jTH` pK^?>ddoN&Vm3EzVmVJB=IQ%Z&e`n*`aa=c`N8PWp3J%$!{|mP=^&tQN diff --git a/PythonHome/Lib/lib2to3/fixes/fix_zip.py b/PythonHome/Lib/lib2to3/fixes/fix_zip.py new file mode 100644 index 0000000000..c5d7b66d67 --- /dev/null +++ b/PythonHome/Lib/lib2to3/fixes/fix_zip.py @@ -0,0 +1,35 @@ +""" +Fixer that changes zip(seq0, seq1, ...) into list(zip(seq0, seq1, ...) +unless there exists a 'from future_builtins import zip' statement in the +top-level namespace. + +We avoid the transformation if the zip() call is directly contained in +iter(<>), list(<>), tuple(<>), sorted(<>), ...join(<>), or for V in <>:. +""" + +# Local imports +from .. import fixer_base +from ..fixer_util import Name, Call, in_special_context + +class FixZip(fixer_base.ConditionalFix): + + BM_compatible = True + PATTERN = """ + power< 'zip' args=trailer< '(' [any] ')' > + > + """ + + skip_on = "future_builtins.zip" + + def transform(self, node, results): + if self.should_skip(node): + return + + if in_special_context(node): + return None + + new = node.clone() + new.prefix = u"" + new = Call(Name(u"list"), [new]) + new.prefix = node.prefix + return new diff --git a/PythonHome/Lib/lib2to3/fixes/fix_zip.pyc b/PythonHome/Lib/lib2to3/fixes/fix_zip.pyc deleted file mode 100644 index 846ab3cdde339d9d603016e560b51d43f0695c30..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1315 zcmb7DU2oM!5FPtE7ckHw@{)(DT8W42NapKO z%6~KGx>tN!v8qoiccO#(%XCH1e}2ECU~liJ`Fy^ujAO5?30!>YIvtzz&Gtgo-f?A|ZcrdMtovejZ+mC# zBzin_R*#1Puyix}X!^_>H*S2dP)|J)kh^<#=DA5hU;+M!bC|V|Sgxv|3z3a8m;=C% z&ORXVO`I54hECU}vZbKX=gd`WT>SZ zX-3}rSm7DW-$ZAy3B5|F-xOSjoV?xNihEq1O=RN!0dCw)sLY5r2n_=|zQf505~LC! z!P%P_oR1wH45&nd6pvFU6U$d&!l@r@Q-o8ajEcu*%S>Q#{gm2-^kAF9-V{2AFu>bK`v<_lR5H#;D_zFVa zjpPm*CB#dRgwO0FgGr{l}GDodH|vW&A+maT6FD_cQ$)DN1k!?|}KQ_^;r z@s%A>KK$kA=-0(TL@e!>-Yq2ZJ>1X5ypT#?VFiIRO{W=FdQikxgpjgqd<{f!X(8r= tF(262$mqyz)If6Wd)FBGBP)xMjwQYvS>$JTWMogk1<`UkxsiO6z6Kw{EL8vi diff --git a/PythonHome/Lib/lib2to3/main.py b/PythonHome/Lib/lib2to3/main.py new file mode 100644 index 0000000000..ad0625e527 --- /dev/null +++ b/PythonHome/Lib/lib2to3/main.py @@ -0,0 +1,269 @@ +""" +Main program for 2to3. +""" + +from __future__ import with_statement + +import sys +import os +import difflib +import logging +import shutil +import optparse + +from . import refactor + + +def diff_texts(a, b, filename): + """Return a unified diff of two strings.""" + a = a.splitlines() + b = b.splitlines() + return difflib.unified_diff(a, b, filename, filename, + "(original)", "(refactored)", + lineterm="") + + +class StdoutRefactoringTool(refactor.MultiprocessRefactoringTool): + """ + A refactoring tool that can avoid overwriting its input files. + Prints output to stdout. + + Output files can optionally be written to a different directory and or + have an extra file suffix appended to their name for use in situations + where you do not want to replace the input files. + """ + + def __init__(self, fixers, options, explicit, nobackups, show_diffs, + input_base_dir='', output_dir='', append_suffix=''): + """ + Args: + fixers: A list of fixers to import. + options: A dict with RefactoringTool configuration. + explicit: A list of fixers to run even if they are explicit. + nobackups: If true no backup '.bak' files will be created for those + files that are being refactored. + show_diffs: Should diffs of the refactoring be printed to stdout? + input_base_dir: The base directory for all input files. This class + will strip this path prefix off of filenames before substituting + it with output_dir. Only meaningful if output_dir is supplied. + All files processed by refactor() must start with this path. + output_dir: If supplied, all converted files will be written into + this directory tree instead of input_base_dir. + append_suffix: If supplied, all files output by this tool will have + this appended to their filename. Useful for changing .py to + .py3 for example by passing append_suffix='3'. + """ + self.nobackups = nobackups + self.show_diffs = show_diffs + if input_base_dir and not input_base_dir.endswith(os.sep): + input_base_dir += os.sep + self._input_base_dir = input_base_dir + self._output_dir = output_dir + self._append_suffix = append_suffix + super(StdoutRefactoringTool, self).__init__(fixers, options, explicit) + + def log_error(self, msg, *args, **kwargs): + self.errors.append((msg, args, kwargs)) + self.logger.error(msg, *args, **kwargs) + + def write_file(self, new_text, filename, old_text, encoding): + orig_filename = filename + if self._output_dir: + if filename.startswith(self._input_base_dir): + filename = os.path.join(self._output_dir, + filename[len(self._input_base_dir):]) + else: + raise ValueError('filename %s does not start with the ' + 'input_base_dir %s' % ( + filename, self._input_base_dir)) + if self._append_suffix: + filename += self._append_suffix + if orig_filename != filename: + output_dir = os.path.dirname(filename) + if not os.path.isdir(output_dir): + os.makedirs(output_dir) + self.log_message('Writing converted %s to %s.', orig_filename, + filename) + if not self.nobackups: + # Make backup + backup = filename + ".bak" + if os.path.lexists(backup): + try: + os.remove(backup) + except os.error, err: + self.log_message("Can't remove backup %s", backup) + try: + os.rename(filename, backup) + except os.error, err: + self.log_message("Can't rename %s to %s", filename, backup) + # Actually write the new file + write = super(StdoutRefactoringTool, self).write_file + write(new_text, filename, old_text, encoding) + if not self.nobackups: + shutil.copymode(backup, filename) + if orig_filename != filename: + # Preserve the file mode in the new output directory. + shutil.copymode(orig_filename, filename) + + def print_output(self, old, new, filename, equal): + if equal: + self.log_message("No changes to %s", filename) + else: + self.log_message("Refactored %s", filename) + if self.show_diffs: + diff_lines = diff_texts(old, new, filename) + try: + if self.output_lock is not None: + with self.output_lock: + for line in diff_lines: + print line + sys.stdout.flush() + else: + for line in diff_lines: + print line + except UnicodeEncodeError: + warn("couldn't encode %s's diff for your terminal" % + (filename,)) + return + + +def warn(msg): + print >> sys.stderr, "WARNING: %s" % (msg,) + + +def main(fixer_pkg, args=None): + """Main program. + + Args: + fixer_pkg: the name of a package where the fixers are located. + args: optional; a list of command line arguments. If omitted, + sys.argv[1:] is used. + + Returns a suggested exit status (0, 1, 2). + """ + # Set up option parser + parser = optparse.OptionParser(usage="2to3 [options] file|dir ...") + parser.add_option("-d", "--doctests_only", action="store_true", + help="Fix up doctests only") + parser.add_option("-f", "--fix", action="append", default=[], + help="Each FIX specifies a transformation; default: all") + parser.add_option("-j", "--processes", action="store", default=1, + type="int", help="Run 2to3 concurrently") + parser.add_option("-x", "--nofix", action="append", default=[], + help="Prevent a transformation from being run") + parser.add_option("-l", "--list-fixes", action="store_true", + help="List available transformations") + parser.add_option("-p", "--print-function", action="store_true", + help="Modify the grammar so that print() is a function") + parser.add_option("-v", "--verbose", action="store_true", + help="More verbose logging") + parser.add_option("--no-diffs", action="store_true", + help="Don't show diffs of the refactoring") + parser.add_option("-w", "--write", action="store_true", + help="Write back modified files") + parser.add_option("-n", "--nobackups", action="store_true", default=False, + help="Don't write backups for modified files") + parser.add_option("-o", "--output-dir", action="store", type="str", + default="", help="Put output files in this directory " + "instead of overwriting the input files. Requires -n.") + parser.add_option("-W", "--write-unchanged-files", action="store_true", + help="Also write files even if no changes were required" + " (useful with --output-dir); implies -w.") + parser.add_option("--add-suffix", action="store", type="str", default="", + help="Append this string to all output filenames." + " Requires -n if non-empty. " + "ex: --add-suffix='3' will generate .py3 files.") + + # Parse command line arguments + refactor_stdin = False + flags = {} + options, args = parser.parse_args(args) + if options.write_unchanged_files: + flags["write_unchanged_files"] = True + if not options.write: + warn("--write-unchanged-files/-W implies -w.") + options.write = True + # If we allowed these, the original files would be renamed to backup names + # but not replaced. + if options.output_dir and not options.nobackups: + parser.error("Can't use --output-dir/-o without -n.") + if options.add_suffix and not options.nobackups: + parser.error("Can't use --add-suffix without -n.") + + if not options.write and options.no_diffs: + warn("not writing files and not printing diffs; that's not very useful") + if not options.write and options.nobackups: + parser.error("Can't use -n without -w") + if options.list_fixes: + print "Available transformations for the -f/--fix option:" + for fixname in refactor.get_all_fix_names(fixer_pkg): + print fixname + if not args: + return 0 + if not args: + print >> sys.stderr, "At least one file or directory argument required." + print >> sys.stderr, "Use --help to show usage." + return 2 + if "-" in args: + refactor_stdin = True + if options.write: + print >> sys.stderr, "Can't write to stdin." + return 2 + if options.print_function: + flags["print_function"] = True + + # Set up logging handler + level = logging.DEBUG if options.verbose else logging.INFO + logging.basicConfig(format='%(name)s: %(message)s', level=level) + logger = logging.getLogger('lib2to3.main') + + # Initialize the refactoring tool + avail_fixes = set(refactor.get_fixers_from_package(fixer_pkg)) + unwanted_fixes = set(fixer_pkg + ".fix_" + fix for fix in options.nofix) + explicit = set() + if options.fix: + all_present = False + for fix in options.fix: + if fix == "all": + all_present = True + else: + explicit.add(fixer_pkg + ".fix_" + fix) + requested = avail_fixes.union(explicit) if all_present else explicit + else: + requested = avail_fixes.union(explicit) + fixer_names = requested.difference(unwanted_fixes) + input_base_dir = os.path.commonprefix(args) + if (input_base_dir and not input_base_dir.endswith(os.sep) + and not os.path.isdir(input_base_dir)): + # One or more similar names were passed, their directory is the base. + # os.path.commonprefix() is ignorant of path elements, this corrects + # for that weird API. + input_base_dir = os.path.dirname(input_base_dir) + if options.output_dir: + input_base_dir = input_base_dir.rstrip(os.sep) + logger.info('Output in %r will mirror the input directory %r layout.', + options.output_dir, input_base_dir) + rt = StdoutRefactoringTool( + sorted(fixer_names), flags, sorted(explicit), + options.nobackups, not options.no_diffs, + input_base_dir=input_base_dir, + output_dir=options.output_dir, + append_suffix=options.add_suffix) + + # Refactor all files and directories passed as arguments + if not rt.errors: + if refactor_stdin: + rt.refactor_stdin() + else: + try: + rt.refactor(args, options.write, options.doctests_only, + options.processes) + except refactor.MultiprocessingUnsupported: + assert options.processes > 1 + print >> sys.stderr, "Sorry, -j isn't " \ + "supported on this platform." + return 1 + rt.summarize() + + # Return error status (0 if rt.errors is zero) + return int(bool(rt.errors)) diff --git a/PythonHome/Lib/lib2to3/main.pyc b/PythonHome/Lib/lib2to3/main.pyc deleted file mode 100644 index 70ebd87996ea15a6c47fd30c51ff92e862f3f7ed..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 9681 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 3 and nodes[1].type == token.EQUAL: + name = nodes[0].value + nodes = nodes[2:] + repeat = None + if len(nodes) >= 2 and nodes[-1].type == self.syms.Repeater: + repeat = nodes[-1] + nodes = nodes[:-1] + + # Now we've reduced it to: STRING | NAME [Details] | (...) | [...] + pattern = self.compile_basic(nodes, repeat) + + if repeat is not None: + assert repeat.type == self.syms.Repeater + children = repeat.children + child = children[0] + if child.type == token.STAR: + min = 0 + max = pytree.HUGE + elif child.type == token.PLUS: + min = 1 + max = pytree.HUGE + elif child.type == token.LBRACE: + assert children[-1].type == token.RBRACE + assert len(children) in (3, 5) + min = max = self.get_int(children[1]) + if len(children) == 5: + max = self.get_int(children[3]) + else: + assert False + if min != 1 or max != 1: + pattern = pattern.optimize() + pattern = pytree.WildcardPattern([[pattern]], min=min, max=max) + + if name is not None: + pattern.name = name + return pattern.optimize() + + def compile_basic(self, nodes, repeat=None): + # Compile STRING | NAME [Details] | (...) | [...] + assert len(nodes) >= 1 + node = nodes[0] + if node.type == token.STRING: + value = unicode(literals.evalString(node.value)) + return pytree.LeafPattern(_type_of_literal(value), value) + elif node.type == token.NAME: + value = node.value + if value.isupper(): + if value not in TOKEN_MAP: + raise PatternSyntaxError("Invalid token: %r" % value) + if nodes[1:]: + raise PatternSyntaxError("Can't have details for token") + return pytree.LeafPattern(TOKEN_MAP[value]) + else: + if value == "any": + type = None + elif not value.startswith("_"): + type = getattr(self.pysyms, value, None) + if type is None: + raise PatternSyntaxError("Invalid symbol: %r" % value) + if nodes[1:]: # Details present + content = [self.compile_node(nodes[1].children[1])] + else: + content = None + return pytree.NodePattern(type, content) + elif node.value == "(": + return self.compile_node(nodes[1]) + elif node.value == "[": + assert repeat is None + subpattern = self.compile_node(nodes[1]) + return pytree.WildcardPattern([[subpattern]], min=0, max=1) + assert False, node + + def get_int(self, node): + assert node.type == token.NUMBER + return int(node.value) + + +# Map named tokens to the type value for a LeafPattern +TOKEN_MAP = {"NAME": token.NAME, + "STRING": token.STRING, + "NUMBER": token.NUMBER, + "TOKEN": None} + + +def _type_of_literal(value): + if value[0].isalpha(): + return token.NAME + elif value in grammar.opmap: + return grammar.opmap[value] + else: + return None + + +def pattern_convert(grammar, raw_node_info): + """Converts raw node information to a Node or Leaf instance.""" + type, value, context, children = raw_node_info + if children or type in grammar.number2symbol: + return pytree.Node(type, children, context=context) + else: + return pytree.Leaf(type, value, context=context) + + +def compile_pattern(pattern): + return PatternCompiler().compile_pattern(pattern) diff --git a/PythonHome/Lib/lib2to3/patcomp.pyc b/PythonHome/Lib/lib2to3/patcomp.pyc deleted file mode 100644 index 58a7ceaaa8af096ee39d96270f751227444606cf..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6486 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 diff --git a/PythonHome/Lib/lib2to3/pgen2/__init__.py b/PythonHome/Lib/lib2to3/pgen2/__init__.py new file mode 100644 index 0000000000..af39048452 --- /dev/null +++ b/PythonHome/Lib/lib2to3/pgen2/__init__.py @@ -0,0 +1,4 @@ +# Copyright 2004-2005 Elemental Security, Inc. All Rights Reserved. +# Licensed to PSF under a Contributor Agreement. + +"""The pgen2 package.""" diff --git a/PythonHome/Lib/lib2to3/pgen2/__init__.pyc b/PythonHome/Lib/lib2to3/pgen2/__init__.pyc deleted file mode 100644 index e2df8002a552c58b5ff8fa07e2c14013fc5a605d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 159 zcmZSn%*(YSJRvxl0SXv_v;zVK0YNsIX+$k$Yeke#qvO|UW`v>QcO-}l2J*%aSYgmnE3e2yv&mL ac)fzk5)Pmmo80`A(wtN~79hJAh#3G3mLNp{ diff --git a/PythonHome/Lib/lib2to3/pgen2/conv.py b/PythonHome/Lib/lib2to3/pgen2/conv.py new file mode 100644 index 0000000000..28fbb0b95f --- /dev/null +++ b/PythonHome/Lib/lib2to3/pgen2/conv.py @@ -0,0 +1,257 @@ +# Copyright 2004-2005 Elemental Security, Inc. All Rights Reserved. +# Licensed to PSF under a Contributor Agreement. + +"""Convert graminit.[ch] spit out by pgen to Python code. + +Pgen is the Python parser generator. It is useful to quickly create a +parser from a grammar file in Python's grammar notation. But I don't +want my parsers to be written in C (yet), so I'm translating the +parsing tables to Python data structures and writing a Python parse +engine. + +Note that the token numbers are constants determined by the standard +Python tokenizer. The standard token module defines these numbers and +their names (the names are not used much). The token numbers are +hardcoded into the Python tokenizer and into pgen. A Python +implementation of the Python tokenizer is also available, in the +standard tokenize module. + +On the other hand, symbol numbers (representing the grammar's +non-terminals) are assigned by pgen based on the actual grammar +input. + +Note: this module is pretty much obsolete; the pgen module generates +equivalent grammar tables directly from the Grammar.txt input file +without having to invoke the Python pgen C program. + +""" + +# Python imports +import re + +# Local imports +from pgen2 import grammar, token + + +class Converter(grammar.Grammar): + """Grammar subclass that reads classic pgen output files. + + The run() method reads the tables as produced by the pgen parser + generator, typically contained in two C files, graminit.h and + graminit.c. The other methods are for internal use only. + + See the base class for more documentation. + + """ + + def run(self, graminit_h, graminit_c): + """Load the grammar tables from the text files written by pgen.""" + self.parse_graminit_h(graminit_h) + self.parse_graminit_c(graminit_c) + self.finish_off() + + def parse_graminit_h(self, filename): + """Parse the .h file written by pgen. (Internal) + + This file is a sequence of #define statements defining the + nonterminals of the grammar as numbers. We build two tables + mapping the numbers to names and back. + + """ + try: + f = open(filename) + except IOError, err: + print "Can't open %s: %s" % (filename, err) + return False + self.symbol2number = {} + self.number2symbol = {} + lineno = 0 + for line in f: + lineno += 1 + mo = re.match(r"^#define\s+(\w+)\s+(\d+)$", line) + if not mo and line.strip(): + print "%s(%s): can't parse %s" % (filename, lineno, + line.strip()) + else: + symbol, number = mo.groups() + number = int(number) + assert symbol not in self.symbol2number + assert number not in self.number2symbol + self.symbol2number[symbol] = number + self.number2symbol[number] = symbol + return True + + def parse_graminit_c(self, filename): + """Parse the .c file written by pgen. (Internal) + + The file looks as follows. The first two lines are always this: + + #include "pgenheaders.h" + #include "grammar.h" + + After that come four blocks: + + 1) one or more state definitions + 2) a table defining dfas + 3) a table defining labels + 4) a struct defining the grammar + + A state definition has the following form: + - one or more arc arrays, each of the form: + static arc arcs__[] = { + {, }, + ... + }; + - followed by a state array, of the form: + static state states_[] = { + {, arcs__}, + ... + }; + + """ + try: + f = open(filename) + except IOError, err: + print "Can't open %s: %s" % (filename, err) + return False + # The code below essentially uses f's iterator-ness! + lineno = 0 + + # Expect the two #include lines + lineno, line = lineno+1, f.next() + assert line == '#include "pgenheaders.h"\n', (lineno, line) + lineno, line = lineno+1, f.next() + assert line == '#include "grammar.h"\n', (lineno, line) + + # Parse the state definitions + lineno, line = lineno+1, f.next() + allarcs = {} + states = [] + while line.startswith("static arc "): + while line.startswith("static arc "): + mo = re.match(r"static arc arcs_(\d+)_(\d+)\[(\d+)\] = {$", + line) + assert mo, (lineno, line) + n, m, k = map(int, mo.groups()) + arcs = [] + for _ in range(k): + lineno, line = lineno+1, f.next() + mo = re.match(r"\s+{(\d+), (\d+)},$", line) + assert mo, (lineno, line) + i, j = map(int, mo.groups()) + arcs.append((i, j)) + lineno, line = lineno+1, f.next() + assert line == "};\n", (lineno, line) + allarcs[(n, m)] = arcs + lineno, line = lineno+1, f.next() + mo = re.match(r"static state states_(\d+)\[(\d+)\] = {$", line) + assert mo, (lineno, line) + s, t = map(int, mo.groups()) + assert s == len(states), (lineno, line) + state = [] + for _ in range(t): + lineno, line = lineno+1, f.next() + mo = re.match(r"\s+{(\d+), arcs_(\d+)_(\d+)},$", line) + assert mo, (lineno, line) + k, n, m = map(int, mo.groups()) + arcs = allarcs[n, m] + assert k == len(arcs), (lineno, line) + state.append(arcs) + states.append(state) + lineno, line = lineno+1, f.next() + assert line == "};\n", (lineno, line) + lineno, line = lineno+1, f.next() + self.states = states + + # Parse the dfas + dfas = {} + mo = re.match(r"static dfa dfas\[(\d+)\] = {$", line) + assert mo, (lineno, line) + ndfas = int(mo.group(1)) + for i in range(ndfas): + lineno, line = lineno+1, f.next() + mo = re.match(r'\s+{(\d+), "(\w+)", (\d+), (\d+), states_(\d+),$', + line) + assert mo, (lineno, line) + symbol = mo.group(2) + number, x, y, z = map(int, mo.group(1, 3, 4, 5)) + assert self.symbol2number[symbol] == number, (lineno, line) + assert self.number2symbol[number] == symbol, (lineno, line) + assert x == 0, (lineno, line) + state = states[z] + assert y == len(state), (lineno, line) + lineno, line = lineno+1, f.next() + mo = re.match(r'\s+("(?:\\\d\d\d)*")},$', line) + assert mo, (lineno, line) + first = {} + rawbitset = eval(mo.group(1)) + for i, c in enumerate(rawbitset): + byte = ord(c) + for j in range(8): + if byte & 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 Q5@i&At5C>K= os.path.getmtime(b) + + +def main(*args): + """Main program, when run as a script: produce grammar pickle files. + + Calls load_grammar for each argument, a path to a grammar text file. + """ + if not args: + args = sys.argv[1:] + logging.basicConfig(level=logging.INFO, stream=sys.stdout, + format='%(message)s') + for gt in args: + load_grammar(gt, save=True, force=True) + return True + +if __name__ == "__main__": + sys.exit(int(not main())) diff --git a/PythonHome/Lib/lib2to3/pgen2/driver.pyc b/PythonHome/Lib/lib2to3/pgen2/driver.pyc deleted file mode 100644 index 034dd1be2a111ee7d7e9216e274619b803a6b72e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5223 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 delta 2435 zcmb7F&u<%55T3WT*Rf+KX;PvJL!oD$hu!CedPhU!rx^-i_Zz zX{tth2vX0;XAa!BqDmG24u1pU3d}d_#0f>T#M#-|d2i><_sx&}bM>dStnhoi`fKaE zW{)O+MZSN+mmRYRh}tX_1r9}u+N=~PC{pCmpg`>c4T{t*k_t*>O0>_*E`3jQPV}(t zQc$LLnL_q4LytDdl&N3A+UDLpYFEirX|&$Ltv?I%u0!n_wd-W&$P~!b>D(bRL#9US zM=j$27KhRFW)R&|MfA(*QF<3dEA zVeK0h%)}ES|58zOkXxLKB_a1f$+qH!v2>xh7fKo7z|{=mZF+#b!`>(8KhM5=@b$wG z0SG0sq6@t2afFoCS=iG-H;x*^<3ZPq#FDFxd?6J;X(u%{E%NqYzhlJ~b-E_9LhYeB zJ&8v_ZWo?yS`*iq_?E4b4x4sHsRus9nKjYA#}6dJ-ezrWcRTFvMq#&+#&>s<12b&w z9^~0tOHSoD-w%gj>igTg-7eyFRhj&1lY0+zGtMsvF$?c^SxK2?&a6T`ojH^$>N}vX z&m?lL9XcA`_rWidXguVyJ6pL9dqc7$#L5+__`U@8fFhmpydIvymG zc!RLV@d^XID7MB!3N+Z44f|nahMj@oc!>U!kn9CUGze(%WpO+?^J-ZMdc=)m1pGQH z{|=rpD>@VW%mPq@k0SL;^n{-kvw&8EC;L9}8QXCu82_+vbG$ycl+!Wl?nv3|1>U4@ z;3ym(@kV_UrX`pV-f<^xl@oHCxA{eJR3dpO(d$@p zQB%Ii$w<1x2abQ6yOU|~pwW~X(P%WCu0qVR$Y;e1J!oOM)`J#q(0Bs$qT3|ldAHfT z+osLt;kY!zdA{F^_)RW9*sS4JPDi32Omukf#mT7#jT(8<@OPz1LFdq%r0^%T3?DB~ zR(7RxHJUr%%c4rCSW^W~)*V&nUoB4>dJ2~$?J+Bp&kfOli1UVi+`5l!G3(sJuoR~j zsbqYBF86Fs3fP^RxUunCd1@);mKoa0leu+2sBpm}OZGz+-1cvbe_nVi|Gwn23mhfM zC>*9KsIiTq+=mUD(Xm{Jp096|8J#x-POU1hPT&FTyaVzCY-QM7(s<*QJ;8R^)UD3FGyRzNQCI2m*jf7CgV`72L?)+SMyM&WSsVS|=`qhOag vA15-%z>t2E-Ft+O_Z0Oj02Y$hb6P)^R>!<{3$?;>Vfjbban+J?)uQ?vvgW<) diff --git a/PythonHome/Lib/lib2to3/pgen2/literals.py b/PythonHome/Lib/lib2to3/pgen2/literals.py new file mode 100644 index 0000000000..0b3948a54e --- /dev/null +++ b/PythonHome/Lib/lib2to3/pgen2/literals.py @@ -0,0 +1,60 @@ +# Copyright 2004-2005 Elemental Security, Inc. All Rights Reserved. +# Licensed to PSF under a Contributor Agreement. + +"""Safely evaluate Python string literals without using eval().""" + +import re + +simple_escapes = {"a": "\a", + "b": "\b", + "f": "\f", + "n": "\n", + "r": "\r", + "t": "\t", + "v": "\v", + "'": "'", + '"': '"', + "\\": "\\"} + +def escape(m): + all, tail = m.group(0, 1) + assert all.startswith("\\") + esc = simple_escapes.get(tail) + if esc is not None: + return esc + if tail.startswith("x"): + hexes = tail[1:] + if len(hexes) < 2: + raise ValueError("invalid hex string escape ('\\%s')" % tail) + try: + i = int(hexes, 16) + except ValueError: + raise ValueError("invalid hex string escape ('\\%s')" % tail) + else: + try: + i = int(tail, 8) + except ValueError: + raise ValueError("invalid octal string escape ('\\%s')" % tail) + return chr(i) + +def evalString(s): + assert s.startswith("'") or s.startswith('"'), repr(s[:1]) + q = s[0] + if s[:3] == q*3: + q = q*3 + assert s.endswith(q), repr(s[-len(q):]) + assert len(s) >= 2*len(q) + s = s[len(q):-len(q)] + return re.sub(r"\\(\'|\"|\\|[abfnrtv]|x.{0,2}|[0-7]{1,3})", escape, s) + +def test(): + for i in range(256): + c = chr(i) + s = repr(c) + e = evalString(s) + if e != c: + print i, c, s, e + + +if __name__ == "__main__": + test() diff --git a/PythonHome/Lib/lib2to3/pgen2/literals.pyc b/PythonHome/Lib/lib2to3/pgen2/literals.pyc deleted file mode 100644 index 369aa5f458d5ed3038410c0f778d3e4188d08ad5..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1958 zcmb7E&2Jk;6o0d}N?Y&(e2T0OjUHDU-eATeRDF2a6g)WIyhK+c%)xO7@dk(P` zADHyQH)nA=h@J7jyl_Xo%(pI2vO_;joXO+V`rjll51c=+Z06|p@@n!oew$XIOx3ZB zMX!mzFM3n-1JN6zXQH=6&qc3`?nIv!{Y>PN$VIV-9j-rxw}STtUR!}>NOU}I?WISd zMzC?u)wYipe5QrGUsD- zjqSvJhjwW>xy4a6j(`7Je6Qo;^uIG?VaI?R=Dk7R@jk4Jb7z?@?gplxSZi{Z z^s>+LyqAl~CMW&WM8)D3pdj5iSH`&6%ZwOOlS#F&z)Dl3a$J%*ad(dLHgiF~@kC5< zno0>5C#e`vU$%ztHC6(XHd080orks>zD)MRG}&Ksy(eM+&}3_v6@*{yUjTNZVwW?} z><18}?x{I-Q#Dl?vY~FP8CAmDQg^*#oK+phfZIM{>hG9Lm z^$~#wwBmW0?t{{-RmcaeG0gIbj+o;-ffw}S@}RV2+8_R{hn^J1>G?@nwh=D@4p02E z-3r;CIk8xH;+QDY3nO&ALdUpOs(b{v2+mELDYF?=Ap=&0g9RG}GhyH|9AVfFmxkfu zFbs#U;{AgxcV~OU^VQdnSJpcSkn=1rMd~R4p9Rz_YEeB<9k%h# z_#!{^}7i6Zi(_1w{-)P4LCP&FKv8& z+9EvL8kepBSXUP@KxQ$Eb#s g=O;ZqNX: + if p.addtoken(...): # parse a token; may raise ParseError + break + root = p.rootnode # root of abstract syntax tree + + A Parser instance may be reused by calling setup() repeatedly. + + A Parser instance contains state pertaining to the current token + sequence, and should not be used concurrently by different threads + to parse separate token sequences. + + See driver.py for how to get input tokens by tokenizing a file or + string. + + Parsing is complete when addtoken() returns True; the root of the + abstract syntax tree can then be retrieved from the rootnode + instance variable. When a syntax error occurs, addtoken() raises + the ParseError exception. There is no error recovery; the parser + cannot be used after a syntax error was reported (but it can be + reinitialized by calling setup()). + + """ + + def __init__(self, grammar, convert=None): + """Constructor. + + The grammar argument is a grammar.Grammar instance; see the + grammar module for more information. + + The parser is not ready yet for parsing; you must call the + setup() method to get it started. + + The optional convert argument is a function mapping concrete + syntax tree nodes to abstract syntax tree nodes. If not + given, no conversion is done and the syntax tree produced is + the concrete syntax tree. If given, it must be a function of + two arguments, the first being the grammar (a grammar.Grammar + instance), and the second being the concrete syntax tree node + to be converted. The syntax tree is converted from the bottom + up. + + A concrete syntax tree node is a (type, value, context, nodes) + tuple, where type is the node type (a token or symbol number), + value is None for symbols and a string for tokens, context is + None or an opaque value used for error reporting (typically a + (lineno, offset) pair), and nodes is a list of children for + symbols, and None for tokens. + + An abstract syntax tree node may be anything; this is entirely + up to the converter function. + + """ + self.grammar = grammar + self.convert = convert or (lambda grammar, node: node) + + def setup(self, start=None): + """Prepare for parsing. + + This *must* be called before starting to parse. + + The optional argument is an alternative start symbol; it + defaults to the grammar's start symbol. + + You can use a Parser instance to parse any number of programs; + each time you call setup() the parser is reset to an initial + state determined by the (implicit or explicit) start symbol. + + """ + if start is None: + start = self.grammar.start + # Each stack entry is a tuple: (dfa, state, node). + # A node is a tuple: (type, value, context, children), + # where children is a list of nodes or None, and context may be None. + newnode = (start, None, None, []) + stackentry = (self.grammar.dfas[start], 0, newnode) + self.stack = [stackentry] + self.rootnode = None + self.used_names = set() # Aliased to self.rootnode.used_names in pop() + + def addtoken(self, type, value, context): + """Add a token; return True iff this is the end of the program.""" + # Map from token to label + ilabel = self.classify(type, value, context) + # Loop until the token is shifted; may raise exceptions + while True: + dfa, state, node = self.stack[-1] + states, first = dfa + arcs = states[state] + # Look for a state with this label + for i, newstate in arcs: + t, v = self.grammar.labels[i] + if ilabel == i: + # Look it up in the list of labels + assert t < 256 + # Shift a token; we're done with it + self.shift(type, value, newstate, context) + # Pop while we are in an accept-only state + state = newstate + while states[state] == [(0, state)]: + self.pop() + if not self.stack: + # Done parsing! + return True + dfa, state, node = self.stack[-1] + states, first = dfa + # Done with this token + return False + elif t >= 256: + # See if it's a symbol and if we're in its first set + itsdfa = self.grammar.dfas[t] + itsstates, itsfirst = itsdfa + if ilabel in itsfirst: + # Push a symbol + self.push(t, self.grammar.dfas[t], newstate, context) + break # To continue the outer while loop + else: + if (0, state) in arcs: + # An accepting state, pop it and try something else + self.pop() + if not self.stack: + # Done parsing, but another token is input + raise ParseError("too much input", + type, value, context) + else: + # No success finding a transition + raise ParseError("bad input", type, value, context) + + def classify(self, type, value, context): + """Turn a token into a label. (Internal)""" + if type == token.NAME: + # Keep a listing of all used names + self.used_names.add(value) + # Check for reserved words + ilabel = self.grammar.keywords.get(value) + if ilabel is not None: + return ilabel + ilabel = self.grammar.tokens.get(type) + if ilabel is None: + raise ParseError("bad token", type, value, context) + return ilabel + + def shift(self, type, value, newstate, context): + """Shift a token. (Internal)""" + dfa, state, node = self.stack[-1] + newnode = (type, value, context, None) + newnode = self.convert(self.grammar, newnode) + if newnode is not None: + node[-1].append(newnode) + self.stack[-1] = (dfa, newstate, node) + + def push(self, type, newdfa, newstate, context): + """Push a nonterminal. (Internal)""" + dfa, state, node = self.stack[-1] + newnode = (type, None, context, []) + self.stack[-1] = (dfa, newstate, node) + self.stack.append((newdfa, 0, newnode)) + + def pop(self): + """Pop a nonterminal. (Internal)""" + popdfa, popstate, popnode = self.stack.pop() + newnode = self.convert(self.grammar, popnode) + if newnode is not None: + if self.stack: + dfa, state, node = self.stack[-1] + node[-1].append(newnode) + else: + self.rootnode = newnode + self.rootnode.used_names = self.used_names diff --git a/PythonHome/Lib/lib2to3/pgen2/parse.pyc b/PythonHome/Lib/lib2to3/pgen2/parse.pyc deleted file mode 100644 index 3f9212c7344080dc1a2e1318e27e0b4b4d9cfd47..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 7056 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 JUGZ-&{}<8IsAd2F diff --git a/PythonHome/Lib/lib2to3/pgen2/pgen.py b/PythonHome/Lib/lib2to3/pgen2/pgen.py new file mode 100644 index 0000000000..63084a4cd5 --- /dev/null +++ b/PythonHome/Lib/lib2to3/pgen2/pgen.py @@ -0,0 +1,386 @@ +# Copyright 2004-2005 Elemental Security, Inc. All Rights Reserved. +# Licensed to PSF under a Contributor Agreement. + +# Pgen imports +from . import grammar, token, tokenize + +class PgenGrammar(grammar.Grammar): + pass + +class ParserGenerator(object): + + def __init__(self, filename, stream=None): + close_stream = None + if stream is None: + stream = open(filename) + close_stream = stream.close + self.filename = filename + self.stream = stream + self.generator = tokenize.generate_tokens(stream.readline) + self.gettoken() # Initialize lookahead + self.dfas, self.startsymbol = self.parse() + if close_stream is not None: + close_stream() + self.first = {} # map from symbol name to set of tokens + self.addfirstsets() + + def make_grammar(self): + c = PgenGrammar() + names = self.dfas.keys() + names.sort() + names.remove(self.startsymbol) + names.insert(0, self.startsymbol) + for name in names: + i = 256 + len(c.symbol2number) + c.symbol2number[name] = i + c.number2symbol[i] = name + for name in names: + dfa = self.dfas[name] + states = [] + for state in dfa: + arcs = [] + for label, next in state.arcs.iteritems(): + arcs.append((self.make_label(c, label), dfa.index(next))) + if state.isfinal: + arcs.append((0, dfa.index(state))) + states.append(arcs) + c.states.append(states) + c.dfas[c.symbol2number[name]] = (states, self.make_first(c, name)) + c.start = c.symbol2number[self.startsymbol] + return c + + def make_first(self, c, name): + rawfirst = self.first[name] + first = {} + for label in rawfirst: + ilabel = self.make_label(c, label) + ##assert ilabel not in first # XXX failed on <> ... != + first[ilabel] = 1 + return first + + def make_label(self, c, label): + # XXX Maybe this should be a method on a subclass of converter? + ilabel = len(c.labels) + if label[0].isalpha(): + # Either a symbol name or a named token + if label in c.symbol2number: + # A symbol name (a non-terminal) + if label in c.symbol2label: + return c.symbol2label[label] + else: + c.labels.append((c.symbol2number[label], None)) + c.symbol2label[label] = ilabel + return ilabel + else: + # A named token (NAME, NUMBER, STRING) + itoken = getattr(token, label, None) + assert isinstance(itoken, int), label + assert itoken in token.tok_name, label + if itoken in c.tokens: + return c.tokens[itoken] + else: + c.labels.append((itoken, None)) + c.tokens[itoken] = ilabel + return ilabel + else: + # Either a keyword or an operator + assert label[0] in ('"', "'"), label + value = eval(label) + if value[0].isalpha(): + # A keyword + if value in c.keywords: + return c.keywords[value] + else: + c.labels.append((token.NAME, value)) + c.keywords[value] = ilabel + return ilabel + else: + # An operator (any non-numeric token) + itoken = grammar.opmap[value] # Fails if unknown token + if itoken in c.tokens: + return c.tokens[itoken] + else: + c.labels.append((itoken, None)) + c.tokens[itoken] = ilabel + return ilabel + + def addfirstsets(self): + names = self.dfas.keys() + names.sort() + for name in names: + if name not in self.first: + self.calcfirst(name) + #print name, self.first[name].keys() + + def calcfirst(self, name): + dfa = self.dfas[name] + self.first[name] = None # dummy to detect left recursion + state = dfa[0] + totalset = {} + overlapcheck = {} + for label, next in state.arcs.iteritems(): + if label in self.dfas: + if label in self.first: + fset = self.first[label] + if fset is None: + raise ValueError("recursion for rule %r" % name) + else: + self.calcfirst(label) + fset = self.first[label] + totalset.update(fset) + overlapcheck[label] = fset + else: + totalset[label] = 1 + overlapcheck[label] = {label: 1} + inverse = {} + for label, itsfirst in overlapcheck.iteritems(): + for symbol in itsfirst: + if symbol in inverse: + raise ValueError("rule %s is ambiguous; %s is in the" + " first sets of %s as well as %s" % + (name, symbol, label, inverse[symbol])) + inverse[symbol] = label + self.first[name] = totalset + + def parse(self): + dfas = {} + startsymbol = None + # MSTART: (NEWLINE | RULE)* ENDMARKER + while self.type != token.ENDMARKER: + while self.type == token.NEWLINE: + self.gettoken() + # RULE: NAME ':' RHS NEWLINE + name = self.expect(token.NAME) + self.expect(token.OP, ":") + a, z = self.parse_rhs() + self.expect(token.NEWLINE) + #self.dump_nfa(name, a, z) + dfa = self.make_dfa(a, z) + #self.dump_dfa(name, dfa) + oldlen = len(dfa) + self.simplify_dfa(dfa) + newlen = len(dfa) + dfas[name] = dfa + #print name, oldlen, newlen + if startsymbol is None: + startsymbol = name + return dfas, startsymbol + + def make_dfa(self, start, finish): + # To turn an NFA into a DFA, we define the states of the DFA + # to correspond to *sets* of states of the NFA. Then do some + # state reduction. Let's represent sets as dicts with 1 for + # values. + assert isinstance(start, NFAState) + assert isinstance(finish, NFAState) + def closure(state): + base = {} + addclosure(state, base) + return base + def addclosure(state, base): + assert isinstance(state, NFAState) + if state in base: + return + base[state] = 1 + for label, next in state.arcs: + if label is None: + addclosure(next, base) + states = [DFAState(closure(start), finish)] + for state in states: # NB states grows while we're iterating + arcs = {} + for nfastate in state.nfaset: + for label, next in nfastate.arcs: + if label is not None: + addclosure(next, arcs.setdefault(label, {})) + for label, nfaset in arcs.iteritems(): + for st in states: + if st.nfaset == nfaset: + break + else: + st = DFAState(nfaset, finish) + states.append(st) + state.addarc(st, label) + return states # List of DFAState instances; first one is start + + def dump_nfa(self, name, start, finish): + print "Dump of NFA for", name + todo = [start] + for i, state in enumerate(todo): + print " State", i, state is finish and "(final)" or "" + for label, next in state.arcs: + if next in todo: + j = todo.index(next) + else: + j = len(todo) + todo.append(next) + if label is None: + print " -> %d" % j + else: + print " %s -> %d" % (label, j) + + def dump_dfa(self, name, dfa): + print "Dump of DFA for", name + for i, state in enumerate(dfa): + print " State", i, state.isfinal and "(final)" or "" + for label, next in state.arcs.iteritems(): + print " %s -> %d" % (label, dfa.index(next)) + + def simplify_dfa(self, dfa): + # This is not theoretically optimal, but works well enough. + # Algorithm: repeatedly look for two states that have the same + # set of arcs (same labels pointing to the same nodes) and + # unify them, until things stop changing. + + # dfa is a list of DFAState instances + changes = True + while changes: + changes = False + for i, state_i in enumerate(dfa): + for j in range(i+1, len(dfa)): + state_j = dfa[j] + if state_i == state_j: + #print " unify", i, j + del dfa[j] + for state in dfa: + state.unifystate(state_j, state_i) + changes = True + break + + def parse_rhs(self): + # RHS: ALT ('|' ALT)* + a, z = self.parse_alt() + if self.value != "|": + return a, z + else: + aa = NFAState() + zz = NFAState() + aa.addarc(a) + z.addarc(zz) + while self.value == "|": + self.gettoken() + a, z = self.parse_alt() + aa.addarc(a) + z.addarc(zz) + return aa, zz + + def parse_alt(self): + # ALT: ITEM+ + a, b = self.parse_item() + while (self.value in ("(", "[") or + self.type in (token.NAME, token.STRING)): + c, d = self.parse_item() + b.addarc(c) + b = d + return a, b + + def parse_item(self): + # ITEM: '[' RHS ']' | ATOM ['+' | '*'] + if self.value == "[": + self.gettoken() + a, z = self.parse_rhs() + self.expect(token.OP, "]") + a.addarc(z) + return a, z + else: + a, z = self.parse_atom() + value = self.value + if value not in ("+", "*"): + return a, z + self.gettoken() + z.addarc(a) + if value == "+": + return a, z + else: + return a, a + + def parse_atom(self): + # ATOM: '(' RHS ')' | NAME | STRING + if self.value == "(": + self.gettoken() + a, z = self.parse_rhs() + self.expect(token.OP, ")") + return a, z + elif self.type in (token.NAME, token.STRING): + a = NFAState() + z = NFAState() + a.addarc(z, self.value) + self.gettoken() + return a, z + else: + self.raise_error("expected (...) or NAME or STRING, got %s/%s", + self.type, self.value) + + def expect(self, type, value=None): + if self.type != type or (value is not None and self.value != value): + self.raise_error("expected %s/%s, got %s/%s", + type, value, self.type, self.value) + value = self.value + self.gettoken() + return value + + def gettoken(self): + tup = self.generator.next() + while tup[0] in (tokenize.COMMENT, tokenize.NL): + tup = self.generator.next() + self.type, self.value, self.begin, self.end, self.line = tup + #print token.tok_name[self.type], repr(self.value) + + def raise_error(self, msg, *args): + if args: + try: + msg = msg % args + except: + msg = " ".join([msg] + map(str, args)) + raise SyntaxError(msg, (self.filename, self.end[0], + self.end[1], self.line)) + +class NFAState(object): + + def __init__(self): + self.arcs = [] # list of (label, NFAState) pairs + + def addarc(self, next, label=None): + assert label is None or isinstance(label, str) + assert isinstance(next, NFAState) + self.arcs.append((label, next)) + +class DFAState(object): + + def __init__(self, nfaset, final): + assert isinstance(nfaset, dict) + assert isinstance(iter(nfaset).next(), NFAState) + assert isinstance(final, NFAState) + self.nfaset = nfaset + self.isfinal = final in nfaset + self.arcs = {} # map from label to DFAState + + def addarc(self, next, label): + assert isinstance(label, str) + assert label not in self.arcs + assert isinstance(next, DFAState) + self.arcs[label] = next + + def unifystate(self, old, new): + for label, next in self.arcs.iteritems(): + if next is old: + self.arcs[label] = new + + def __eq__(self, other): + # Equality test -- ignore the nfaset instance variable + assert isinstance(other, DFAState) + if self.isfinal != other.isfinal: + return False + # Can't just return self.arcs == other.arcs, because that + # would invoke this method recursively, with cycles... + if len(self.arcs) != len(other.arcs): + return False + for label, next in self.arcs.iteritems(): + if next is not other.arcs.get(label): + return False + return True + + __hash__ = None # For Py3 compatibility. + +def generate_grammar(filename="Grammar.txt"): + p = ParserGenerator(filename) + return p.make_grammar() diff --git a/PythonHome/Lib/lib2to3/pgen2/pgen.pyc b/PythonHome/Lib/lib2to3/pgen2/pgen.pyc deleted file mode 100644 index c008e69806b282f1a2797aa782f185ffb2c58f6d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 11693 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 NT_OFFSET + +def ISEOF(x): + return x == ENDMARKER diff --git a/PythonHome/Lib/lib2to3/pgen2/token.pyc b/PythonHome/Lib/lib2to3/pgen2/token.pyc deleted file mode 100644 index a83745716927c97b374e720e234b5bd7bf9d4f85..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2243 zcmc(f>2ecC5Xb+rv3y~CaTwcx?}Ni&8;k*iSxIYK<<+jeyN**`PASH%5XFZGT2fGz z;tM=fo+Gc47s&i)1%fZRzC_ag)YCKD-P7GOt$*}%{kH#obcDv|ocVulp8D?@Kmjq# zKr+x4NDH(T(h5BXIR|Znv_Z3wEVLcc4()(+KszCw&@M<9v>Vb5Jr6k#?Sb?_FF-Cp zdm+8hK1d(5AJPvUfDAwfA%oD1kc-eukW0|Zkjv03kSow3$Pn}@r zqtI)RYtZYE>(CpJ8_+Sx7<3#m4xNBZKqn!S&?(3ibQ&@Zoq^0iXCbrDImjGz9x@NT z3AqWq1-S*i4Y>`y1GxiTfGj}oLheHELGD2pA&bx@$P#oJvJAZsxet8+c>rC3tUw<^ z9zs_ktI$V~N6^QR$IvH`C#ae{uiV+RC<`+y*K-F{ssx3q-!S<-O5m}<0=pZ_YE~1+_PxKHMh+d+P z=qCn%Tf}YR z4zWPoCGHW6#1gSg+$SCoE5t)$m3TzJWao$(;=?56%~NLUAY5OXWkS|#OA^raw_pE6#@&o@<1c6cflL%VAiomAA^$R5@+;+qN77E+27`ed) zx6=s0pL5M1VPBTZT01J2L$+)}_)f`9*tY&&Dd&b(jN-89Z`$>~yYChKbVboGxPEL` z6kIFPfVbm>)>8OM@S@#Zs-eJu@_`rl4XIRe>}2GYidNY1_98oHYG)+cjACPxFGijd zZCTYfxrWLq?U*pFXE%y$kei|Fn9SQZ+}%CLOL!~`L2PHu@;u{apXHqV_U>K~ryKHe zp_5O=Fcq01cQ>`sVPxMdwFddJXZ)oj9^{78RKZx|qE~QjC+3S`ey_CQx!+o+p1To8 zTg8poPKL$JtuKa!U@vD3bHnt(WHjBIj5OVIO*&$?+svdxM$_12bKa(@`7+a&j(F=d z159Ugm=bhcK!&%PL^i+C2Dv>K*RHlb7nJGMaipj2XksPaAA zU!fC*!M@FxYoss^wp~B56)9UevZvK*%q37hJ3OseTQ5&)FAh)YwiT*Lhd|R`b(acb$ JzqQkR{{(TSfE54$ diff --git a/PythonHome/Lib/lib2to3/pgen2/tokenize.py b/PythonHome/Lib/lib2to3/pgen2/tokenize.py new file mode 100644 index 0000000000..4cb2a41262 --- /dev/null +++ b/PythonHome/Lib/lib2to3/pgen2/tokenize.py @@ -0,0 +1,499 @@ +# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006 Python Software Foundation. +# All rights reserved. + +"""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 ' +__credits__ = \ + 'GvR, ESR, Tim Peters, Thomas Wouters, Fred Drake, Skip Montanaro' + +import string, re +from codecs import BOM_UTF8, lookup +from lib2to3.pgen2.token import * + +from . import token +__all__ = [x for x in dir(token) if x[0] != '_'] + ["tokenize", + "generate_tokens", "untokenize"] +del token + +try: + bytes +except NameError: + # Support bytes type in Python <= 2.5, so 2to3 turns itself into + # valid Python 3 code. + bytes = str + +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*' + +Binnumber = r'0[bB][01]*' +Hexnumber = r'0[xX][\da-fA-F]*[lL]?' +Octnumber = r'0[oO]?[0-7]*[lL]?' +Decnumber = r'[1-9]\d*[lL]?' +Intnumber = group(Binnumber, Hexnumber, 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("[ubUB]?[rR]?'''", '[ubUB]?[rR]?"""') +# Single-line ' or " string. +String = group(r"[uU]?[rR]?'[^\n'\\]*(?:\\.[^\n'\\]*)*'", + r'[uU]?[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"[+\-*/%&@|^=<>]=?", + 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', 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, + "b'''": single3prog, 'b"""': double3prog, + "ur'''": single3prog, 'ur"""': double3prog, + "br'''": single3prog, 'br"""': double3prog, + "R'''": single3prog, 'R"""': double3prog, + "U'''": single3prog, 'U"""': double3prog, + "B'''": single3prog, 'B"""': double3prog, + "uR'''": single3prog, 'uR"""': double3prog, + "Ur'''": single3prog, 'Ur"""': double3prog, + "UR'''": single3prog, 'UR"""': 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"""', + "b'''", 'b"""', "B'''", 'B"""', + "ur'''", 'ur"""', "Ur'''", 'Ur"""', + "uR'''", 'uR"""', "UR'''", 'UR"""', + "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"', + "b'", 'b"', "B'", 'B"', + "ur'", 'ur"', "Ur'", 'Ur"', + "uR'", 'uR"', "UR'", 'UR"', + "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, start, end, line): # for testing + (srow, scol) = start + (erow, ecol) = end + 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 + for tok in iterable: + toknum, tokval = tok[:2] + + if toknum in (NAME, NUMBER): + tokval += ' ' + + 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) + +cookie_re = re.compile(r'^[ \t\f]*#.*coding[:=][ \t]*([-\w.]+)') + +def _get_normal_name(orig_enc): + """Imitates get_normal_name in tokenizer.c.""" + # Only care about the first 12 characters. + enc = orig_enc[:12].lower().replace("_", "-") + if enc == "utf-8" or enc.startswith("utf-8-"): + return "utf-8" + if enc in ("latin-1", "iso-8859-1", "iso-latin-1") or \ + enc.startswith(("latin-1-", "iso-8859-1-", "iso-latin-1-")): + return "iso-8859-1" + return orig_enc + +def detect_encoding(readline): + """ + The detect_encoding() function is used to detect the encoding that should + be used to decode a Python source file. It requires one argument, readline, + in the same way as the tokenize() generator. + + It will call readline a maximum of twice, and return the encoding used + (as a string) and a list of any lines (left as bytes) it has read + in. + + It detects the encoding from the presence of a utf-8 bom or an encoding + cookie as specified in pep-0263. If both a bom and a cookie are present, but + disagree, a SyntaxError will be raised. If the encoding cookie is an invalid + charset, raise a SyntaxError. Note that if a utf-8 bom is found, + 'utf-8-sig' is returned. + + If no encoding is specified, then the default of 'utf-8' will be returned. + """ + bom_found = False + encoding = None + default = 'utf-8' + def read_or_stop(): + try: + return readline() + except StopIteration: + return bytes() + + def find_cookie(line): + try: + line_string = line.decode('ascii') + except UnicodeDecodeError: + return None + match = cookie_re.match(line_string) + if not match: + return None + encoding = _get_normal_name(match.group(1)) + try: + codec = lookup(encoding) + except LookupError: + # This behaviour mimics the Python interpreter + raise SyntaxError("unknown encoding: " + encoding) + + if bom_found: + if codec.name != 'utf-8': + # This behaviour mimics the Python interpreter + raise SyntaxError('encoding problem: utf-8') + encoding += '-sig' + return encoding + + first = read_or_stop() + if first.startswith(BOM_UTF8): + bom_found = True + first = first[3:] + default = 'utf-8-sig' + if not first: + return default, [] + + encoding = find_cookie(first) + if encoding: + return encoding, [first] + + second = read_or_stop() + if not second: + return default, [first] + + encoding = find_cookie(second) + if encoding: + return encoding, [first, second] + + return default, [first, second] + +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 tokin generate_tokens(readline)] + assert t1 == t2 + """ + ut = Untokenizer() + return ut.untokenize(iterable) + +def generate_tokens(readline): + """ + The generate_tokens() generator requires one argument, 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 = 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 = column + 1 + elif line[pos] == '\t': column = (column//tabsize + 1)*tabsize + elif line[pos] == '\f': column = 0 + else: break + pos = 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", + ("", 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 + 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': + newline = NEWLINE + if parenlev > 0: + newline = NL + yield (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 + # This yield is new; needed for better idempotency: + yield (NL, token, spos, (lnum, pos), line) + continued = 1 + else: + if initial in '([{': parenlev = parenlev + 1 + elif initial in ')]}': parenlev = parenlev - 1 + yield (OP, token, spos, epos, line) + else: + yield (ERRORTOKEN, line[pos], + (lnum, pos), (lnum, pos+1), line) + pos = 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/PythonHome/Lib/lib2to3/pgen2/tokenize.pyc b/PythonHome/Lib/lib2to3/pgen2/tokenize.pyc deleted file mode 100644 index ef5a3f1e9e5fe7e1114e328e8226ff50778dcf73..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 16570 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 diff --git a/PythonHome/Lib/lib2to3/pygram.py b/PythonHome/Lib/lib2to3/pygram.py new file mode 100644 index 0000000000..621ff24c95 --- /dev/null +++ b/PythonHome/Lib/lib2to3/pygram.py @@ -0,0 +1,40 @@ +# Copyright 2006 Google, Inc. All Rights Reserved. +# Licensed to PSF under a Contributor Agreement. + +"""Export the Python grammar and symbols.""" + +# Python imports +import os + +# Local imports +from .pgen2 import token +from .pgen2 import driver +from . import pytree + +# The grammar file +_GRAMMAR_FILE = os.path.join(os.path.dirname(__file__), "Grammar.txt") +_PATTERN_GRAMMAR_FILE = os.path.join(os.path.dirname(__file__), + "PatternGrammar.txt") + + +class Symbols(object): + + def __init__(self, grammar): + """Initializer. + + Creates an attribute for each grammar symbol (nonterminal), + whose value is the symbol's type (an int >= 256). + """ + for name, symbol in grammar.symbol2number.iteritems(): + setattr(self, name, symbol) + + +python_grammar = driver.load_grammar(_GRAMMAR_FILE) + +python_symbols = Symbols(python_grammar) + +python_grammar_no_print_statement = python_grammar.copy() +del python_grammar_no_print_statement.keywords["print"] + +pattern_grammar = driver.load_grammar(_PATTERN_GRAMMAR_FILE) +pattern_symbols = Symbols(pattern_grammar) diff --git a/PythonHome/Lib/lib2to3/pygram.pyc b/PythonHome/Lib/lib2to3/pygram.pyc deleted file mode 100644 index 6ae0adbf11b4e61c8c46a416895dd2fcfdc325a0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1369 zcmb7DOHbQC5FXnhKoUrJwg(R8(i*AFA$^<*Dy0-50YVNEs+G!h;tg42dsFWQNJUTS zPw0>7Z|b!_pq*KVKt-jhc6KuF$2V*1=UnOg>BnXV#*c;nukpwqNJ0P)sR5x0u>l@3 z7K8ac{O0DscC+Jm}rswyd_{u5G_MkhRtz6MLVtN zfECTJ(r`_uLNh-?vU}ARnX*-n*~dfG6RCZc1xXTQc94d)942iM%R2vs&k;8;z#*ch zh=_BR=3)`WFyj|2yOsMxl`$sEXxhtD*434gizpulO0g`xqgKh!dM?Ob#^%Smg69ADx$h`fq1}zi5;LieO!ZpA(QVT}7 z(oZ!w#g#W5$|S!b*-yFRLCin1tX?YF<7X#hfnpM2v9bG%w+D*ZU6I)===3I_<$&2v zDpH&<;b{Is@iB2`94R0e18>rN%^6;X5{VVW=ie*s-%4r5e{M$UAhOiRsLDZ zrFoa}NZL!$)Hkl5Avg{-sORzhP;{^oc?g+%oUydwq71ISro@OF}iRj9O zJkvj?x_~`mkaVg#HcK z^Qb`N@XPv}Do0=HraA)s*6+FdsqppSzQo0{gr!RF;hYUGMHWg`rI7rKnv}S!8`t;` n@OA!I`Rcax6= 256) + parent = None # Parent node pointer, or None + children = () # Tuple of subnodes + was_changed = False + was_checked = False + + def __new__(cls, *args, **kwds): + """Constructor that prevents Base from being instantiated.""" + assert cls is not Base, "Cannot instantiate Base" + return object.__new__(cls) + + def __eq__(self, other): + """ + Compare two nodes for equality. + + This calls the method _eq(). + """ + if self.__class__ is not other.__class__: + return NotImplemented + return self._eq(other) + + __hash__ = None # For Py3 compatibility. + + def __ne__(self, other): + """ + Compare two nodes for inequality. + + This calls the method _eq(). + """ + if self.__class__ is not other.__class__: + return NotImplemented + return not self._eq(other) + + def _eq(self, other): + """ + Compare two nodes for equality. + + This is called by __eq__ and __ne__. It is only called if the two nodes + have the same type. This must be implemented by the concrete subclass. + Nodes should be considered equal if they have the same structure, + ignoring the prefix string and other context information. + """ + raise NotImplementedError + + def clone(self): + """ + Return a cloned (deep) copy of self. + + This must be implemented by the concrete subclass. + """ + raise NotImplementedError + + def post_order(self): + """ + Return a post-order iterator for the tree. + + This must be implemented by the concrete subclass. + """ + raise NotImplementedError + + def pre_order(self): + """ + Return a pre-order iterator for the tree. + + This must be implemented by the concrete subclass. + """ + raise NotImplementedError + + def set_prefix(self, prefix): + """ + Set the prefix for the node (see Leaf class). + + DEPRECATED; use the prefix property directly. + """ + warnings.warn("set_prefix() is deprecated; use the prefix property", + DeprecationWarning, stacklevel=2) + self.prefix = prefix + + def get_prefix(self): + """ + Return the prefix for the node (see Leaf class). + + DEPRECATED; use the prefix property directly. + """ + warnings.warn("get_prefix() is deprecated; use the prefix property", + DeprecationWarning, stacklevel=2) + return self.prefix + + def replace(self, new): + """Replace this node with a new one in the parent.""" + assert self.parent is not None, str(self) + assert new is not None + if not isinstance(new, list): + new = [new] + l_children = [] + found = False + for ch in self.parent.children: + if ch is self: + assert not found, (self.parent.children, self, new) + if new is not None: + l_children.extend(new) + found = True + else: + l_children.append(ch) + assert found, (self.children, self, new) + self.parent.changed() + self.parent.children = l_children + for x in new: + x.parent = self.parent + self.parent = None + + def get_lineno(self): + """Return the line number which generated the invocant node.""" + node = self + while not isinstance(node, Leaf): + if not node.children: + return + node = node.children[0] + return node.lineno + + def changed(self): + if self.parent: + self.parent.changed() + self.was_changed = True + + def remove(self): + """ + Remove the node from the tree. Returns the position of the node in its + parent's children before it was removed. + """ + if self.parent: + for i, node in enumerate(self.parent.children): + if node is self: + self.parent.changed() + del self.parent.children[i] + self.parent = None + return i + + @property + def next_sibling(self): + """ + The node immediately following the invocant in their parent's children + list. If the invocant does not have a next sibling, it is None + """ + if self.parent is None: + return None + + # Can't use index(); we need to test by identity + for i, child in enumerate(self.parent.children): + if child is self: + try: + return self.parent.children[i+1] + except IndexError: + return None + + @property + def prev_sibling(self): + """ + The node immediately preceding the invocant in their parent's children + list. If the invocant does not have a previous sibling, it is None. + """ + if self.parent is None: + return None + + # Can't use index(); we need to test by identity + for i, child in enumerate(self.parent.children): + if child is self: + if i == 0: + return None + return self.parent.children[i-1] + + def leaves(self): + for child in self.children: + for x in child.leaves(): + yield x + + def depth(self): + if self.parent is None: + return 0 + return 1 + self.parent.depth() + + def get_suffix(self): + """ + Return the string immediately following the invocant node. This is + effectively equivalent to node.next_sibling.prefix + """ + next_sib = self.next_sibling + if next_sib is None: + return u"" + return next_sib.prefix + + if sys.version_info < (3, 0): + def __str__(self): + return unicode(self).encode("ascii") + +class Node(Base): + + """Concrete implementation for interior nodes.""" + + def __init__(self,type, children, + context=None, + prefix=None, + fixers_applied=None): + """ + Initializer. + + Takes a type constant (a symbol number >= 256), a sequence of + child nodes, and an optional context keyword argument. + + As a side effect, the parent pointers of the children are updated. + """ + assert type >= 256, type + self.type = type + self.children = list(children) + for ch in self.children: + assert ch.parent is None, repr(ch) + ch.parent = self + if prefix is not None: + self.prefix = prefix + if fixers_applied: + self.fixers_applied = fixers_applied[:] + else: + self.fixers_applied = None + + def __repr__(self): + """Return a canonical string representation.""" + return "%s(%s, %r)" % (self.__class__.__name__, + type_repr(self.type), + self.children) + + def __unicode__(self): + """ + Return a pretty string representation. + + This reproduces the input source exactly. + """ + return u"".join(map(unicode, self.children)) + + if sys.version_info > (3, 0): + __str__ = __unicode__ + + def _eq(self, other): + """Compare two nodes for equality.""" + return (self.type, self.children) == (other.type, other.children) + + def clone(self): + """Return a cloned (deep) copy of self.""" + return Node(self.type, [ch.clone() for ch in self.children], + fixers_applied=self.fixers_applied) + + def post_order(self): + """Return a post-order iterator for the tree.""" + for child in self.children: + for node in child.post_order(): + yield node + yield self + + def pre_order(self): + """Return a pre-order iterator for the tree.""" + yield self + for child in self.children: + for node in child.pre_order(): + yield node + + def _prefix_getter(self): + """ + The whitespace and comments preceding this node in the input. + """ + if not self.children: + return "" + return self.children[0].prefix + + def _prefix_setter(self, prefix): + if self.children: + self.children[0].prefix = prefix + + prefix = property(_prefix_getter, _prefix_setter) + + def set_child(self, i, child): + """ + Equivalent to 'node.children[i] = child'. This method also sets the + child's parent attribute appropriately. + """ + child.parent = self + self.children[i].parent = None + self.children[i] = child + self.changed() + + def insert_child(self, i, child): + """ + Equivalent to 'node.children.insert(i, child)'. This method also sets + the child's parent attribute appropriately. + """ + child.parent = self + self.children.insert(i, child) + self.changed() + + def append_child(self, child): + """ + Equivalent to 'node.children.append(child)'. This method also sets the + child's parent attribute appropriately. + """ + child.parent = self + self.children.append(child) + self.changed() + + +class Leaf(Base): + + """Concrete implementation for leaf nodes.""" + + # Default values for instance variables + _prefix = "" # Whitespace and comments preceding this token in the input + lineno = 0 # Line where this token starts in the input + column = 0 # Column where this token tarts in the input + + def __init__(self, type, value, + context=None, + prefix=None, + fixers_applied=[]): + """ + Initializer. + + Takes a type constant (a token number < 256), a string value, and an + optional context keyword argument. + """ + assert 0 <= type < 256, type + if context is not None: + self._prefix, (self.lineno, self.column) = context + self.type = type + self.value = value + if prefix is not None: + self._prefix = prefix + self.fixers_applied = fixers_applied[:] + + def __repr__(self): + """Return a canonical string representation.""" + return "%s(%r, %r)" % (self.__class__.__name__, + self.type, + self.value) + + def __unicode__(self): + """ + Return a pretty string representation. + + This reproduces the input source exactly. + """ + return self.prefix + unicode(self.value) + + if sys.version_info > (3, 0): + __str__ = __unicode__ + + def _eq(self, other): + """Compare two nodes for equality.""" + return (self.type, self.value) == (other.type, other.value) + + def clone(self): + """Return a cloned (deep) copy of self.""" + return Leaf(self.type, self.value, + (self.prefix, (self.lineno, self.column)), + fixers_applied=self.fixers_applied) + + def leaves(self): + yield self + + def post_order(self): + """Return a post-order iterator for the tree.""" + yield self + + def pre_order(self): + """Return a pre-order iterator for the tree.""" + yield self + + def _prefix_getter(self): + """ + The whitespace and comments preceding this token in the input. + """ + return self._prefix + + def _prefix_setter(self, prefix): + self.changed() + self._prefix = prefix + + prefix = property(_prefix_getter, _prefix_setter) + +def convert(gr, raw_node): + """ + Convert raw node information to a Node or Leaf instance. + + This is passed to the parser driver which calls it whenever a reduction of a + grammar rule produces a new complete node, so that the tree is build + strictly bottom-up. + """ + type, value, context, children = raw_node + if children or type in gr.number2symbol: + # If there's exactly one child, return that child instead of + # creating a new node. + if len(children) == 1: + return children[0] + return Node(type, children, context=context) + else: + return Leaf(type, value, context=context) + + +class BasePattern(object): + + """ + A pattern is a tree matching pattern. + + It looks for a specific node type (token or symbol), and + optionally for a specific content. + + This is an abstract base class. There are three concrete + subclasses: + + - LeafPattern matches a single leaf node; + - NodePattern matches a single node (usually non-leaf); + - WildcardPattern matches a sequence of nodes of variable length. + """ + + # Defaults for instance variables + type = None # Node type (token if < 256, symbol if >= 256) + content = None # Optional content matching pattern + name = None # Optional name used to store match in results dict + + def __new__(cls, *args, **kwds): + """Constructor that prevents BasePattern from being instantiated.""" + assert cls is not BasePattern, "Cannot instantiate BasePattern" + return object.__new__(cls) + + def __repr__(self): + args = [type_repr(self.type), self.content, self.name] + while args and args[-1] is None: + del args[-1] + return "%s(%s)" % (self.__class__.__name__, ", ".join(map(repr, args))) + + def optimize(self): + """ + A subclass can define this as a hook for optimizations. + + Returns either self or another node with the same effect. + """ + return self + + def match(self, node, results=None): + """ + Does this pattern exactly match a node? + + Returns True if it matches, False if not. + + If results is not None, it must be a dict which will be + updated with the nodes matching named subpatterns. + + Default implementation for non-wildcard patterns. + """ + if self.type is not None and node.type != self.type: + return False + if self.content is not None: + r = None + if results is not None: + r = {} + if not self._submatch(node, r): + return False + if r: + results.update(r) + if results is not None and self.name: + results[self.name] = node + return True + + def match_seq(self, nodes, results=None): + """ + Does this pattern exactly match a sequence of nodes? + + Default implementation for non-wildcard patterns. + """ + if len(nodes) != 1: + return False + return self.match(nodes[0], results) + + def generate_matches(self, nodes): + """ + Generator yielding all matches for this pattern. + + Default implementation for non-wildcard patterns. + """ + r = {} + if nodes and self.match(nodes[0], r): + yield 1, r + + +class LeafPattern(BasePattern): + + def __init__(self, type=None, content=None, name=None): + """ + Initializer. Takes optional type, content, and name. + + The type, if given must be a token type (< 256). If not given, + this matches any *leaf* node; the content may still be required. + + The content, if given, must be a string. + + If a name is given, the matching node is stored in the results + dict under that key. + """ + if type is not None: + assert 0 <= type < 256, type + if content is not None: + assert isinstance(content, basestring), repr(content) + self.type = type + self.content = content + self.name = name + + def match(self, node, results=None): + """Override match() to insist on a leaf node.""" + if not isinstance(node, Leaf): + return False + return BasePattern.match(self, node, results) + + def _submatch(self, node, results=None): + """ + Match the pattern's content to the node's children. + + This assumes the node type matches and self.content is not None. + + Returns True if it matches, False if not. + + If results is not None, it must be a dict which will be + updated with the nodes matching named subpatterns. + + When returning False, the results dict may still be updated. + """ + return self.content == node.value + + +class NodePattern(BasePattern): + + wildcards = False + + def __init__(self, type=None, content=None, name=None): + """ + Initializer. Takes optional type, content, and name. + + The type, if given, must be a symbol type (>= 256). If the + type is None this matches *any* single node (leaf or not), + except if content is not None, in which it only matches + non-leaf nodes that also match the content pattern. + + The content, if not None, must be a sequence of Patterns that + must match the node's children exactly. If the content is + given, the type must not be None. + + If a name is given, the matching node is stored in the results + dict under that key. + """ + if type is not None: + assert type >= 256, type + if content is not None: + assert not isinstance(content, basestring), repr(content) + content = list(content) + for i, item in enumerate(content): + assert isinstance(item, BasePattern), (i, item) + if isinstance(item, WildcardPattern): + self.wildcards = True + self.type = type + self.content = content + self.name = name + + def _submatch(self, node, results=None): + """ + Match the pattern's content to the node's children. + + This assumes the node type matches and self.content is not None. + + Returns True if it matches, False if not. + + If results is not None, it must be a dict which will be + updated with the nodes matching named subpatterns. + + When returning False, the results dict may still be updated. + """ + if self.wildcards: + for c, r in generate_matches(self.content, node.children): + if c == len(node.children): + if results is not None: + results.update(r) + return True + return False + if len(self.content) != len(node.children): + return False + for subpattern, child in zip(self.content, node.children): + if not subpattern.match(child, results): + return False + return True + + +class WildcardPattern(BasePattern): + + """ + A wildcard pattern can match zero or more nodes. + + This has all the flexibility needed to implement patterns like: + + .* .+ .? .{m,n} + (a b c | d e | f) + (...)* (...)+ (...)? (...){m,n} + + except it always uses non-greedy matching. + """ + + def __init__(self, content=None, min=0, max=HUGE, name=None): + """ + Initializer. + + Args: + content: optional sequence of subsequences of patterns; + if absent, matches one node; + if present, each subsequence is an alternative [*] + min: optional minimum number of times to match, default 0 + max: optional maximum number of times to match, default HUGE + name: optional name assigned to this match + + [*] Thus, if content is [[a, b, c], [d, e], [f, g, h]] this is + equivalent to (a b c | d e | f g h); if content is None, + this is equivalent to '.' in regular expression terms. + The min and max parameters work as follows: + min=0, max=maxint: .* + min=1, max=maxint: .+ + min=0, max=1: .? + min=1, max=1: . + If content is not None, replace the dot with the parenthesized + list of alternatives, e.g. (a b c | d e | f g h)* + """ + assert 0 <= min <= max <= HUGE, (min, max) + if content is not None: + content = tuple(map(tuple, content)) # Protect against alterations + # Check sanity of alternatives + assert len(content), repr(content) # Can't have zero alternatives + for alt in content: + assert len(alt), repr(alt) # Can have empty alternatives + self.content = content + self.min = min + self.max = max + self.name = name + + def optimize(self): + """Optimize certain stacked wildcard patterns.""" + subpattern = None + if (self.content is not None and + len(self.content) == 1 and len(self.content[0]) == 1): + subpattern = self.content[0][0] + if self.min == 1 and self.max == 1: + if self.content is None: + return NodePattern(name=self.name) + if subpattern is not None and self.name == subpattern.name: + return subpattern.optimize() + if (self.min <= 1 and isinstance(subpattern, WildcardPattern) and + subpattern.min <= 1 and self.name == subpattern.name): + return WildcardPattern(subpattern.content, + self.min*subpattern.min, + self.max*subpattern.max, + subpattern.name) + return self + + def match(self, node, results=None): + """Does this pattern exactly match a node?""" + return self.match_seq([node], results) + + def match_seq(self, nodes, results=None): + """Does this pattern exactly match a sequence of nodes?""" + for c, r in self.generate_matches(nodes): + if c == len(nodes): + if results is not None: + results.update(r) + if self.name: + results[self.name] = list(nodes) + return True + return False + + def generate_matches(self, nodes): + """ + Generator yielding matches for a sequence of nodes. + + Args: + nodes: sequence of nodes + + Yields: + (count, results) tuples where: + count: the match comprises nodes[:count]; + results: dict containing named submatches. + """ + if self.content is None: + # Shortcut for special case (see __init__.__doc__) + for count in xrange(self.min, 1 + min(len(nodes), self.max)): + r = {} + if self.name: + r[self.name] = nodes[:count] + yield count, r + elif self.name == "bare_name": + yield self._bare_name_matches(nodes) + else: + # The reason for this is that hitting the recursion limit usually + # results in some ugly messages about how RuntimeErrors are being + # ignored. We don't do this on non-CPython implementation because + # they don't have this problem. + if hasattr(sys, "getrefcount"): + save_stderr = sys.stderr + sys.stderr = StringIO() + try: + for count, r in self._recursive_matches(nodes, 0): + if self.name: + r[self.name] = nodes[:count] + yield count, r + except RuntimeError: + # We fall back to the iterative pattern matching scheme if the recursive + # scheme hits the recursion limit. + for count, r in self._iterative_matches(nodes): + if self.name: + r[self.name] = nodes[:count] + yield count, r + finally: + if hasattr(sys, "getrefcount"): + sys.stderr = save_stderr + + def _iterative_matches(self, nodes): + """Helper to iteratively yield the matches.""" + nodelen = len(nodes) + if 0 >= self.min: + yield 0, {} + + results = [] + # generate matches that use just one alt from self.content + for alt in self.content: + for c, r in generate_matches(alt, nodes): + yield c, r + results.append((c, r)) + + # for each match, iterate down the nodes + while results: + new_results = [] + for c0, r0 in results: + # stop if the entire set of nodes has been matched + if c0 < nodelen and c0 <= self.max: + for alt in self.content: + for c1, r1 in generate_matches(alt, nodes[c0:]): + if c1 > 0: + r = {} + r.update(r0) + r.update(r1) + yield c0 + c1, r + new_results.append((c0 + c1, r)) + results = new_results + + def _bare_name_matches(self, nodes): + """Special optimized matcher for bare_name.""" + count = 0 + r = {} + done = False + max = len(nodes) + while not done and count < max: + done = True + for leaf in self.content: + if leaf[0].match(nodes[count], r): + count += 1 + done = False + break + r[self.name] = nodes[:count] + return count, r + + def _recursive_matches(self, nodes, count): + """Helper to recursively yield the matches.""" + assert self.content is not None + if count >= self.min: + yield 0, {} + if count < self.max: + for alt in self.content: + for c0, r0 in generate_matches(alt, nodes): + for c1, r1 in self._recursive_matches(nodes[c0:], count+1): + r = {} + r.update(r0) + r.update(r1) + yield c0 + c1, r + + +class NegatedPattern(BasePattern): + + def __init__(self, content=None): + """ + Initializer. + + The argument is either a pattern or None. If it is None, this + only matches an empty sequence (effectively '$' in regex + lingo). If it is not None, this matches whenever the argument + pattern doesn't have any matches. + """ + if content is not None: + assert isinstance(content, BasePattern), repr(content) + self.content = content + + def match(self, node): + # We never match a node in its entirety + return False + + def match_seq(self, nodes): + # We only match an empty sequence of nodes in its entirety + return len(nodes) == 0 + + def generate_matches(self, nodes): + if self.content is None: + # Return a match if there is an empty sequence + if len(nodes) == 0: + yield 0, {} + else: + # Return a match if the argument pattern has no matches + for c, r in self.content.generate_matches(nodes): + return + yield 0, {} + + +def generate_matches(patterns, nodes): + """ + Generator yielding matches for a sequence of patterns and nodes. + + Args: + patterns: a sequence of patterns + nodes: a sequence of nodes + + Yields: + (count, results) tuples where: + count: the entire sequence of patterns matches nodes[:count]; + results: dict containing named submatches. + """ + if not patterns: + yield 0, {} + else: + p, rest = patterns[0], patterns[1:] + for c0, r0 in p.generate_matches(nodes): + if not rest: + yield c0, r0 + else: + for c1, r1 in generate_matches(rest, nodes[c0:]): + r = {} + r.update(r0) + r.update(r1) + yield c0 + c1, r diff --git a/PythonHome/Lib/lib2to3/pytree.pyc b/PythonHome/Lib/lib2to3/pytree.pyc deleted file mode 100644 index 39d02218ba3c01b7597ce5a0e031ddc12b2fa2af..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 29163 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 diff --git a/PythonHome/Lib/lib2to3/refactor.py b/PythonHome/Lib/lib2to3/refactor.py new file mode 100644 index 0000000000..a4c168df9e --- /dev/null +++ b/PythonHome/Lib/lib2to3/refactor.py @@ -0,0 +1,747 @@ +# Copyright 2006 Google, Inc. All Rights Reserved. +# Licensed to PSF under a Contributor Agreement. + +"""Refactoring framework. + +Used as a main program, this can refactor any number of files and/or +recursively descend down directories. Imported as a module, this +provides infrastructure to write your own refactoring tool. +""" + +from __future__ import with_statement + +__author__ = "Guido van Rossum " + + +# Python imports +import os +import sys +import logging +import operator +import collections +import StringIO +from itertools import chain + +# Local imports +from .pgen2 import driver, tokenize, token +from .fixer_util import find_root +from . import pytree, pygram +from . import btm_utils as bu +from . import btm_matcher as bm + + +def get_all_fix_names(fixer_pkg, remove_prefix=True): + """Return a sorted list of all available fix names in the given package.""" + pkg = __import__(fixer_pkg, [], [], ["*"]) + fixer_dir = os.path.dirname(pkg.__file__) + fix_names = [] + for name in sorted(os.listdir(fixer_dir)): + if name.startswith("fix_") and name.endswith(".py"): + if remove_prefix: + name = name[4:] + fix_names.append(name[:-3]) + return fix_names + + +class _EveryNode(Exception): + pass + + +def _get_head_types(pat): + """ Accepts a pytree Pattern Node and returns a set + of the pattern types which will match first. """ + + if isinstance(pat, (pytree.NodePattern, pytree.LeafPattern)): + # NodePatters must either have no type and no content + # or a type and content -- so they don't get any farther + # Always return leafs + if pat.type is None: + raise _EveryNode + return set([pat.type]) + + if isinstance(pat, pytree.NegatedPattern): + if pat.content: + return _get_head_types(pat.content) + raise _EveryNode # Negated Patterns don't have a type + + if isinstance(pat, pytree.WildcardPattern): + # Recurse on each node in content + r = set() + for p in pat.content: + for x in p: + r.update(_get_head_types(x)) + return r + + raise Exception("Oh no! I don't understand pattern %s" %(pat)) + + +def _get_headnode_dict(fixer_list): + """ Accepts a list of fixers and returns a dictionary + of head node type --> fixer list. """ + head_nodes = collections.defaultdict(list) + every = [] + for fixer in fixer_list: + if fixer.pattern: + try: + heads = _get_head_types(fixer.pattern) + except _EveryNode: + every.append(fixer) + else: + for node_type in heads: + head_nodes[node_type].append(fixer) + else: + if fixer._accept_type is not None: + head_nodes[fixer._accept_type].append(fixer) + else: + every.append(fixer) + for node_type in chain(pygram.python_grammar.symbol2number.itervalues(), + pygram.python_grammar.tokens): + head_nodes[node_type].extend(every) + return dict(head_nodes) + + +def get_fixers_from_package(pkg_name): + """ + Return the fully qualified names for fixers in the package pkg_name. + """ + return [pkg_name + "." + fix_name + for fix_name in get_all_fix_names(pkg_name, False)] + +def _identity(obj): + return obj + +if sys.version_info < (3, 0): + import codecs + _open_with_encoding = codecs.open + # codecs.open doesn't translate newlines sadly. + def _from_system_newlines(input): + return input.replace(u"\r\n", u"\n") + def _to_system_newlines(input): + if os.linesep != "\n": + return input.replace(u"\n", os.linesep) + else: + return input +else: + _open_with_encoding = open + _from_system_newlines = _identity + _to_system_newlines = _identity + + +def _detect_future_features(source): + have_docstring = False + gen = tokenize.generate_tokens(StringIO.StringIO(source).readline) + def advance(): + tok = gen.next() + return tok[0], tok[1] + ignore = frozenset((token.NEWLINE, tokenize.NL, token.COMMENT)) + features = set() + try: + while True: + tp, value = advance() + if tp in ignore: + continue + elif tp == token.STRING: + if have_docstring: + break + have_docstring = True + elif tp == token.NAME and value == u"from": + tp, value = advance() + if tp != token.NAME or value != u"__future__": + break + tp, value = advance() + if tp != token.NAME or value != u"import": + break + tp, value = advance() + if tp == token.OP and value == u"(": + tp, value = advance() + while tp == token.NAME: + features.add(value) + tp, value = advance() + if tp != token.OP or value != u",": + break + tp, value = advance() + else: + break + except StopIteration: + pass + return frozenset(features) + + +class FixerError(Exception): + """A fixer could not be loaded.""" + + +class RefactoringTool(object): + + _default_options = {"print_function" : False, + "write_unchanged_files" : False} + + CLASS_PREFIX = "Fix" # The prefix for fixer classes + FILE_PREFIX = "fix_" # The prefix for modules with a fixer within + + def __init__(self, fixer_names, options=None, explicit=None): + """Initializer. + + Args: + fixer_names: a list of fixers to import + options: an dict with configuration. + explicit: a list of fixers to run even if they are explicit. + """ + self.fixers = fixer_names + self.explicit = explicit or [] + self.options = self._default_options.copy() + if options is not None: + self.options.update(options) + if self.options["print_function"]: + self.grammar = pygram.python_grammar_no_print_statement + else: + self.grammar = pygram.python_grammar + # When this is True, the refactor*() methods will call write_file() for + # files processed even if they were not changed during refactoring. If + # and only if the refactor method's write parameter was True. + self.write_unchanged_files = self.options.get("write_unchanged_files") + self.errors = [] + self.logger = logging.getLogger("RefactoringTool") + self.fixer_log = [] + self.wrote = False + self.driver = driver.Driver(self.grammar, + convert=pytree.convert, + logger=self.logger) + self.pre_order, self.post_order = self.get_fixers() + + + self.files = [] # List of files that were or should be modified + + self.BM = bm.BottomMatcher() + self.bmi_pre_order = [] # Bottom Matcher incompatible fixers + self.bmi_post_order = [] + + for fixer in chain(self.post_order, self.pre_order): + if fixer.BM_compatible: + self.BM.add_fixer(fixer) + # remove fixers that will be handled by the bottom-up + # matcher + elif fixer in self.pre_order: + self.bmi_pre_order.append(fixer) + elif fixer in self.post_order: + self.bmi_post_order.append(fixer) + + self.bmi_pre_order_heads = _get_headnode_dict(self.bmi_pre_order) + self.bmi_post_order_heads = _get_headnode_dict(self.bmi_post_order) + + + + def get_fixers(self): + """Inspects the options to load the requested patterns and handlers. + + Returns: + (pre_order, post_order), where pre_order is the list of fixers that + want a pre-order AST traversal, and post_order is the list that want + post-order traversal. + """ + pre_order_fixers = [] + post_order_fixers = [] + for fix_mod_path in self.fixers: + mod = __import__(fix_mod_path, {}, {}, ["*"]) + fix_name = fix_mod_path.rsplit(".", 1)[-1] + if fix_name.startswith(self.FILE_PREFIX): + fix_name = fix_name[len(self.FILE_PREFIX):] + parts = fix_name.split("_") + class_name = self.CLASS_PREFIX + "".join([p.title() for p in parts]) + try: + fix_class = getattr(mod, class_name) + except AttributeError: + raise FixerError("Can't find %s.%s" % (fix_name, class_name)) + fixer = fix_class(self.options, self.fixer_log) + if fixer.explicit and self.explicit is not True and \ + fix_mod_path not in self.explicit: + self.log_message("Skipping implicit fixer: %s", fix_name) + continue + + self.log_debug("Adding transformation: %s", fix_name) + if fixer.order == "pre": + pre_order_fixers.append(fixer) + elif fixer.order == "post": + post_order_fixers.append(fixer) + else: + raise FixerError("Illegal fixer order: %r" % fixer.order) + + key_func = operator.attrgetter("run_order") + pre_order_fixers.sort(key=key_func) + post_order_fixers.sort(key=key_func) + return (pre_order_fixers, post_order_fixers) + + def log_error(self, msg, *args, **kwds): + """Called when an error occurs.""" + raise + + def log_message(self, msg, *args): + """Hook to log a message.""" + if args: + msg = msg % args + self.logger.info(msg) + + def log_debug(self, msg, *args): + if args: + msg = msg % args + self.logger.debug(msg) + + def print_output(self, old_text, new_text, filename, equal): + """Called with the old version, new version, and filename of a + refactored file.""" + pass + + def refactor(self, items, write=False, doctests_only=False): + """Refactor a list of files and directories.""" + + for dir_or_file in items: + if os.path.isdir(dir_or_file): + self.refactor_dir(dir_or_file, write, doctests_only) + else: + self.refactor_file(dir_or_file, write, doctests_only) + + def refactor_dir(self, dir_name, write=False, doctests_only=False): + """Descends down a directory and refactor every Python file found. + + Python files are assumed to have a .py extension. + + Files and subdirectories starting with '.' are skipped. + """ + py_ext = os.extsep + "py" + for dirpath, dirnames, filenames in os.walk(dir_name): + self.log_debug("Descending into %s", dirpath) + dirnames.sort() + filenames.sort() + for name in filenames: + if (not name.startswith(".") and + os.path.splitext(name)[1] == py_ext): + fullname = os.path.join(dirpath, name) + self.refactor_file(fullname, write, doctests_only) + # Modify dirnames in-place to remove subdirs with leading dots + dirnames[:] = [dn for dn in dirnames if not dn.startswith(".")] + + def _read_python_source(self, filename): + """ + Do our best to decode a Python source file correctly. + """ + try: + f = open(filename, "rb") + except IOError as err: + self.log_error("Can't open %s: %s", filename, err) + return None, None + try: + encoding = tokenize.detect_encoding(f.readline)[0] + finally: + f.close() + with _open_with_encoding(filename, "r", encoding=encoding) as f: + return _from_system_newlines(f.read()), encoding + + def refactor_file(self, filename, write=False, doctests_only=False): + """Refactors a file.""" + input, encoding = self._read_python_source(filename) + if input is None: + # Reading the file failed. + return + input += u"\n" # Silence certain parse errors + if doctests_only: + self.log_debug("Refactoring doctests in %s", filename) + output = self.refactor_docstring(input, filename) + if self.write_unchanged_files or output != input: + self.processed_file(output, filename, input, write, encoding) + else: + self.log_debug("No doctest changes in %s", filename) + else: + tree = self.refactor_string(input, filename) + if self.write_unchanged_files or (tree and tree.was_changed): + # The [:-1] is to take off the \n we added earlier + self.processed_file(unicode(tree)[:-1], filename, + write=write, encoding=encoding) + else: + self.log_debug("No changes in %s", filename) + + def refactor_string(self, data, name): + """Refactor a given input string. + + Args: + data: a string holding the code to be refactored. + name: a human-readable name for use in error/log messages. + + Returns: + An AST corresponding to the refactored input stream; None if + there were errors during the parse. + """ + features = _detect_future_features(data) + if "print_function" in features: + self.driver.grammar = pygram.python_grammar_no_print_statement + try: + tree = self.driver.parse_string(data) + except Exception as err: + self.log_error("Can't parse %s: %s: %s", + name, err.__class__.__name__, err) + return + finally: + self.driver.grammar = self.grammar + tree.future_features = features + self.log_debug("Refactoring %s", name) + self.refactor_tree(tree, name) + return tree + + def refactor_stdin(self, doctests_only=False): + input = sys.stdin.read() + if doctests_only: + self.log_debug("Refactoring doctests in stdin") + output = self.refactor_docstring(input, "") + if self.write_unchanged_files or output != input: + self.processed_file(output, "", input) + else: + self.log_debug("No doctest changes in stdin") + else: + tree = self.refactor_string(input, "") + if self.write_unchanged_files or (tree and tree.was_changed): + self.processed_file(unicode(tree), "", input) + else: + self.log_debug("No changes in stdin") + + def refactor_tree(self, tree, name): + """Refactors a parse tree (modifying the tree in place). + + For compatible patterns the bottom matcher module is + used. Otherwise the tree is traversed node-to-node for + matches. + + Args: + tree: a pytree.Node instance representing the root of the tree + to be refactored. + name: a human-readable name for this tree. + + Returns: + True if the tree was modified, False otherwise. + """ + + for fixer in chain(self.pre_order, self.post_order): + fixer.start_tree(tree, name) + + #use traditional matching for the incompatible fixers + self.traverse_by(self.bmi_pre_order_heads, tree.pre_order()) + self.traverse_by(self.bmi_post_order_heads, tree.post_order()) + + # obtain a set of candidate nodes + match_set = self.BM.run(tree.leaves()) + + while any(match_set.values()): + for fixer in self.BM.fixers: + if fixer in match_set and match_set[fixer]: + #sort by depth; apply fixers from bottom(of the AST) to top + match_set[fixer].sort(key=pytree.Base.depth, reverse=True) + + if fixer.keep_line_order: + #some fixers(eg fix_imports) must be applied + #with the original file's line order + match_set[fixer].sort(key=pytree.Base.get_lineno) + + for node in list(match_set[fixer]): + if node in match_set[fixer]: + match_set[fixer].remove(node) + + try: + find_root(node) + except ValueError: + # this node has been cut off from a + # previous transformation ; skip + continue + + if node.fixers_applied and fixer in node.fixers_applied: + # do not apply the same fixer again + continue + + results = fixer.match(node) + + if results: + new = fixer.transform(node, results) + if new is not None: + node.replace(new) + #new.fixers_applied.append(fixer) + for node in new.post_order(): + # do not apply the fixer again to + # this or any subnode + if not node.fixers_applied: + node.fixers_applied = [] + node.fixers_applied.append(fixer) + + # update the original match set for + # the added code + new_matches = self.BM.run(new.leaves()) + for fxr in new_matches: + if not fxr in match_set: + match_set[fxr]=[] + + match_set[fxr].extend(new_matches[fxr]) + + for fixer in chain(self.pre_order, self.post_order): + fixer.finish_tree(tree, name) + return tree.was_changed + + def traverse_by(self, fixers, traversal): + """Traverse an AST, applying a set of fixers to each node. + + This is a helper method for refactor_tree(). + + Args: + fixers: a list of fixer instances. + traversal: a generator that yields AST nodes. + + Returns: + None + """ + if not fixers: + return + for node in traversal: + for fixer in fixers[node.type]: + results = fixer.match(node) + if results: + new = fixer.transform(node, results) + if new is not None: + node.replace(new) + node = new + + def processed_file(self, new_text, filename, old_text=None, write=False, + encoding=None): + """ + Called when a file has been refactored and there may be changes. + """ + self.files.append(filename) + if old_text is None: + old_text = self._read_python_source(filename)[0] + if old_text is None: + return + equal = old_text == new_text + self.print_output(old_text, new_text, filename, equal) + if equal: + self.log_debug("No changes to %s", filename) + if not self.write_unchanged_files: + return + if write: + self.write_file(new_text, filename, old_text, encoding) + else: + self.log_debug("Not writing changes to %s", filename) + + def write_file(self, new_text, filename, old_text, encoding=None): + """Writes a string to a file. + + It first shows a unified diff between the old text and the new text, and + then rewrites the file; the latter is only done if the write option is + set. + """ + try: + f = _open_with_encoding(filename, "w", encoding=encoding) + except os.error as err: + self.log_error("Can't create %s: %s", filename, err) + return + try: + f.write(_to_system_newlines(new_text)) + except os.error as err: + self.log_error("Can't write %s: %s", filename, err) + finally: + f.close() + self.log_debug("Wrote changes to %s", filename) + self.wrote = True + + PS1 = ">>> " + PS2 = "... " + + def refactor_docstring(self, input, filename): + """Refactors a docstring, looking for doctests. + + This returns a modified version of the input string. It looks + for doctests, which start with a ">>>" prompt, and may be + continued with "..." prompts, as long as the "..." is indented + the same as the ">>>". + + (Unfortunately we can't use the doctest module's parser, + since, like most parsers, it is not geared towards preserving + the original source.) + """ + result = [] + block = None + block_lineno = None + indent = None + lineno = 0 + for line in input.splitlines(True): + lineno += 1 + if line.lstrip().startswith(self.PS1): + if block is not None: + result.extend(self.refactor_doctest(block, block_lineno, + indent, filename)) + block_lineno = lineno + block = [line] + i = line.find(self.PS1) + indent = line[:i] + elif (indent is not None and + (line.startswith(indent + self.PS2) or + line == indent + self.PS2.rstrip() + u"\n")): + block.append(line) + else: + if block is not None: + result.extend(self.refactor_doctest(block, block_lineno, + indent, filename)) + block = None + indent = None + result.append(line) + if block is not None: + result.extend(self.refactor_doctest(block, block_lineno, + indent, filename)) + return u"".join(result) + + def refactor_doctest(self, block, lineno, indent, filename): + """Refactors one doctest. + + A doctest is given as a block of lines, the first of which starts + with ">>>" (possibly indented), while the remaining lines start + with "..." (identically indented). + + """ + try: + tree = self.parse_block(block, lineno, indent) + except Exception as err: + if self.logger.isEnabledFor(logging.DEBUG): + for line in block: + self.log_debug("Source: %s", line.rstrip(u"\n")) + self.log_error("Can't parse docstring in %s line %s: %s: %s", + filename, lineno, err.__class__.__name__, err) + return block + if self.refactor_tree(tree, filename): + new = unicode(tree).splitlines(True) + # Undo the adjustment of the line numbers in wrap_toks() below. + clipped, new = new[:lineno-1], new[lineno-1:] + assert clipped == [u"\n"] * (lineno-1), clipped + if not new[-1].endswith(u"\n"): + new[-1] += u"\n" + block = [indent + self.PS1 + new.pop(0)] + if new: + block += [indent + self.PS2 + line for line in new] + return block + + def summarize(self): + if self.wrote: + were = "were" + else: + were = "need to be" + if not self.files: + self.log_message("No files %s modified.", were) + else: + self.log_message("Files that %s modified:", were) + for file in self.files: + self.log_message(file) + if self.fixer_log: + self.log_message("Warnings/messages while refactoring:") + for message in self.fixer_log: + self.log_message(message) + if self.errors: + if len(self.errors) == 1: + self.log_message("There was 1 error:") + else: + self.log_message("There were %d errors:", len(self.errors)) + for msg, args, kwds in self.errors: + self.log_message(msg, *args, **kwds) + + def parse_block(self, block, lineno, indent): + """Parses a block into a tree. + + This is necessary to get correct line number / offset information + in the parser diagnostics and embedded into the parse tree. + """ + tree = self.driver.parse_tokens(self.wrap_toks(block, lineno, indent)) + tree.future_features = frozenset() + return tree + + def wrap_toks(self, block, lineno, indent): + """Wraps a tokenize stream to systematically modify start/end.""" + tokens = tokenize.generate_tokens(self.gen_lines(block, indent).next) + for type, value, (line0, col0), (line1, col1), line_text in tokens: + line0 += lineno - 1 + line1 += lineno - 1 + # Don't bother updating the columns; this is too complicated + # since line_text would also have to be updated and it would + # still break for tokens spanning lines. Let the user guess + # that the column numbers for doctests are relative to the + # end of the prompt string (PS1 or PS2). + yield type, value, (line0, col0), (line1, col1), line_text + + + def gen_lines(self, block, indent): + """Generates lines as expected by tokenize from a list of lines. + + This strips the first len(indent + self.PS1) characters off each line. + """ + prefix1 = indent + self.PS1 + prefix2 = indent + self.PS2 + prefix = prefix1 + for line in block: + if line.startswith(prefix): + yield line[len(prefix):] + elif line == prefix.rstrip() + u"\n": + yield u"\n" + else: + raise AssertionError("line=%r, prefix=%r" % (line, prefix)) + prefix = prefix2 + while True: + yield "" + + +class MultiprocessingUnsupported(Exception): + pass + + +class MultiprocessRefactoringTool(RefactoringTool): + + def __init__(self, *args, **kwargs): + super(MultiprocessRefactoringTool, self).__init__(*args, **kwargs) + self.queue = None + self.output_lock = None + + def refactor(self, items, write=False, doctests_only=False, + num_processes=1): + if num_processes == 1: + return super(MultiprocessRefactoringTool, self).refactor( + items, write, doctests_only) + try: + import multiprocessing + except ImportError: + raise MultiprocessingUnsupported + if self.queue is not None: + raise RuntimeError("already doing multiple processes") + self.queue = multiprocessing.JoinableQueue() + self.output_lock = multiprocessing.Lock() + processes = [multiprocessing.Process(target=self._child) + for i in xrange(num_processes)] + try: + for p in processes: + p.start() + super(MultiprocessRefactoringTool, self).refactor(items, write, + doctests_only) + finally: + self.queue.join() + for i in xrange(num_processes): + self.queue.put(None) + for p in processes: + if p.is_alive(): + p.join() + self.queue = None + + def _child(self): + task = self.queue.get() + while task is not None: + args, kwargs = task + try: + super(MultiprocessRefactoringTool, self).refactor_file( + *args, **kwargs) + finally: + self.queue.task_done() + task = self.queue.get() + + def refactor_file(self, *args, **kwargs): + if self.queue is not None: + self.queue.put((args, kwargs)) + else: + return super(MultiprocessRefactoringTool, self).refactor_file( + *args, **kwargs) diff --git a/PythonHome/Lib/lib2to3/refactor.pyc b/PythonHome/Lib/lib2to3/refactor.pyc deleted file mode 100644 index 3132fe3ae0ffa0c57d5df36e3de6b6e4e83581f3..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 23342 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� 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')): + 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/PythonHome/Lib/linecache.pyc b/PythonHome/Lib/linecache.pyc index 56a85cd1bbc93d47be5d5d2ec25556a9dfaa4187..16dc4886c54319a5b72e8e73d5ac16cec675c3b8 100644 GIT binary patch delta 346 zcmaDWu~TY88zUpj6s-NrAaa2`4xIz!Tx?h0nRc0r6mQWB{43k zNu}vA0hJ{g`FS4sxv7)Gn7T;UwfQ}hI3pR_L|NFGNY^%5o6UofdvgifSr#%h2XJ2{ JLzfAUB>?w%cAWqK delta 141 zcmdlf^;Tj-8zUq0lPj3I(8V?zGmA4~2v)POGocGk a-puB~$iDdx+gTP2sbAbz(Zwe5S^@y;q9?-u diff --git a/PythonHome/Lib/locale.py b/PythonHome/Lib/locale.py new file mode 100644 index 0000000000..25dccaf22f --- /dev/null +++ b/PythonHome/Lib/locale.py @@ -0,0 +1,1947 @@ +""" 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.*?)\))?' + r'(?P[-#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 + +# 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 _replace_encoding(code, encoding): + if '.' in code: + langname = code[:code.index('.')] + else: + langname = code + # 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) + #print('found encoding %r' % encoding) + return langname + '.' + encoding + +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 and modifier + if isinstance(localename, _unicode): + localename = localename.encode('ascii') + code = localename.translate(_ascii_lower_map) + if ':' in code: + # ':' is sometimes used as encoding delimiter. + code = code.replace(':', '.') + if '@' in code: + code, modifier = code.split('@', 1) + else: + modifier = '' + if '.' in code: + langname, encoding = code.split('.')[:2] + else: + langname = code + encoding = '' + + # First lookup: fullname (possibly with encoding and modifier) + lang_enc = langname + if encoding: + norm_encoding = encoding.replace('-', '') + norm_encoding = norm_encoding.replace('_', '') + lang_enc += '.' + norm_encoding + lookup_name = lang_enc + if modifier: + lookup_name += '@' + modifier + code = locale_alias.get(lookup_name, None) + if code is not None: + return code + #print('first lookup failed') + + if modifier: + # Second try: fullname without modifier (possibly with encoding) + code = locale_alias.get(lang_enc, None) + if code is not None: + #print('lookup without modifier succeeded') + if '@' not in code: + return code + '@' + modifier + if code.split('@', 1)[1].translate(_ascii_lower_map) == modifier: + return code + #print('second lookup failed') + + if encoding: + # Third try: langname (without encoding, possibly with modifier) + lookup_name = langname + if modifier: + lookup_name += '@' + modifier + code = locale_alias.get(lookup_name, None) + if code is not None: + #print('lookup without encoding succeeded') + if '@' not in code: + return _replace_encoding(code, encoding) + code, modifier = code.split('@', 1) + return _replace_encoding(code, encoding) + '@' + modifier + + if modifier: + # Fourth try: langname (without encoding and modifier) + code = locale_alias.get(langname, None) + if code is not None: + #print('lookup without modifier and encoding succeeded') + if '@' not in code: + return _replace_encoding(code, encoding) + '@' + modifier + code, defmod = code.split('@', 1) + if defmod.translate(_ascii_lower_map) == modifier: + return _replace_encoding(code, encoding) + '@' + defmod + + 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('@', 1) + 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' +# +# SS 2013-12-20: +# 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.7.6 +# and older): +# +# updated 'a3' -> 'a3_AZ.KOI8-C' to 'az_AZ.KOI8-C' +# updated 'a3_az' -> 'a3_AZ.KOI8-C' to 'az_AZ.KOI8-C' +# updated 'a3_az.koi8c' -> 'a3_AZ.KOI8-C' to 'az_AZ.KOI8-C' +# updated 'cs_cs.iso88592' -> 'cs_CS.ISO8859-2' to 'cs_CZ.ISO8859-2' +# updated 'hebrew' -> 'iw_IL.ISO8859-8' to 'he_IL.ISO8859-8' +# updated 'hebrew.iso88598' -> 'iw_IL.ISO8859-8' to 'he_IL.ISO8859-8' +# updated 'sd' -> 'sd_IN@devanagari.UTF-8' to 'sd_IN.UTF-8' +# updated 'sr@latn' -> 'sr_RS.UTF-8@latin' to 'sr_CS.UTF-8@latin' +# updated 'sr_cs' -> 'sr_RS.UTF-8' to 'sr_CS.UTF-8' +# updated 'sr_cs.utf8@latn' -> 'sr_RS.UTF-8@latin' to 'sr_CS.UTF-8@latin' +# updated 'sr_cs@latn' -> 'sr_RS.UTF-8@latin' to 'sr_CS.UTF-8@latin' + +locale_alias = { + 'a3': 'az_AZ.KOI8-C', + 'a3_az': 'az_AZ.KOI8-C', + 'a3_az.koi8c': 'az_AZ.KOI8-C', + 'a3_az.koic': 'az_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_in': 'ar_IN.UTF-8', + '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', + 'as_in': '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', + 'bo_in': 'bo_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.ascii': 'C', + '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_CZ.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': 'he_IL.ISO8859-8', + 'hebrew.iso88598': 'he_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', + 'hne_in': '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': 'ks_IN.UTF-8', + 'ks_in@devanagari': 'ks_IN.UTF-8@devanagari', + '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', + 'mai_in': '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', + 'ml_in': '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', + 'ne_np': 'ne_NP.UTF-8', + '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', + 'or_in': '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.UTF-8', + 'sd@devanagari': 'sd_IN.UTF-8@devanagari', + 'sd_in': 'sd_IN.UTF-8', + 'sd_in@devanagari': 'sd_IN.UTF-8@devanagari', + '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_CS.UTF-8@latin', + 'sr_cs': 'sr_CS.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_CS.UTF-8@latin', + 'sr_cs@latn': 'sr_CS.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_in': 'ur_IN.UTF-8', + '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/PythonHome/Lib/locale.pyc b/PythonHome/Lib/locale.pyc index b4536a1a020df588a95c0b0829e85c5acebdf9ba..65cb23ba39fbb1dd243199125a9f2c6bf3419791 100644 GIT binary patch delta 1824 zcmey}!@PSc^M(dxLu&>G23M!OaSmC&347^P{7_VH(vGV}Kzz`El$;4C9~1VTf&h9*>!tHrFQZ2?yF{wQ~-J VLpHPTF~$_k-ggvJF!5j%Cjfz~)k^>X diff --git a/PythonHome/Lib/logging/__init__.py b/PythonHome/Lib/logging/__init__.py new file mode 100644 index 0000000000..b2a7711dc3 --- /dev/null +++ b/PythonHome/Lib/logging/__init__.py @@ -0,0 +1,1737 @@ +# Copyright 2001-2014 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-2014 Vinay Sajip. All Rights Reserved. + +To use, simply 'import logging' and log away! +""" + +import sys, os, time, cStringIO, traceback, warnings, weakref, collections + +__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 " +__status__ = "production" +# Note: the attributes below are no longer maintained. +__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. + # Issue #21172: a request was made to relax the isinstance check + # to hasattr(args[0], '__getitem__'). However, the docs on string + # formatting still seem to suggest a mapping object is required. + # Thus, while not removing the isinstance check, it does now look + # for collections.Mapping rather than, as before, dict. + if (args and len(args) == 1 and isinstance(args[0], collections.Mapping) + and args[0]): + args = args[0] + self.args = args + self.levelname = getLevelName(level) + self.levelno = level + self.pathname = pathname + try: + self.filename = os.path.basename(pathname) + self.module = os.path.splitext(self.filename)[0] + except (TypeError, ValueError, AttributeError): + self.filename = pathname + self.module = "Unknown module" + self.exc_info = exc_info + self.exc_text = None # used to cache the traceback text + self.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 ''%(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. It can also be called from another thread. So we need to + # pre-emptively grab the necessary globals and check if they're None, + # to prevent race conditions and failures during interpreter shutdown. + acquire, release, handlers = _acquireLock, _releaseLock, _handlerList + if acquire and release and handlers: + acquire() + try: + if wr in handlers: + handlers.remove(wr) + finally: + release() + +def _addHandlerRef(handler): + """ + Add a handler to the internal cleanup list using a weak reference. + """ + _acquireLock() + try: + _handlerList.append(weakref.ref(handler, _removeHandlerRef)) + finally: + _releaseLock() + +class Handler(Filterer): + """ + Handler instances dispatch logging events to specific destinations. + + The base handler class. Acts as a placeholder which defines the Handler + interface. Handlers can optionally use Formatter instances to format + records as desired. By default, no formatter is specified; in this case, + the 'raw' message as determined by record.message is logged. + """ + def __init__(self, level=NOTSET): + """ + Initializes the instance - basically setting the formatter to None + and the filter list to empty. + """ + Filterer.__init__(self) + self._name = None + self.level = _checkLevel(level) + self.formatter = None + # Add the handler to the global _handlerList (for cleanup on shutdown) + _addHandlerRef(self) + self.createLock() + + def get_name(self): + return self._name + + def set_name(self, name): + _acquireLock() + try: + if self._name in _handlers: + del _handlers[self._name] + self._name = name + if name: + _handlers[name] = self + finally: + _releaseLock() + + name = property(get_name, set_name) + + def createLock(self): + """ + Acquire a thread lock for serializing access to the underlying I/O. + """ + if 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 = u'%s\n' + 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 + self.delay = delay + if delay: + #We don't open the stream, but we still need to call the + #Handler constructor to set level, formatter, lock etc. + Handler.__init__(self) + self.stream = None + else: + StreamHandler.__init__(self, self._open()) + + def close(self): + """ + Closes the stream. + """ + self.acquire() + try: + if self.stream: + self.flush() + if hasattr(self.stream, "close"): + self.stream.close() + self.stream = None + # Issue #19523: call unconditionally to + # prevent a handler leak when delay is set + StreamHandler.close(self) + finally: + self.release() + + def _open(self): + """ + Open the current base file with the (original) mode and encoding. + Return the resulting stream. + """ + 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/PythonHome/Lib/logging/__init__.pyc b/PythonHome/Lib/logging/__init__.pyc index 8b2538ec4a54cce1b1febc75af8ada9d1b55469d..2d2c96ec5085597dddc0b0d5b35feab4bce9b940 100644 GIT binary patch delta 7027 zcmbW5|4+4yD`pUK58)=!%b>T=a21A%fPE@4zNrMDIp5mAI;2{sza)-m?SLrf!~;gVxdEq1y(JX0EsGme;&|{L zK%DcM2yRkBs6_o?O^9a>jC)+WT?YwkXl{50BFsH*i0A}F+49B6*BD7fJNhxZ8j%;J z2SkUXf)uXg5j_i$<=q>qgJ*H^u1at{iHP_lpjhtBv-rm#*`ogqkn+Y6!wJZ=VDe_7 z4b(L4z73F^P>bG;w0nG!1;JCI$Z!lnc`f-QkAtW@B^t4Euk4?|K=Lv6B5s{2K?*lo zdEgqd_PIY_Q(FPY+?wvRwb=Dk65gh_n5cbG26DRJ8Fr(RSjlD zNhc?fEzTR&dS)+L>SUpxe4u+5ZNhA8=tOZosy*+#0gUH0ZedTo6E~UR5%{0DE-n|6rXwJBbbtxKs{66)gP!|$B>FXRU{ybST9L*@cL{N zt-euyR$V1&jH%aiG7R^^uC{lw7|Q9aQ#Pr;rZwH6~Q2 z61qF!t%7127a(0?;nF4oqT=nF(L9J$8`c8+nUSsK4^p8#5^12#3qv*JM$3>A$I2v1 zzP|)PIau3+6)5U>2)~<#w8QtchDZLW;h!BVK~%^?QN(n%W2;xJ?lMiCBwLqu#?-O@ zr=7CL53N+!>%c@sdLJ?fdH7oUKZBYVUZ9%tsV-^Ok-M2O* KURKV3|MwqN8tCW% delta 2944 zcmZ`*ZA^_}81C(ylw%F~n1h$oB11lA$Vxe-X|z7h>KrBcW?50Fsfl6;CAOys&9p-b zeYp*BMni@CV4B3y^yT}EgG|GC?|z>9_V>D;>$>jydG6zb%Kp0#G94nBmxJ?y6Q87YhlEiCTfJed9Tw+10Zx=5#2sK zRPV%U;)fNF-#CMPb3}1cJ0~#LC(|orPtD`jLgSWb)*RNRjbXch`{}_v5wqRE5wiG} z5$>1`TQaAxxuR!BqvPWKY3BS#@b4?cQ2>o&*)uQM!eciCzIv7c7HyCw7cl8n} z0tF+lJ)$YtjZfV?R!~*fLle;Hm1Pu9EVw<9jex59{}A$>NxY)qF7vaa%nCR+_%VtS z84fj41#~opFsqfOQyy5jrbYV0^&AcpnmyfE;>c4SpU~Ixg$R`S6~52j6Wq}H*Aau= z&j;|vPue~?F7AK6TwmHa90ILs-YEYSf93bJS5N_d@v>eYWe;AMx+0ipS$yq^WpJ%1 j><;E|(Dk^|E24Y|A^qJkS`yBp@k1#s34c{XY`^{iZr!y{ diff --git a/PythonHome/Lib/logging/config.py b/PythonHome/Lib/logging/config.py new file mode 100644 index 0000000000..8b3795675d --- /dev/null +++ b/PythonHome/Lib/logging/config.py @@ -0,0 +1,919 @@ +# Copyright 2001-2014 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-2014 Vinay Sajip. All Rights Reserved. + +To use, simply 'import logging' and log away! +""" + +import cStringIO +import errno +import io +import logging +import logging.handlers +import os +import re +import socket +import struct +import sys +import traceback +import types + +try: + import thread + import threading +except ImportError: + thread = None + +from SocketServer import ThreadingTCPServer, StreamRequestHandler + + +DEFAULT_LOGGING_CONFIG_PORT = 9030 + +RESET_ERROR = errno.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 + else: + logger.disabled = disable_existing_loggers + + + +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 + + +class ConvertingMixin(object): + """For ConvertingXXX's, this mixin class provides common functions""" + + def convert_with_key(self, key, value, replace=True): + result = self.configurator.convert(value) + #If the converted value is different, save for next time + if value is not result: + if replace: + self[key] = result + if type(result) in (ConvertingDict, ConvertingList, + ConvertingTuple): + result.parent = self + result.key = key + return result + + def convert(self, value): + result = self.configurator.convert(value) + if value is not result: + if type(result) in (ConvertingDict, ConvertingList, + ConvertingTuple): + result.parent = self + return result + + +# 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, ConvertingMixin): + """A converting dictionary wrapper.""" + + def __getitem__(self, key): + value = dict.__getitem__(self, key) + return self.convert_with_key(key, value) + + def get(self, key, default=None): + value = dict.get(self, key, default) + return self.convert_with_key(key, value) + + def pop(self, key, default=None): + value = dict.pop(self, key, default) + return self.convert_with_key(key, value, replace=False) + +class ConvertingList(list, ConvertingMixin): + """A converting list wrapper.""" + def __getitem__(self, key): + value = list.__getitem__(self, key) + return self.convert_with_key(key, value) + + def pop(self, idx=-1): + value = list.pop(self, idx) + return self.convert(value) + +class ConvertingTuple(tuple, ConvertingMixin): + """A converting tuple wrapper.""" + def __getitem__(self, key): + value = tuple.__getitem__(self, key) + # Can't replace a tuple entry. + return self.convert_with_key(key, value, replace=False) + +class BaseConfigurator(object): + """ + The configurator base class which defines some useful defaults. + """ + + CONVERT_PATTERN = re.compile(r'^(?P[a-z]+)://(?P.*)$') + + 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 + # Issue 12718: winpdb replaces __import__ with a Python function, which + # ends up being treated as a bound method. To avoid problems, we + # set the importer on the instance, but leave it defined in the class + # so existing code doesn't break + if type(__import__) == types.FunctionType: + self.importer = __import__ + + 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 as 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 as 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 as 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 as 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 as 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) + deferred = [] + for name in sorted(handlers): + try: + handler = self.configure_handler(handlers[name]) + handler.name = name + handlers[name] = handler + except StandardError as e: + if 'target not configured yet' in str(e): + deferred.append(name) + else: + raise ValueError('Unable to configure handler ' + '%r: %s' % (name, e)) + + # Now do any that were deferred + for name in deferred: + try: + handler = self.configure_handler(handlers[name]) + handler.name = name + handlers[name] = handler + except StandardError as 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 as 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 as 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 as 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 as 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 as 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: + cname = config.pop('class') + klass = self.resolve(cname) + #Special case for handler which refers to another handler + if issubclass(klass, logging.handlers.MemoryHandler) and\ + 'target' in config: + try: + th = self.config['handlers'][config['target']] + if not isinstance(th, logging.Handler): + config['class'] = cname # restore for deferred configuration + raise StandardError('target not configured yet') + config['target'] = th + except StandardError as 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 as 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 as 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 as e: + if e.errno != 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): + import select + abort = 0 + while not abort: + rd, wr, ex = select.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/PythonHome/Lib/logging/config.pyc b/PythonHome/Lib/logging/config.pyc deleted file mode 100644 index a0369b5b107b942b9ad38099f27aba90e1324039..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 25686 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 diff --git a/PythonHome/Lib/logging/handlers.py b/PythonHome/Lib/logging/handlers.py new file mode 100644 index 0000000000..b7bf931aa4 --- /dev/null +++ b/PythonHome/Lib/logging/handlers.py @@ -0,0 +1,1222 @@ +# Copyright 2001-2013 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-2013 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) + # Issue 18940: A file may not have been created if delay is True. + if os.path.exists(self.baseFilename): + os.rename(self.baseFilename, dfn) + if not self.delay: + 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) + # Issue 18940: A file may not have been created if delay is True. + if os.path.exists(self.baseFilename): + os.rename(self.baseFilename, dfn) + if self.backupCount > 0: + for s in self.getFilesToDelete(): + os.remove(s) + if not self.delay: + 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() + self.stream = None # See Issue #21742: _open () might fail. + # 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 : + # ====================================================================== + # 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=None): + """ + 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. If socktype is + specified as socket.SOCK_DGRAM or socket.SOCK_STREAM, that specific + socket type will be used. For Unix sockets, you can also specify a + socktype of None, in which case socket.SOCK_DGRAM will be used, falling + back to socket.SOCK_STREAM. + """ + 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 + if socktype is None: + socktype = socket.SOCK_DGRAM + self.socket = socket.socket(socket.AF_INET, socktype) + if socktype == socket.SOCK_STREAM: + self.socket.connect(address) + self.socktype = socktype + self.formatter = None + + def _connect_unixsocket(self, address): + use_socktype = self.socktype + if use_socktype is None: + use_socktype = socket.SOCK_DGRAM + self.socket = socket.socket(socket.AF_UNIX, use_socktype) + try: + self.socket.connect(address) + # it worked, so set self.socktype to the used type + self.socktype = use_socktype + except socket.error: + self.socket.close() + if self.socktype is not None: + # user didn't specify falling back, so fail + raise + use_socktype = socket.SOCK_STREAM + self.socket = socket.socket(socket.AF_UNIX, use_socktype) + try: + self.socket.connect(address) + # it worked, so set self.socktype to the used type + self.socktype = use_socktype + 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.socket.close() # See issue 17981 + 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/PythonHome/Lib/logging/handlers.pyc b/PythonHome/Lib/logging/handlers.pyc deleted file mode 100644 index fb92502ccc925d87cefe1c439d6ea8c8f8b5d5e8..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 38918 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 G=l&n?yQ41v diff --git a/PythonHome/Lib/macpath.py b/PythonHome/Lib/macpath.py new file mode 100644 index 0000000000..cd4cb8581a --- /dev/null +++ b/PythonHome/Lib/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 .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/PythonHome/Lib/macpath.pyc b/PythonHome/Lib/macpath.pyc deleted file mode 100644 index 7b81857965fbd21d6b5e30fd8257395764a4ac93..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 7362 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 L+NIi4wYmQQU)MoI diff --git a/PythonHome/Lib/macurl2path.py b/PythonHome/Lib/macurl2path.py new file mode 100644 index 0000000000..6f8260f104 --- /dev/null +++ b/PythonHome/Lib/macurl2path.py @@ -0,0 +1,77 @@ +"""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 diff --git a/PythonHome/Lib/macurl2path.pyc b/PythonHome/Lib/macurl2path.pyc deleted file mode 100644 index 0ad92dd51b6b4f16d5f2acbc0a73b3e44e047496..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2184 zcma)7O>ZMb5Un0Nlf-d8_A{{*l$H=$Yo)be1+282MW77_#1f>jAW~RlCNu4%?QxGY z-3}X(To(Sz-Z*pT06&5M!5P7;9@_~45iEC2byam$clCQSmEV_ZKka?fNoev5@caCC5dU=>w^abt+C<`cM3JT^+UIc{oky4b#a(coKn#IgBdC zGYtDHERLuz=#1!lfA+>XCW4B0SmI!V3hU1I;#EL~I228h=*J+SV%N_@+BzpPo0Ew| zYuMSpy0DKvE^wuDB!sNc%b)42Las_@0ow;e#g2duVN+CCG+L5+ixl>IJb4>KW$5ze-P;?1&0yp06fz_Pl(=i*8*L7y&0>3`Y{Z!KEb(ylukHzEcbg1>h)))==0RD+ z=1@gTJmqS`c;tA}9T|ojztug=a_a%hh5a&Z;{zM<7oo|^q7@cvEN-w3<2pz(oZiK- zn;cxJdmu6hF@grX$W7Wnz z<=av6*mIYuR+5f$d;ZP{_J8(&2dh5i++2V}LzJ%s&fV>%dD87htVeetJjc7;ILlzg loFc9naf*vl|4m{4R@g4T^B;IzaPz|eeGBTr;{C<-zX0Jg#qt0E diff --git a/PythonHome/Lib/mailbox.py b/PythonHome/Lib/mailbox.py new file mode 100644 index 0000000000..ba49753087 --- /dev/null +++ b/PythonHome/Lib/mailbox.py @@ -0,0 +1,2236 @@ +"""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) + if isinstance(message, MaildirMessage): + os.utime(tmp_file.name, + (os.path.getatime(tmp_file.name), message.get_date())) + # No file modification should be done after the file is moved to its + # final position in order to prevent race conditions with changes + # from other programs + 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 + 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) + tmp_path = os.path.join(self._path, temp_subpath) + new_path = os.path.join(self._path, subdir, key + suffix) + if isinstance(message, MaildirMessage): + os.utime(tmp_path, + (os.path.getatime(tmp_path), message.get_date())) + # No file modification should be done after the file is moved to its + # final position in order to prevent race conditions with changes + # from other programs + os.rename(tmp_path, new_path) + + 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/PythonHome/Lib/mailbox.pyc b/PythonHome/Lib/mailbox.pyc deleted file mode 100644 index 299bd3d7c5ec81cbf2ca84a1164b4079f9501825..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 73406 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 diff --git a/PythonHome/Lib/mailcap.py b/PythonHome/Lib/mailcap.py new file mode 100644 index 0000000000..04077ba0db --- /dev/null +++ b/PythonHome/Lib/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 + with fp: + morecaps = readmailcapfile(fp) + 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/PythonHome/Lib/mailcap.pyc b/PythonHome/Lib/mailcap.pyc deleted file mode 100644 index b5576b502558c32481d83fba0689715f5c066177..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6883 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') +_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 (""). + # 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] == "": + # 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 content + def parse_marked_section(self, i, report=1): + rawdata= self.rawdata + assert rawdata[i:i+3] == ' 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] != '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¹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 aQTB_d7W+#Ku%Ar-oqu|N_TTprevline 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/PythonHome/Lib/quopri.pyc b/PythonHome/Lib/quopri.pyc index 8d0f48c9746552c9e602699e36814d373a0658bf..a76d56faad4a7163078548c37be6aab2d675fa95 100644 GIT binary patch delta 646 zcmexr^xAa8Ek;I`&9@onF&bJkFfgQA#iVDJWRxbwgy&c2c?J9X1qC?A_?MOxl$OM} zq$ZW7#{^WCWaQ_0&9@onG4e|?Ffce<#ROEAWaQ@=nNMEDd=_17^9q(8W=7V@rW|)L zq?|Y%G0fP!g)0q1aI!a#F(dotdLC{T3`2GccwnkG5i(|Eo}3|sVdvyhVRc59&2xnl bFg59kS~Ie3&Jtb4jA4nZq&lYhxl(=rs5wdV diff --git a/PythonHome/Lib/random.py b/PythonHome/Lib/random.py new file mode 100644 index 0000000000..3f96a3770b --- /dev/null +++ b/PythonHome/Lib/random.py @@ -0,0 +1,910 @@ +"""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: + # Seed with enough bytes to span the 19937 bit + # state space for the Mersenne Twister + a = long(_hexlify(_urandom(2500)), 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, _maxwidth=1L< 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< 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): + """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 + _int = int + 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() + try: + c = 0.5 if mode is None else (mode - low) / (high - low) + except ZeroDivisionError: + return 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/PythonHome/Lib/random.pyc b/PythonHome/Lib/random.pyc index 9e61c7df180cd1a97b73338924861788c91d0c1e..874c2acb7699932061e13e070ccf1df97299f775 100644 GIT binary patch delta 2408 zcmeA?#<>3?GhE%JV^vsfs(xjO1{0cp@A)~md-vhbj3>8GO}%+En&$*y5`M~WjM(RncuSNKs%M?`pHQ!2NiCS;nG!# zKgn_FCS^lLj?GV$li5hOb8?v0U($7LPSQ3YBUm;s)SX6#2RFOvPb5d%GlMteXnSZB zz)X6OOm;By2Bw!Dv&rP7Q9bKKa>8?-Z2}oSoXl%~jdTxg{$wvqhGm;Y9OcN-=IAtu zoPd1fmQ03ilS4cXkP#xvo?c{Fwz293-KH@DIx?V?ClCEoWaa15V;c+>p Wkcd7E*SJm~L3(kbq(GWLu|e=mu|gaTdl< zxVghc4pZ>D>m*FeXL%)KsGO|la{%3*$%#V3n~i+UF%>t83U6NPCxq$c4}lgyFKY%J z!tfm^5l_|+H33SegigYgR*z^!w}1292u%!yo6Vz_VLFH}b`QGl$-iUYVu(q`SE7q; ZJ{%v2X^U%8A%^cZKTnm!Pzm%`9{|_4488yW diff --git a/PythonHome/Lib/re.py b/PythonHome/Lib/re.py new file mode 100644 index 0000000000..9b01f3e228 --- /dev/null +++ b/PythonHome/Lib/re.py @@ -0,0 +1,327 @@ +# +# 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...) 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). + (?= 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 + pattern, flags = key + bypass_cache = flags & DEBUG + if not bypass_cache: + cachekey = (type(key[0]),) + key + p = _cache.get(cachekey) + if p is not None: + return p + 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 not bypass_cache: + 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/PythonHome/Lib/re.pyc b/PythonHome/Lib/re.pyc index 631953dea1a74152abbcfdb2cf45459ea5ba024b..b2d643d31609c5da23a513fb43bc947c0ff939e3 100644 GIT binary patch delta 1158 zcmeyGx<7k^gt(zO0|SGrRZMzjNk(Z>On82Uo>#EHUr>N^jDKlKL1{^hOKMVSdQ3oN zNk)F2M}BVVWOeaRr0d$OA@Pxs9BopWOk`+VAj3qCZ5w6V$kFB|?@Wfa$uktzknXj~ z!HVn2&?Ts}mULa4&nhh=!(*G9R1T06X@TnTWY{)&zs6qDy*9a9Q-_gd@(xXM^tNdE pkzwOQttQfSZ7$MICnqdl=$;`bED!6~lHo>w19>vsIJwrS0suU8mEZsX delta 444 zcmdm={WW!iggCz_0|SGzRZKu-Nk)F2k@;j#@lWVtn{y;SGGYk!No6u&2x`bOVXBOl zYr_;2QgFr)oZP0k2HnWX$x7=n#GIAaqKj=-R9S{$;N~By2QVG^QX?Ki<>X4Oz34_x zPS@69WS%@l8&jr9#}7j_qiz$r*yb&|>6rHW7@Wbh-_xiTL-%(hc?{i?-AyY1e}8-M diff --git a/PythonHome/Lib/repr.py b/PythonHome/Lib/repr.py new file mode 100644 index 0000000000..3c26cc39a2 --- /dev/null +++ b/PythonHome/Lib/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/PythonHome/Lib/repr.pyc b/PythonHome/Lib/repr.pyc deleted file mode 100644 index 5b903597762515c81198d4e90f524b8d393a8ace..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5130 zcmb_gUvC^&6+bik&+Dx1G^Vym0~x4R8Pi}1BoHm3gtmY{l^+$Yp z?oDeaULoW@z$ZZh3BCXi{T#gU$TJ@Re!p{PXI#4GBr|z7 zNGo%F484QL{23&LhOj|YXV~W{1B-oS>ZSFcdqUG1I@l}?hH0g-Fl|An+LE-DS(Ic^ znQM|G(HN0}u_mXukRWLcRNiF)A*v>8xmKGgADJZ29BN}Y(r6$5?U2=w)J3i{TR zfxd1E$~p$hItI$tRR+p7l!3BMWuUAeGA-=2ovFtfU^6;4`z}dH@-2|?8i-v0IqV8EKvd$CU^d1|=?XEI}F6aAv-AI~O|Y+yAe5HhK?9VfqAjGv_=4wOqL>653aB~&PA zi)^$vTOuEWFU7`yPvHVhWlfszQdLo6mcVU&^nUjEBcft!a;%@laW=|q953>NHA;K! zOMV9o0iPNk4aF)L#9;`k9vyme>cee}*LFxzOSf^aA4U91$D(CUQ0C|=)gnr)<1t)F zya5-Wm9$H@{|^|ed!KrOy{8B|^r*=}Q;Ijq41FHBDKOy65O}ByBq27!hZ=ffD_#e`H@sEvroZC7 z>fOZe>mKlcq`^Z+&8We76A6nEsLMGAyW7i9D&ovO*kw5`xaycY#2 z$0DsD-iW#{?>%}|rq|?TQBFYH9QxRoC%>0zhl@doi1?$NbO<^u45WAnCEzgxLOO~f zKnVEO&h^_;#lm<3{PRP||w$l*_6fA=zGn2ilsXN=Sop6C|b_KJ6&_ z$N6z=#)VB2XU_s=UOFWFNJE01?t?E)=*&_5bxdHouDXXW8xk@8PI1EGr4{EvRmH3I z-@}L|9?@K^HTo+6-tZV}hcj20Nz3WVpue=P6;gEB-%-yqeFU9U6^DP}WsVc=2mlWz z=34|wZ(c0!GL`6i9Tmb=d+i8NAyDX#K4hIhIdq)@@rI6r1>={qYLD`uL#Q>V6D%n$ z`F1&kii18wn`);0w(R<{#@g}ZV|l<@pzE==d@+-3R<#8;3bd~Jj*5lm8|7)&W7%M+ z%d$ZaJf9j`{u~X$)YT87t!v&2x@J~a)Kw@cJX_DZW~z$#&H z{eWX{kZ3XbAvo@~$*W(O zK}@yDLt9rZUzY$8pW_2v;_Y>}8^eofvP)AEBYV6`S}^|X`Q*$uWn}U*K;nbmi;;|Q*ZGK_Kmo#0x553305^+nyu@sU9CJ; z0rKwc}kzi&FeTJdgioV4=np2hh_*0*^9Z^gci>Ex`lewba3XWt&#k zJMB6*0JIr!&&^zPaKmA;TK2qyd7!opFN62GCdfv{_D6#>=-Z%s^mc~f%kC!h%^a(G zvHkVYAf50Z9Qqc=gS>AHE*!j)!gef^xE!Rw{w6TZ9$2%;Oz9j0<_3s(HE*@Hgv>Du zRjAoZbzyCZk;{Pe!iBl16bbidSpOE~F~hJ{72#bB~t^suTQI%9GxM(FX8@ zA_qK$#1ro~Zt4R7b#{ekDc9Dl?0I;m-6a9dq+av&rZ?C961CZLJi}v{K%`#tmeH)a zFNgt6`*EC%2e_58n#6HG&*4?(F$IENJ;vkQ=siZ=ptVP@BmIcwg2v93Q0}58+K%3H WQG1(TXa;Ng9lzsU_g4$J&ig-34<>d1 diff --git a/PythonHome/Lib/rexec.py b/PythonHome/Lib/rexec.py new file mode 100644 index 0000000000..74461512dd --- /dev/null +++ b/PythonHome/Lib/rexec.py @@ -0,0 +1,588 @@ +"""Restricted execution facilities. + +The class RExec exports methods r_exec(), r_eval(), r_execfile(), and +r_import(), which correspond roughly to the built-in operations +exec, eval(), execfile() and import, but executing the code in an +environment that only exposes those built-in operations that are +deemed safe. To this end, a modest collection of 'fake' modules is +created which mimics the standard modules by the same names. It is a +policy decision which built-in modules and operations are made +available; this module provides a reasonable default, but derived +classes can change the policies e.g. by overriding or extending class +variables like ok_builtin_modules or methods like make_sys(). + +XXX To do: +- r_open should allow writing tmp dir +- r_exec etc. with explicit globals/locals? (Use rexec("exec ... in ...")?) + +""" +from warnings import warnpy3k +warnpy3k("the rexec module has been removed in Python 3.0", stacklevel=2) +del warnpy3k + + +import sys +import __builtin__ +import os +import ihooks +import imp + +__all__ = ["RExec"] + +class FileBase: + + ok_file_methods = ('fileno', 'flush', 'isatty', 'read', 'readline', + 'readlines', 'seek', 'tell', 'write', 'writelines', 'xreadlines', + '__iter__') + + +class FileWrapper(FileBase): + + # XXX This is just like a Bastion -- should use that! + + def __init__(self, f): + for m in self.ok_file_methods: + if not hasattr(self, m) and hasattr(f, m): + setattr(self, m, getattr(f, m)) + + def close(self): + self.flush() + + +TEMPLATE = """ +def %s(self, *args): + return getattr(self.mod, self.name).%s(*args) +""" + +class FileDelegate(FileBase): + + def __init__(self, mod, name): + self.mod = mod + self.name = name + + for m in FileBase.ok_file_methods + ('close',): + exec TEMPLATE % (m, m) + + +class RHooks(ihooks.Hooks): + + def __init__(self, *args): + # Hacks to support both old and new interfaces: + # old interface was RHooks(rexec[, verbose]) + # new interface is RHooks([verbose]) + verbose = 0 + rexec = None + if args and type(args[-1]) == type(0): + verbose = args[-1] + args = args[:-1] + if args and hasattr(args[0], '__class__'): + rexec = args[0] + args = args[1:] + if args: + raise TypeError, "too many arguments" + ihooks.Hooks.__init__(self, verbose) + self.rexec = rexec + + def set_rexec(self, rexec): + # Called by RExec instance to complete initialization + self.rexec = rexec + + def get_suffixes(self): + return self.rexec.get_suffixes() + + def is_builtin(self, name): + return self.rexec.is_builtin(name) + + def init_builtin(self, name): + m = __import__(name) + return self.rexec.copy_except(m, ()) + + def init_frozen(self, name): raise SystemError, "don't use this" + def load_source(self, *args): raise SystemError, "don't use this" + def load_compiled(self, *args): raise SystemError, "don't use this" + def load_package(self, *args): raise SystemError, "don't use this" + + def load_dynamic(self, name, filename, file): + return self.rexec.load_dynamic(name, filename, file) + + def add_module(self, name): + return self.rexec.add_module(name) + + def modules_dict(self): + return self.rexec.modules + + def default_path(self): + return self.rexec.modules['sys'].path + + +# XXX Backwards compatibility +RModuleLoader = ihooks.FancyModuleLoader +RModuleImporter = ihooks.ModuleImporter + + +class RExec(ihooks._Verbose): + """Basic restricted execution framework. + + Code executed in this restricted environment will only have access to + modules and functions that are deemed safe; you can subclass RExec to + add or remove capabilities as desired. + + The RExec class can prevent code from performing unsafe operations like + reading or writing disk files, or using TCP/IP sockets. However, it does + not protect against code using extremely large amounts of memory or + processor time. + + """ + + ok_path = tuple(sys.path) # That's a policy decision + + ok_builtin_modules = ('audioop', 'array', 'binascii', + 'cmath', 'errno', 'imageop', + 'marshal', 'math', 'md5', 'operator', + 'parser', 'select', + 'sha', '_sre', 'strop', 'struct', 'time', + '_weakref') + + ok_posix_names = ('error', 'fstat', 'listdir', 'lstat', 'readlink', + 'stat', 'times', 'uname', 'getpid', 'getppid', + 'getcwd', 'getuid', 'getgid', 'geteuid', 'getegid') + + ok_sys_names = ('byteorder', 'copyright', 'exit', 'getdefaultencoding', + 'getrefcount', 'hexversion', 'maxint', 'maxunicode', + 'platform', 'ps1', 'ps2', 'version', 'version_info') + + nok_builtin_names = ('open', 'file', 'reload', '__import__') + + ok_file_types = (imp.C_EXTENSION, imp.PY_SOURCE) + + def __init__(self, hooks = None, verbose = 0): + """Returns an instance of the RExec class. + + The hooks parameter is an instance of the RHooks class or a subclass + of it. If it is omitted or None, the default RHooks class is + instantiated. + + Whenever the RExec module searches for a module (even a built-in one) + or reads a module's code, it doesn't actually go out to the file + system itself. Rather, it calls methods of an RHooks instance that + was passed to or created by its constructor. (Actually, the RExec + object doesn't make these calls --- they are made by a module loader + object that's part of the RExec object. This allows another level of + flexibility, which can be useful when changing the mechanics of + import within the restricted environment.) + + By providing an alternate RHooks object, we can control the file + system accesses made to import a module, without changing the + actual algorithm that controls the order in which those accesses are + made. For instance, we could substitute an RHooks object that + passes all filesystem requests to a file server elsewhere, via some + RPC mechanism such as ILU. Grail's applet loader uses this to support + importing applets from a URL for a directory. + + If the verbose parameter is true, additional debugging output may be + sent to standard output. + + """ + + raise RuntimeError, "This code is not secure in Python 2.2 and later" + + ihooks._Verbose.__init__(self, verbose) + # XXX There's a circular reference here: + self.hooks = hooks or RHooks(verbose) + self.hooks.set_rexec(self) + self.modules = {} + self.ok_dynamic_modules = self.ok_builtin_modules + list = [] + for mname in self.ok_builtin_modules: + if mname in sys.builtin_module_names: + list.append(mname) + self.ok_builtin_modules = tuple(list) + self.set_trusted_path() + self.make_builtin() + self.make_initial_modules() + # make_sys must be last because it adds the already created + # modules to its builtin_module_names + self.make_sys() + self.loader = RModuleLoader(self.hooks, verbose) + self.importer = RModuleImporter(self.loader, verbose) + + def set_trusted_path(self): + # Set the path from which dynamic modules may be loaded. + # Those dynamic modules must also occur in ok_builtin_modules + self.trusted_path = filter(os.path.isabs, sys.path) + + def load_dynamic(self, name, filename, file): + if name not in self.ok_dynamic_modules: + raise ImportError, "untrusted dynamic module: %s" % name + if name in sys.modules: + src = sys.modules[name] + else: + src = imp.load_dynamic(name, filename, file) + dst = self.copy_except(src, []) + return dst + + def make_initial_modules(self): + self.make_main() + self.make_osname() + + # Helpers for RHooks + + def get_suffixes(self): + return [item # (suff, mode, type) + for item in imp.get_suffixes() + if item[2] in self.ok_file_types] + + def is_builtin(self, mname): + return mname in self.ok_builtin_modules + + # The make_* methods create specific built-in modules + + def make_builtin(self): + m = self.copy_except(__builtin__, self.nok_builtin_names) + m.__import__ = self.r_import + m.reload = self.r_reload + m.open = m.file = self.r_open + + def make_main(self): + self.add_module('__main__') + + def make_osname(self): + osname = os.name + src = __import__(osname) + dst = self.copy_only(src, self.ok_posix_names) + dst.environ = e = {} + for key, value in os.environ.items(): + e[key] = value + + def make_sys(self): + m = self.copy_only(sys, self.ok_sys_names) + m.modules = self.modules + m.argv = ['RESTRICTED'] + m.path = map(None, self.ok_path) + m.exc_info = self.r_exc_info + m = self.modules['sys'] + l = self.modules.keys() + list(self.ok_builtin_modules) + l.sort() + m.builtin_module_names = tuple(l) + + # The copy_* methods copy existing modules with some changes + + def copy_except(self, src, exceptions): + dst = self.copy_none(src) + for name in dir(src): + setattr(dst, name, getattr(src, name)) + for name in exceptions: + try: + delattr(dst, name) + except AttributeError: + pass + return dst + + def copy_only(self, src, names): + dst = self.copy_none(src) + for name in names: + try: + value = getattr(src, name) + except AttributeError: + continue + setattr(dst, name, value) + return dst + + def copy_none(self, src): + m = self.add_module(src.__name__) + m.__doc__ = src.__doc__ + return m + + # Add a module -- return an existing module or create one + + def add_module(self, mname): + m = self.modules.get(mname) + if m is None: + self.modules[mname] = m = self.hooks.new_module(mname) + m.__builtins__ = self.modules['__builtin__'] + return m + + # The r* methods are public interfaces + + def r_exec(self, code): + """Execute code within a restricted environment. + + The code parameter must either be a string containing one or more + lines of Python code, or a compiled code object, which will be + executed in the restricted environment's __main__ module. + + """ + m = self.add_module('__main__') + exec code in m.__dict__ + + def r_eval(self, code): + """Evaluate code within a restricted environment. + + The code parameter must either be a string containing a Python + expression, or a compiled code object, which will be evaluated in + the restricted environment's __main__ module. The value of the + expression or code object will be returned. + + """ + m = self.add_module('__main__') + return eval(code, m.__dict__) + + def r_execfile(self, file): + """Execute the Python code in the file in the restricted + environment's __main__ module. + + """ + m = self.add_module('__main__') + execfile(file, m.__dict__) + + def r_import(self, mname, globals={}, locals={}, fromlist=[]): + """Import a module, raising an ImportError exception if the module + is considered unsafe. + + This method is implicitly called by code executing in the + restricted environment. Overriding this method in a subclass is + used to change the policies enforced by a restricted environment. + + """ + return self.importer.import_module(mname, globals, locals, fromlist) + + def r_reload(self, m): + """Reload the module object, re-parsing and re-initializing it. + + This method is implicitly called by code executing in the + restricted environment. Overriding this method in a subclass is + used to change the policies enforced by a restricted environment. + + """ + return self.importer.reload(m) + + def r_unload(self, m): + """Unload the module. + + Removes it from the restricted environment's sys.modules dictionary. + + This method is implicitly called by code executing in the + restricted environment. Overriding this method in a subclass is + used to change the policies enforced by a restricted environment. + + """ + return self.importer.unload(m) + + # The s_* methods are similar but also swap std{in,out,err} + + def make_delegate_files(self): + s = self.modules['sys'] + self.delegate_stdin = FileDelegate(s, 'stdin') + self.delegate_stdout = FileDelegate(s, 'stdout') + self.delegate_stderr = FileDelegate(s, 'stderr') + self.restricted_stdin = FileWrapper(sys.stdin) + self.restricted_stdout = FileWrapper(sys.stdout) + self.restricted_stderr = FileWrapper(sys.stderr) + + def set_files(self): + if not hasattr(self, 'save_stdin'): + self.save_files() + if not hasattr(self, 'delegate_stdin'): + self.make_delegate_files() + s = self.modules['sys'] + s.stdin = self.restricted_stdin + s.stdout = self.restricted_stdout + s.stderr = self.restricted_stderr + sys.stdin = self.delegate_stdin + sys.stdout = self.delegate_stdout + sys.stderr = self.delegate_stderr + + def reset_files(self): + self.restore_files() + s = self.modules['sys'] + self.restricted_stdin = s.stdin + self.restricted_stdout = s.stdout + self.restricted_stderr = s.stderr + + + def save_files(self): + self.save_stdin = sys.stdin + self.save_stdout = sys.stdout + self.save_stderr = sys.stderr + + def restore_files(self): + sys.stdin = self.save_stdin + sys.stdout = self.save_stdout + sys.stderr = self.save_stderr + + def s_apply(self, func, args=(), kw={}): + self.save_files() + try: + self.set_files() + r = func(*args, **kw) + finally: + self.restore_files() + return r + + def s_exec(self, *args): + """Execute code within a restricted environment. + + Similar to the r_exec() method, but the code will be granted access + to restricted versions of the standard I/O streams sys.stdin, + sys.stderr, and sys.stdout. + + The code parameter must either be a string containing one or more + lines of Python code, or a compiled code object, which will be + executed in the restricted environment's __main__ module. + + """ + return self.s_apply(self.r_exec, args) + + def s_eval(self, *args): + """Evaluate code within a restricted environment. + + Similar to the r_eval() method, but the code will be granted access + to restricted versions of the standard I/O streams sys.stdin, + sys.stderr, and sys.stdout. + + The code parameter must either be a string containing a Python + expression, or a compiled code object, which will be evaluated in + the restricted environment's __main__ module. The value of the + expression or code object will be returned. + + """ + return self.s_apply(self.r_eval, args) + + def s_execfile(self, *args): + """Execute the Python code in the file in the restricted + environment's __main__ module. + + Similar to the r_execfile() method, but the code will be granted + access to restricted versions of the standard I/O streams sys.stdin, + sys.stderr, and sys.stdout. + + """ + return self.s_apply(self.r_execfile, args) + + def s_import(self, *args): + """Import a module, raising an ImportError exception if the module + is considered unsafe. + + This method is implicitly called by code executing in the + restricted environment. Overriding this method in a subclass is + used to change the policies enforced by a restricted environment. + + Similar to the r_import() method, but has access to restricted + versions of the standard I/O streams sys.stdin, sys.stderr, and + sys.stdout. + + """ + return self.s_apply(self.r_import, args) + + def s_reload(self, *args): + """Reload the module object, re-parsing and re-initializing it. + + This method is implicitly called by code executing in the + restricted environment. Overriding this method in a subclass is + used to change the policies enforced by a restricted environment. + + Similar to the r_reload() method, but has access to restricted + versions of the standard I/O streams sys.stdin, sys.stderr, and + sys.stdout. + + """ + return self.s_apply(self.r_reload, args) + + def s_unload(self, *args): + """Unload the module. + + Removes it from the restricted environment's sys.modules dictionary. + + This method is implicitly called by code executing in the + restricted environment. Overriding this method in a subclass is + used to change the policies enforced by a restricted environment. + + Similar to the r_unload() method, but has access to restricted + versions of the standard I/O streams sys.stdin, sys.stderr, and + sys.stdout. + + """ + return self.s_apply(self.r_unload, args) + + # Restricted open(...) + + def r_open(self, file, mode='r', buf=-1): + """Method called when open() is called in the restricted environment. + + The arguments are identical to those of the open() function, and a + file object (or a class instance compatible with file objects) + should be returned. RExec's default behaviour is allow opening + any file for reading, but forbidding any attempt to write a file. + + This method is implicitly called by code executing in the + restricted environment. Overriding this method in a subclass is + used to change the policies enforced by a restricted environment. + + """ + mode = str(mode) + if mode not in ('r', 'rb'): + raise IOError, "can't open files for writing in restricted mode" + return open(file, mode, buf) + + # Restricted version of sys.exc_info() + + def r_exc_info(self): + ty, va, tr = sys.exc_info() + tr = None + return ty, va, tr + + +def test(): + import getopt, traceback + opts, args = getopt.getopt(sys.argv[1:], 'vt:') + verbose = 0 + trusted = [] + for o, a in opts: + if o == '-v': + verbose = verbose+1 + if o == '-t': + trusted.append(a) + r = RExec(verbose=verbose) + if trusted: + r.ok_builtin_modules = r.ok_builtin_modules + tuple(trusted) + if args: + r.modules['sys'].argv = args + r.modules['sys'].path.insert(0, os.path.dirname(args[0])) + else: + r.modules['sys'].path.insert(0, "") + fp = sys.stdin + if args and args[0] != '-': + try: + fp = open(args[0]) + except IOError, msg: + print "%s: can't open file %r" % (sys.argv[0], args[0]) + return 1 + if fp.isatty(): + try: + import readline + except ImportError: + pass + import code + class RestrictedConsole(code.InteractiveConsole): + def runcode(self, co): + self.locals['__builtins__'] = r.modules['__builtin__'] + r.s_apply(code.InteractiveConsole.runcode, (self, co)) + try: + RestrictedConsole(r.modules['__main__'].__dict__).interact() + except SystemExit, n: + return n + else: + text = fp.read() + fp.close() + c = compile(text, fp.name, 'exec') + try: + r.s_exec(c) + except SystemExit, n: + return n + except: + traceback.print_exc() + return 1 + + +if __name__ == '__main__': + sys.exit(test()) diff --git a/PythonHome/Lib/rexec.pyc b/PythonHome/Lib/rexec.pyc deleted file mode 100644 index 9f5b71ea0b074b060495cc47f538742b2482f606..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 23253 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 + +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/PythonHome/Lib/rfc822.pyc b/PythonHome/Lib/rfc822.pyc index f957ddc1ec2b4f2f9fbcd2e52f47b414c7343da0..b41fbd54346ff29c6860777393e30d68bcb9cdb7 100644 GIT binary patch delta 3353 zcmbW%+be@{7zgmZb1V_PxLM96iOn36(~M2l%8aEsyoh;ij&s;@%#FBEgr9b$$cRwr zNl9(j!UZneDwK;QMY&OO_z&LiAMojUp5OERJ+q(O*PQ$~kyn?u=lte?oPq# z99J4GwWfNrPN;RehTJYeFLt`^f_cK_a1I)r10rSf3Jze_*pE09#9VLYkaU zYDCy;@*C1*AT0`E;pxzm=rT@`*}^hcfF_wgFP?l^RY=7cxdPOSW)x6=0h=j*0A#h z5D8F0-N@1XJD=~}TR=UpeHu_oM=zju9dFVV?eyGoTm+5v`9c7#8`cByBF~5cVXvdB Qz$Kxjv2*0ZStk#F03W5H_W%F@ delta 1313 zcmey}%GCUgaf6&Nza#?#gR@mkKxIirex8x}W`AL6MhwB(BA?kX1ounpFkuMF$UVl? zZlDl>DY#SdJ*M`XDtwrN66%;1O}-c>wz*q#KBl?R+7mI2kkyOERJl@rKBme_qXbNq zTqcbef|K`{u0Z$xUU=*cQ} z+cCs0#tBcBx6i;3_ZJqMe9pcfL%h#n0ftz-<7o`BXs2QfvHwnAFvL_`;u)DYx40-_ zdf~e3J`Cl@+@7F|ZNBY(ff+;aj(0GIiJKFAMKA;>FZDA7y5PDW7DH|Xt-^@*$(uui z8JQQehhfNUwumsm5S%-Me zDHAXRC*Mk&kD+^2dJ$$o_+}QOE1dj3a}I{so~&yaVxZJ~BYPf(I4BwI&Dn|}{@+P# z^3L3a7~&xH3-i)2#4Yl(FvKqBzeg9_{JG#FBO}-5qeXjJG2}K^xL|mCvqqH%rr^Tr SNf@!UIi-FVX5jiatpNbP4THe| diff --git a/PythonHome/Lib/rlcompleter.py b/PythonHome/Lib/rlcompleter.py new file mode 100644 index 0000000000..6e4bd12ad3 --- /dev/null +++ b/PythonHome/Lib/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 + evaluable 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/PythonHome/Lib/rlcompleter.pyc b/PythonHome/Lib/rlcompleter.pyc deleted file mode 100644 index faf237e76f9dab44656e3ff983f9bb2cb5dd211e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5858 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 400 and self.errcode < 500: + 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() + + self.modified() + 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 + + # Until the robots.txt file has been read or found not + # to exist, we must assume that no url is allowable. + # This prevents false positives when a user erronenously + # calls can_fetch() before calling read(). + if not self.last_checked: + return False + + # 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 + path = urlparse.urlunparse(urlparse.urlparse(path)) + 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/PythonHome/Lib/robotparser.pyc b/PythonHome/Lib/robotparser.pyc deleted file mode 100644 index d61e9a5b35049ef98b44dd90c8df5eec7e651bd5..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 7600 zcmb7J&u`qu6&`X|EA3jcY%7W5)J_;Vb=HP0yF!W}s-4!B;~Zir0+qmx5SO6HS&0&t zTyeOORM?j~hoa~qMbdwuhXTE|K!FxH^jPGcLoex}K+%7oy{F&zW|zB8EJT()Pcy@r zH}ihKH>&-2rnPa|tVL?@Q^W6{pqYmNu~O@Rj*4BCI%*vq+jrHvtKyp4#AJ<~_?U|8 z>SLuIDfPj6UBweBo>ppis!AhkMkNA9HqP> z-^j~eSQuR_^bT4r4?oL!@1RIFw@RFHcI}$y-3m>agqinFs*_A7aoDwMKgj!D zg!yPI&yDsrbh)Q>=9PQ7mnM<10lcBK}q@ z`5HefN+(7a&TU*cF5k>X)n zM&G;%u&LAor2^4!c3f4~WTrmsOmMi}P!AmS$Wad1!*!rrK`)7KB>_%QN}lO*2Ax=U!hTu?{CH4KVCGJkg63&{OH7!i`Cb56HZd_85g%3s{UVj6;940( zTRPg&u^cX^7@c--ZKbfRjbBQDc?P|O5AP-$A3kn0C9fI;NtTpBa0Y$DTPUYF_&4K3 zurxJn!Yf{cd?3;MVEzK&>#|=!2qo0JOu7J%>p4Z>?Ln7$ZLgzC+&mu0gmx>M0A=VK z-RY-dIcc74UMc!nM&sMl8!!VXNWnA0(#tf=q0B`Gh(I_Y`!c;ZZectb>ZOY$kCO=e zJQzDx2=K{h+iS6h_FZhF)VieeWpoThuO@|4k7?CQn6@^QD)kWB;*e{Pte%N&t+gpD z^8vt`E}xQpv<$F$#DacNK&gcPV>DV1Fj5g-+mg)7`Xt$>Q#}gZRF^LJNN02jeM8Mw z6Vpy*Qlv-JpZ-M@8#W+5Lo8z}H>GrXVYwyTu%vVK5lHt*`XZVo*=<_OpdwTx z{|y5;m`9bch5T)o-r}Jv4#rit@1If+;aF;FyT+wIbJgy=dRSKv5cBGsai}NaYXa+W zBuefyRI#HYQ6!%dd_wR)f-it< zMfg4X+@{ire*?z6r!!rMXxO#lBVP@iXHOhtlp;V|k6IK_9&1_sUeVWngLkD%l7%Af zHaClK!2_iR_;DB2k$ow$09nnBIfCqE7h}-tz+s*PP>}yA=Ow4*Ogpn^FQPp=G6EXb zGS}V&V3-iYrv$HvEF{40OsV3=&_o=ydqZU> zgpw21hE@PFpk$x~TlfD>y}o__E9W7!8V2vG*J%e6%KVbLk1@4#eYDpi+_hh!<@ky| z5W;6ztsNK}k`g%^OQFZW2+Km6LaT$hAVG1&ME=N67<#zCV4c_-?}J->p>{6}=Ow$r zjUKrQUujAcL`Pf0EiP~fq-U(XB2xu{cIrAD53LH{-Qjm^wBzf8ZLl<=={qFbqWr1z zWWspQy4r53?PEivG*=)8uXkN{h;dRdel8e6ZA}$lJKQ+UjYvBN7b=gFB*9P<3|~8A zNTvh{kct=&M>6{)Bw!x?-y4xM?>?OHp5%4 zS*0poU{WrFx-zfI7m$gt2@b*_p@z_M{HHU*JZcijJQ#Lio`5ZZuqyPYRi`0~k@I6a z%w-s}(J{ZGEyLWP!TZ*KABP{aF&ic}JMh)TXJV@G;j(#c_cK@nZhle~UkV8))pqrf zm$$j!4G=giFtv@O@pz6CqxOqoBOTFmQFEzUC5QH)Dn3Og^1IqTg{}>Wq6?x1R0zrU ze5$8^g)4XP{DDD?du1RGYQgK6rdSP3ly!6rqS6O{R= zW(l)MOJEv{#>}&;uw~;sx6AP{3mehLBPgL96NOnIO!x(Gm{$N8mFv)}dIPQgJT&fm zh|bVYXxOZC5?@ca5xK>ilR=_kWC)Z48n$UwjZx}3=IbQ_jVKZ1f0}vP2`Y(|+lsK= z5L-(GDK@^HCz<676&VT4SfWW=I|^+SS`c7w5d4lvcv*t9-~0`y-bI8Q(m_F3}!HvvX>lHQ@UqK~y|4oy}x>J4{#s@ZH# zH7ACuh|Bmx*4#of7XdV00VM0O&k7%7C@BCt2;Vh%CYa#s09~cY0d9J9 zbCpLAhlTz8O;*TD^IluLE*0&@4d#Lu>DK3O4@&5z`JvMvUniyZMbwGJA)&zwVRYrz zg18<^jcu8iSOb9knLQv{pQT+-;}?<+>kMFXNJR*Tr49WJ)MhM!g9Bg^Z>t<+B2_vk z>SO)17^v9h4{@S3&^OoqF~makLECMWp}v5s0M#PllY~aIamO#qAJ#?T0$x- zRqJIfwY?WfIq4GDD_YORD?V3Rr51ld`$c3aO0$=YmsQqhp!BA$jx_A>t1bc2pNNdd zsL``Sbw#SLy-hJoneg1_#_o=FWv6eq$ z>(C^n_P9k{WTJnYKrD~MJe_UPa(<5{d3M8v&zfr1d@?RVlb_0-7BM`cJs}IGg*9kc zba>{+05>yFDgkc`?=j=q&?u3@YZ}VDpX(y8Ql%>A5D&`BRH9);WPK+}{Xs{J-98Z6 z>d&Syd=+>)rjwzcquII}zFf|ym#92ATsMz}>FvKd(2?8s&(cb*5<^>HfzX!C8XdR; zKYnljlB{Gs{*u(=qV6zVv`=wJ zSmedrs@fn$7(N(`UbHR2d~uNc+xi#b-zCiXmkB%q@sj*7<_xd%!#kWq`z~ilqx?IX zp{rH3GfX?(I+D(5XX*(IV~X@GbrL>+jbLDb1QJ91Nn*DJ4ltjiQJ8grRa72%7ANvB zZU0ulH_9ts-Y-0x!ac?i6fDA~VZ_2pK3mdvvY6qs3(`Qmd&E|4M3uzJh$oYjpOUsA z;tqRf0gl2IBKQ)`7Wj20O2-@dYCZKe@Q*c&REU>k4BOs?xH8+;B7SH0U$<0Vfj!XTL0_OYdtVjF<9QF zEJv9HqB!PTd=?#4uTs{XpT_(sk&{F(EH;nwawPlziR}aLHD@av-nH_cbY<{RgTEli zIV&sHM{?bmx}U^Q!W-VA((Z`)hw{B-jK*J9x;^~e0KO{d;ZH4l@xL%@V^}R>3}c%_ zTjo5`!UuwJaOO6}!E=h`BW)jjJnP^&gwKU!{@~S>OtQJlUG(H+{+TMk(`{Y^gFkw- zd6d;sd8H*2Iz69zt*b1GuGy4Sb_?%qcK;B*qfWeKJSTegn^; ecaSXRy3O+6BpHTk%2IpUZPw;KojW!6%KrhT@}&#_ diff --git a/PythonHome/Lib/runpy.py b/PythonHome/Lib/runpy.py new file mode 100644 index 0000000000..c4d7cc26a2 --- /dev/null +++ b/PythonHome/Lib/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 +# 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 = "" + 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/PythonHome/Lib/runpy.pyc b/PythonHome/Lib/runpy.pyc deleted file mode 100644 index a66ac7ff9b7174221795d183948bc82a1c47ed80..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8308 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 X7wXQ$OzT3cJ@N8r?UXZFYdik~WeB_8 diff --git a/PythonHome/Lib/sched.py b/PythonHome/Lib/sched.py new file mode 100644 index 0000000000..47646a1008 --- /dev/null +++ b/PythonHome/Lib/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/PythonHome/Lib/sched.pyc b/PythonHome/Lib/sched.pyc deleted file mode 100644 index b3f9ece42cc01c3388520af40c18ae0263afdb5e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4859 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])'. + """ + 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/PythonHome/Lib/sets.pyc b/PythonHome/Lib/sets.pyc deleted file mode 100644 index c378c2549fb9aed8c60173aefc0a3073dcdb41b6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 16055 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 WnZ{=CX=}W4_802ivlq_(;C}%Or;]*|' + '/([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 +# and , respectively, or do_foo to handle 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 + 1): + self.handle_data("<") + i = i+1 + else: + # incomplete + break + continue + if rawdata.startswith("2Z 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 o#^uy{#VkYz((|PAwC$^XW1i7IcUvG', 'eval', + dont_inherit=True) + +_cache = weakref.WeakValueDictionary() + +def compile(marker): + """Return compiled marker as a function accepting an environment dict.""" + try: + return _cache[marker] + except KeyError: + pass + if not marker.strip(): + def marker_fn(environment=None, override=None): + """""" + return True + else: + compiled_marker = compile_marker(parse_marker(marker)) + def marker_fn(environment=None, override=None): + """override updates environment""" + if override is None: + override = {} + if environment is None: + environment = default_environment() + environment.update(override) + return eval(compiled_marker, environment) + marker_fn.__doc__ = marker + _cache[marker] = marker_fn + return _cache[marker] + +def interpret(marker, environment=None): + return compile(marker)(environment) diff --git a/PythonHome/Lib/site-packages/_markerlib/markers.pyc b/PythonHome/Lib/site-packages/_markerlib/markers.pyc deleted file mode 100644 index 50e4b1bde103cf3b42a3c382def380b91e781750..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4894 zcmbtXZFAek5nh1Q3u(!+Wxd)?0(I(&?$}K0G)|h4-S|cJC{<|>=!sm$3I-yMGAIb3 zaYxCTQD!=ErZ0b>pV}YL5B&-KNB!0xkUYBwQdH_Ma!BI1*jwD~?epC3q4dA$>d)yv z%{CREar}RdOaI#;iilch9g19vO0-*|7UVKTW0bhmg3`*+mj-f~T2Na37`4U*@;J4| zNlj2|l8)v?IZjEL_AAt?kh7J3NM%)}y(;DZAjff3iMr<~nxH+G^1o9wN#DVl3cdO# zeM^)&^gNy`RH55ZRc@vzI!E3@G)1?$Z<@O2DVnC}JiURlGqfCCK#v{zBBV0g zyulJ@?ahqbT*6I7q&bX?70lD^)bF?>3`HF*X z$jkPxJI{U5BG10|YQ@2CD_WA3K)p=LrS2ki5Yx-7#Grp{Em3quES4#{D#B$_y(h{E1|fQ%zH_Mc9?Q+z2MpVP0oz7uRNl*#@t&?f^*;K|$DT?L;yg?DRcgHb zFyB+Tu2-w;&!768|!n z=7s5zmvubzGSlj_YSqK1cZ9n%IKTvPmU?%*)oZ$bO|N>_yqZ4J^`aw)(@yr)ueNV^ z|EK)*_Vv+`I{hRW8E(Y9u6s#rYS%H0Jdo*n8tyC1SxBPg2YN|pI$6GtuF+dNP0=^- z3^oJvfvQ$GG_c$c+b`pkCmLE7svlbx(TMkZiQ?FY#s+2h+*=KbQ9`eiE9GgE$La13 zFNyb*w|c97d-aBw<=*OHoPKm`wQ4Q_^+H z=u=!43fC|c_nObPUINA>)@Hb(bLhCwhW|pNkfV^!NOF`*oNCL`j!BCO0L_H7NZ*hv z)InuH_Qp^0GPhIIap{v2?X>irmv%E0y$JeTRH8+MaRK!D)}a&+ zq9US@Oz`SpgJ+wyG6vK)(X6Msj}$*#o|mP`5m<<%6{p$@lO#J-k(XwX(sfy01Lb0% zj?=f7m}|OvP5ZpnWE*^4v^8#5>~Nq zXGxHCI$9aS$c5S%4tWFqJj=sWbADI3kpBQ<8-d5?jV(Ka{eD+?{AG;t2$yEZ$(?n^ z@x5ZUMlclC|EVdf&a!8yKy=exC9EuT>k>iBNQ5=QXrtb zL>;Jvi!4-mywf+z3)^j_fdP|3Qelnb>o1~_r8ZCmZ5+a+ufPoiJCYtAL!#FSBeO^HK)e0E%?vXI|u~rAlT2M zeu7*7A`I-}c$p7S(L$VTxa!=`vgAomira8-{|b-CfNW-AB#UjD+@E7DLv=5WBqC38 z`CES_e~&Gx9-DQ!#rcV&wxK1A8yZX(#iljegc%1PYCK;^8>!I5{~0Uf5K04U5k+B zkbZHiFgQjrt)At5WzSB$fyB|M@bsOR%!n6r6hl3S#_kbk#x9u& z$;fc<^`FojO%O)sf;!A%hLz^^2D!4hzHWo8(81vcQ^i_3?lWQ7Oe6X0dp-! zz>dEm24eFUlGhQJ{w$U-K+Xz~r@$$R@tXZxE=mU@Fg&ryVKXYi>xHNqUZ`~cm4U`5S=5`xeTVb=UdJoa#ucNU<l9VbwlV!j z7^aI$@)EgIPQ{tRciL%40g{XmwDE3a6T$D*k(6*rko*$U^EqVxeQx-WBXvIrqO2VR z*6+`_i>I+WN$}pl?HL{A=f390I5Uu25+}=OXUntB{A9(co}8?hNz7q6?OSRC9t)D? zo;~~dJm`p*9O8G~?>~5-PK{qG{6C;6LV{Bj3ZE2ow#c+_d+>rHbqp^>VtlB= zyRdx%Z5pMPXa2^*RmxLtW$6cd Cv_Y=` diff --git a/PythonHome/Lib/site-packages/beautifulsoup4-4.3.2-py2.7.egg-info/PKG-INFO b/PythonHome/Lib/site-packages/beautifulsoup4-4.3.2-py2.7.egg-info/PKG-INFO new file mode 100644 index 0000000000..c9fbab8f8a --- /dev/null +++ b/PythonHome/Lib/site-packages/beautifulsoup4-4.3.2-py2.7.egg-info/PKG-INFO @@ -0,0 +1,20 @@ +Metadata-Version: 1.1 +Name: beautifulsoup4 +Version: 4.3.2 +Summary: UNKNOWN +Home-page: http://www.crummy.com/software/BeautifulSoup/bs4/ +Author: Leonard Richardson +Author-email: leonardr@segfault.org +License: MIT +Download-URL: http://www.crummy.com/software/BeautifulSoup/bs4/download/ +Description: Beautiful Soup sits atop an HTML or XML parser, providing Pythonic idioms for iterating, searching, and modifying the parse tree. +Platform: UNKNOWN +Classifier: Development Status :: 4 - Beta +Classifier: Intended Audience :: Developers +Classifier: License :: OSI Approved :: MIT License +Classifier: Programming Language :: Python +Classifier: Programming Language :: Python :: 3 +Classifier: Topic :: Text Processing :: Markup :: HTML +Classifier: Topic :: Text Processing :: Markup :: XML +Classifier: Topic :: Text Processing :: Markup :: SGML +Classifier: Topic :: Software Development :: Libraries :: Python Modules diff --git a/PythonHome/Lib/site-packages/beautifulsoup4-4.3.2-py2.7.egg-info/SOURCES.txt b/PythonHome/Lib/site-packages/beautifulsoup4-4.3.2-py2.7.egg-info/SOURCES.txt new file mode 100644 index 0000000000..d5fbda3bf9 --- /dev/null +++ b/PythonHome/Lib/site-packages/beautifulsoup4-4.3.2-py2.7.egg-info/SOURCES.txt @@ -0,0 +1,22 @@ +README.txt +beautifulsoup4.egg-info/PKG-INFO +beautifulsoup4.egg-info/SOURCES.txt +beautifulsoup4.egg-info/dependency_links.txt +beautifulsoup4.egg-info/top_level.txt +bs4/__init__.py +bs4/dammit.py +bs4/diagnose.py +bs4/element.py +bs4/testing.py +bs4/builder/__init__.py +bs4/builder/_html5lib.py +bs4/builder/_htmlparser.py +bs4/builder/_lxml.py +bs4/tests/__init__.py +bs4/tests/test_builder_registry.py +bs4/tests/test_docs.py +bs4/tests/test_html5lib.py +bs4/tests/test_htmlparser.py +bs4/tests/test_lxml.py +bs4/tests/test_soup.py +bs4/tests/test_tree.py \ No newline at end of file diff --git a/PythonHome/Lib/site-packages/beautifulsoup4-4.3.2-py2.7.egg-info/dependency_links.txt b/PythonHome/Lib/site-packages/beautifulsoup4-4.3.2-py2.7.egg-info/dependency_links.txt new file mode 100644 index 0000000000..8b13789179 --- /dev/null +++ b/PythonHome/Lib/site-packages/beautifulsoup4-4.3.2-py2.7.egg-info/dependency_links.txt @@ -0,0 +1 @@ + diff --git a/PythonHome/Lib/site-packages/beautifulsoup4-4.3.2-py2.7.egg-info/installed-files.txt b/PythonHome/Lib/site-packages/beautifulsoup4-4.3.2-py2.7.egg-info/installed-files.txt new file mode 100644 index 0000000000..1c4d344b9e --- /dev/null +++ b/PythonHome/Lib/site-packages/beautifulsoup4-4.3.2-py2.7.egg-info/installed-files.txt @@ -0,0 +1,39 @@ +..\bs4\dammit.py +..\bs4\diagnose.py +..\bs4\element.py +..\bs4\testing.py +..\bs4\__init__.py +..\bs4\builder\_html5lib.py +..\bs4\builder\_htmlparser.py +..\bs4\builder\_lxml.py +..\bs4\builder\__init__.py +..\bs4\tests\test_builder_registry.py +..\bs4\tests\test_docs.py +..\bs4\tests\test_html5lib.py +..\bs4\tests\test_htmlparser.py +..\bs4\tests\test_lxml.py +..\bs4\tests\test_soup.py +..\bs4\tests\test_tree.py +..\bs4\tests\__init__.py +..\bs4\dammit.pyc +..\bs4\diagnose.pyc +..\bs4\element.pyc +..\bs4\testing.pyc +..\bs4\__init__.pyc +..\bs4\builder\_html5lib.pyc +..\bs4\builder\_htmlparser.pyc +..\bs4\builder\_lxml.pyc +..\bs4\builder\__init__.pyc +..\bs4\tests\test_builder_registry.pyc +..\bs4\tests\test_docs.pyc +..\bs4\tests\test_html5lib.pyc +..\bs4\tests\test_htmlparser.pyc +..\bs4\tests\test_lxml.pyc +..\bs4\tests\test_soup.pyc +..\bs4\tests\test_tree.pyc +..\bs4\tests\__init__.pyc +.\ +dependency_links.txt +PKG-INFO +SOURCES.txt +top_level.txt diff --git a/PythonHome/Lib/site-packages/beautifulsoup4-4.3.2-py2.7.egg-info/top_level.txt b/PythonHome/Lib/site-packages/beautifulsoup4-4.3.2-py2.7.egg-info/top_level.txt new file mode 100644 index 0000000000..13154420d4 --- /dev/null +++ b/PythonHome/Lib/site-packages/beautifulsoup4-4.3.2-py2.7.egg-info/top_level.txt @@ -0,0 +1 @@ +bs4 diff --git a/PythonHome/Lib/site-packages/bs4/__init__.py b/PythonHome/Lib/site-packages/bs4/__init__.py new file mode 100644 index 0000000000..7ba34269af --- /dev/null +++ b/PythonHome/Lib/site-packages/bs4/__init__.py @@ -0,0 +1,406 @@ +"""Beautiful Soup +Elixir and Tonic +"The Screen-Scraper's Friend" +http://www.crummy.com/software/BeautifulSoup/ + +Beautiful Soup uses a pluggable XML or HTML parser to parse a +(possibly invalid) document into a tree representation. Beautiful Soup +provides provides methods and Pythonic idioms that make it easy to +navigate, search, and modify the parse tree. + +Beautiful Soup works with Python 2.6 and up. It works better if lxml +and/or html5lib is installed. + +For more than you ever wanted to know about Beautiful Soup, see the +documentation: +http://www.crummy.com/software/BeautifulSoup/bs4/doc/ +""" + +__author__ = "Leonard Richardson (leonardr@segfault.org)" +__version__ = "4.3.2" +__copyright__ = "Copyright (c) 2004-2013 Leonard Richardson" +__license__ = "MIT" + +__all__ = ['BeautifulSoup'] + +import os +import re +import warnings + +from .builder import builder_registry, ParserRejectedMarkup +from .dammit import UnicodeDammit +from .element import ( + CData, + Comment, + DEFAULT_OUTPUT_ENCODING, + Declaration, + Doctype, + NavigableString, + PageElement, + ProcessingInstruction, + ResultSet, + SoupStrainer, + Tag, + ) + +# The very first thing we do is give a useful error if someone is +# running this code under Python 3 without converting it. +syntax_error = u'You are trying to run the Python 2 version of Beautiful Soup under Python 3. This will not work. You need to convert the code, either by installing it (`python setup.py install`) or by running 2to3 (`2to3 -w bs4`).' + +class BeautifulSoup(Tag): + """ + This class defines the basic interface called by the tree builders. + + These methods will be called by the parser: + reset() + feed(markup) + + The tree builder may call these methods from its feed() implementation: + handle_starttag(name, attrs) # See note about return value + handle_endtag(name) + handle_data(data) # Appends to the current data node + endData(containerClass=NavigableString) # Ends the current data node + + No matter how complicated the underlying parser is, you should be + able to build a tree using 'start tag' events, 'end tag' events, + 'data' events, and "done with data" events. + + If you encounter an empty-element tag (aka a self-closing tag, + like HTML's
tag), call handle_starttag and then + handle_endtag. + """ + ROOT_TAG_NAME = u'[document]' + + # If the end-user gives no indication which tree builder they + # want, look for one with these features. + DEFAULT_BUILDER_FEATURES = ['html', 'fast'] + + ASCII_SPACES = '\x20\x0a\x09\x0c\x0d' + + def __init__(self, markup="", features=None, builder=None, + parse_only=None, from_encoding=None, **kwargs): + """The Soup object is initialized as the 'root tag', and the + provided markup (which can be a string or a file-like object) + is fed into the underlying parser.""" + + if 'convertEntities' in kwargs: + warnings.warn( + "BS4 does not respect the convertEntities argument to the " + "BeautifulSoup constructor. Entities are always converted " + "to Unicode characters.") + + if 'markupMassage' in kwargs: + del kwargs['markupMassage'] + warnings.warn( + "BS4 does not respect the markupMassage argument to the " + "BeautifulSoup constructor. The tree builder is responsible " + "for any necessary markup massage.") + + if 'smartQuotesTo' in kwargs: + del kwargs['smartQuotesTo'] + warnings.warn( + "BS4 does not respect the smartQuotesTo argument to the " + "BeautifulSoup constructor. Smart quotes are always converted " + "to Unicode characters.") + + if 'selfClosingTags' in kwargs: + del kwargs['selfClosingTags'] + warnings.warn( + "BS4 does not respect the selfClosingTags argument to the " + "BeautifulSoup constructor. The tree builder is responsible " + "for understanding self-closing tags.") + + if 'isHTML' in kwargs: + del kwargs['isHTML'] + warnings.warn( + "BS4 does not respect the isHTML argument to the " + "BeautifulSoup constructor. You can pass in features='html' " + "or features='xml' to get a builder capable of handling " + "one or the other.") + + def deprecated_argument(old_name, new_name): + if old_name in kwargs: + warnings.warn( + 'The "%s" argument to the BeautifulSoup constructor ' + 'has been renamed to "%s."' % (old_name, new_name)) + value = kwargs[old_name] + del kwargs[old_name] + return value + return None + + parse_only = parse_only or deprecated_argument( + "parseOnlyThese", "parse_only") + + from_encoding = from_encoding or deprecated_argument( + "fromEncoding", "from_encoding") + + if len(kwargs) > 0: + arg = kwargs.keys().pop() + raise TypeError( + "__init__() got an unexpected keyword argument '%s'" % arg) + + if builder is None: + if isinstance(features, basestring): + features = [features] + if features is None or len(features) == 0: + features = self.DEFAULT_BUILDER_FEATURES + builder_class = builder_registry.lookup(*features) + if builder_class is None: + raise FeatureNotFound( + "Couldn't find a tree builder with the features you " + "requested: %s. Do you need to install a parser library?" + % ",".join(features)) + builder = builder_class() + self.builder = builder + self.is_xml = builder.is_xml + self.builder.soup = self + + self.parse_only = parse_only + + if hasattr(markup, 'read'): # It's a file-type object. + markup = markup.read() + elif len(markup) <= 256: + # Print out warnings for a couple beginner problems + # involving passing non-markup to Beautiful Soup. + # Beautiful Soup will still parse the input as markup, + # just in case that's what the user really wants. + if (isinstance(markup, unicode) + and not os.path.supports_unicode_filenames): + possible_filename = markup.encode("utf8") + else: + possible_filename = markup + is_file = False + try: + is_file = os.path.exists(possible_filename) + except Exception, e: + # This is almost certainly a problem involving + # characters not valid in filenames on this + # system. Just let it go. + pass + if is_file: + warnings.warn( + '"%s" looks like a filename, not markup. You should probably open this file and pass the filehandle into Beautiful Soup.' % markup) + if markup[:5] == "http:" or markup[:6] == "https:": + # TODO: This is ugly but I couldn't get it to work in + # Python 3 otherwise. + if ((isinstance(markup, bytes) and not b' ' in markup) + or (isinstance(markup, unicode) and not u' ' in markup)): + warnings.warn( + '"%s" looks like a URL. Beautiful Soup is not an HTTP client. You should probably use an HTTP client to get the document behind the URL, and feed that document to Beautiful Soup.' % markup) + + for (self.markup, self.original_encoding, self.declared_html_encoding, + self.contains_replacement_characters) in ( + self.builder.prepare_markup(markup, from_encoding)): + self.reset() + try: + self._feed() + break + except ParserRejectedMarkup: + pass + + # Clear out the markup and remove the builder's circular + # reference to this object. + self.markup = None + self.builder.soup = None + + def _feed(self): + # Convert the document to Unicode. + self.builder.reset() + + self.builder.feed(self.markup) + # Close out any unfinished strings and close all the open tags. + self.endData() + while self.currentTag.name != self.ROOT_TAG_NAME: + self.popTag() + + def reset(self): + Tag.__init__(self, self, self.builder, self.ROOT_TAG_NAME) + self.hidden = 1 + self.builder.reset() + self.current_data = [] + self.currentTag = None + self.tagStack = [] + self.preserve_whitespace_tag_stack = [] + self.pushTag(self) + + def new_tag(self, name, namespace=None, nsprefix=None, **attrs): + """Create a new tag associated with this soup.""" + return Tag(None, self.builder, name, namespace, nsprefix, attrs) + + def new_string(self, s, subclass=NavigableString): + """Create a new NavigableString associated with this soup.""" + navigable = subclass(s) + navigable.setup() + return navigable + + def insert_before(self, successor): + raise NotImplementedError("BeautifulSoup objects don't support insert_before().") + + def insert_after(self, successor): + raise NotImplementedError("BeautifulSoup objects don't support insert_after().") + + def popTag(self): + tag = self.tagStack.pop() + if self.preserve_whitespace_tag_stack and tag == self.preserve_whitespace_tag_stack[-1]: + self.preserve_whitespace_tag_stack.pop() + #print "Pop", tag.name + if self.tagStack: + self.currentTag = self.tagStack[-1] + return self.currentTag + + def pushTag(self, tag): + #print "Push", tag.name + if self.currentTag: + self.currentTag.contents.append(tag) + self.tagStack.append(tag) + self.currentTag = self.tagStack[-1] + if tag.name in self.builder.preserve_whitespace_tags: + self.preserve_whitespace_tag_stack.append(tag) + + def endData(self, containerClass=NavigableString): + if self.current_data: + current_data = u''.join(self.current_data) + # If whitespace is not preserved, and this string contains + # nothing but ASCII spaces, replace it with a single space + # or newline. + if not self.preserve_whitespace_tag_stack: + strippable = True + for i in current_data: + if i not in self.ASCII_SPACES: + strippable = False + break + if strippable: + if '\n' in current_data: + current_data = '\n' + else: + current_data = ' ' + + # Reset the data collector. + self.current_data = [] + + # Should we add this string to the tree at all? + if self.parse_only and len(self.tagStack) <= 1 and \ + (not self.parse_only.text or \ + not self.parse_only.search(current_data)): + return + + o = containerClass(current_data) + self.object_was_parsed(o) + + def object_was_parsed(self, o, parent=None, most_recent_element=None): + """Add an object to the parse tree.""" + parent = parent or self.currentTag + most_recent_element = most_recent_element or self._most_recent_element + o.setup(parent, most_recent_element) + + if most_recent_element is not None: + most_recent_element.next_element = o + self._most_recent_element = o + parent.contents.append(o) + + def _popToTag(self, name, nsprefix=None, inclusivePop=True): + """Pops the tag stack up to and including the most recent + instance of the given tag. If inclusivePop is false, pops the tag + stack up to but *not* including the most recent instqance of + the given tag.""" + #print "Popping to %s" % name + if name == self.ROOT_TAG_NAME: + # The BeautifulSoup object itself can never be popped. + return + + most_recently_popped = None + + stack_size = len(self.tagStack) + for i in range(stack_size - 1, 0, -1): + t = self.tagStack[i] + if (name == t.name and nsprefix == t.prefix): + if inclusivePop: + most_recently_popped = self.popTag() + break + most_recently_popped = self.popTag() + + return most_recently_popped + + def handle_starttag(self, name, namespace, nsprefix, attrs): + """Push a start tag on to the stack. + + If this method returns None, the tag was rejected by the + SoupStrainer. You should proceed as if the tag had not occured + in the document. For instance, if this was a self-closing tag, + don't call handle_endtag. + """ + + # print "Start tag %s: %s" % (name, attrs) + self.endData() + + if (self.parse_only and len(self.tagStack) <= 1 + and (self.parse_only.text + or not self.parse_only.search_tag(name, attrs))): + return None + + tag = Tag(self, self.builder, name, namespace, nsprefix, attrs, + self.currentTag, self._most_recent_element) + if tag is None: + return tag + if self._most_recent_element: + self._most_recent_element.next_element = tag + self._most_recent_element = tag + self.pushTag(tag) + return tag + + def handle_endtag(self, name, nsprefix=None): + #print "End tag: " + name + self.endData() + self._popToTag(name, nsprefix) + + def handle_data(self, data): + self.current_data.append(data) + + def decode(self, pretty_print=False, + eventual_encoding=DEFAULT_OUTPUT_ENCODING, + formatter="minimal"): + """Returns a string or Unicode representation of this document. + To get Unicode, pass None for encoding.""" + + if self.is_xml: + # Print the XML declaration + encoding_part = '' + if eventual_encoding != None: + encoding_part = ' encoding="%s"' % eventual_encoding + prefix = u'\n' % encoding_part + else: + prefix = u'' + if not pretty_print: + indent_level = None + else: + indent_level = 0 + return prefix + super(BeautifulSoup, self).decode( + indent_level, eventual_encoding, formatter) + +# Alias to make it easier to type import: 'from bs4 import _soup' +_s = BeautifulSoup +_soup = BeautifulSoup + +class BeautifulStoneSoup(BeautifulSoup): + """Deprecated interface to an XML parser.""" + + def __init__(self, *args, **kwargs): + kwargs['features'] = 'xml' + warnings.warn( + 'The BeautifulStoneSoup class is deprecated. Instead of using ' + 'it, pass features="xml" into the BeautifulSoup constructor.') + super(BeautifulStoneSoup, self).__init__(*args, **kwargs) + + +class StopParsing(Exception): + pass + +class FeatureNotFound(ValueError): + pass + + +#By default, act as an HTML pretty-printer. +if __name__ == '__main__': + import sys + soup = BeautifulSoup(sys.stdin) + print soup.prettify() diff --git a/PythonHome/Lib/site-packages/bs4/__init__.pyc b/PythonHome/Lib/site-packages/bs4/__init__.pyc new file mode 100644 index 0000000000000000000000000000000000000000..ec20aa419c4c02bde68c720576478bd7aec0351f GIT binary patch literal 14358 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 Hw!;4hneAH- diff --git a/PythonHome/Lib/idlelib/FileList.py b/PythonHome/Lib/idlelib/FileList.py new file mode 100644 index 0000000000..8318ff17b2 --- /dev/null +++ b/PythonHome/Lib/idlelib/FileList.py @@ -0,0 +1,124 @@ +import os +from Tkinter import * +import tkMessageBox + + +class FileList: + + # N.B. this import overridden in PyShellFileList. + from idlelib.EditorWindow import EditorWindow + + def __init__(self, root): + self.root = root + self.dict = {} + self.inversedict = {} + self.vars = {} # For EditorWindow.getrawvar (shared Tcl variables) + + def open(self, filename, action=None): + assert filename + filename = self.canonize(filename) + if os.path.isdir(filename): + # This can happen when bad filename is passed on command line: + tkMessageBox.showerror( + "File Error", + "%r is a directory." % (filename,), + master=self.root) + return None + key = os.path.normcase(filename) + if key in self.dict: + edit = self.dict[key] + edit.top.wakeup() + return edit + if action: + # Don't create window, perform 'action', e.g. open in same window + return action(filename) + else: + return self.EditorWindow(self, filename, key) + + def gotofileline(self, filename, lineno=None): + edit = self.open(filename) + if edit is not None and lineno is not None: + edit.gotoline(lineno) + + def new(self, filename=None): + return self.EditorWindow(self, filename) + + def close_all_callback(self, *args, **kwds): + for edit in self.inversedict.keys(): + reply = edit.close() + if reply == "cancel": + break + return "break" + + def unregister_maybe_terminate(self, edit): + try: + key = self.inversedict[edit] + except KeyError: + print "Don't know this EditorWindow object. (close)" + return + if key: + del self.dict[key] + del self.inversedict[edit] + if not self.inversedict: + self.root.quit() + + def filename_changed_edit(self, edit): + edit.saved_change_hook() + try: + key = self.inversedict[edit] + except KeyError: + print "Don't know this EditorWindow object. (rename)" + return + filename = edit.io.filename + if not filename: + if key: + del self.dict[key] + self.inversedict[edit] = None + return + filename = self.canonize(filename) + newkey = os.path.normcase(filename) + if newkey == key: + return + if newkey in self.dict: + conflict = self.dict[newkey] + self.inversedict[conflict] = None + tkMessageBox.showerror( + "Name Conflict", + "You now have multiple edit windows open for %r" % (filename,), + master=self.root) + self.dict[newkey] = edit + self.inversedict[edit] = newkey + if key: + try: + del self.dict[key] + except KeyError: + pass + + def canonize(self, filename): + if not os.path.isabs(filename): + try: + pwd = os.getcwd() + except os.error: + pass + else: + filename = os.path.join(pwd, filename) + return os.path.normpath(filename) + + +def _test(): + from idlelib.EditorWindow import fixwordbreaks + import sys + root = Tk() + fixwordbreaks(root) + root.withdraw() + flist = FileList(root) + if sys.argv[1:]: + for filename in sys.argv[1:]: + flist.open(filename) + else: + flist.new() + if flist.inversedict: + root.mainloop() + +if __name__ == '__main__': + _test() diff --git a/PythonHome/Lib/idlelib/FileList.pyc b/PythonHome/Lib/idlelib/FileList.pyc deleted file mode 100644 index 760958ffce258445b54aebd4170af16c91f0406e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3783 zcma)9U2i1C6}{E-VbAP%*Si>4B2ZdL3$sM)2tfi$%qp-;5(yaCo|U{rqdRJV_doY)R6T??o;}zC1#|#m-SvY)g{1j6EqH zi*0h+WU6r3--hz^fA|~p4aAboTO~*TnojJesVi3oc^Lc%Uzeh>P;8cFc`|JXHZ+M> z@0fIH(Dz1;+Cmv-L56*hVHMx@?0duO2`n*Qt*}n!Xq+Nor8W8OG-9Ho|h^lXz0#F&TZ(_`>s=1M@*Pw+WpqtOJ;e<=!{-3fkAk)`V@TyY zT!TK=TsCCLT{Nl#*M$cRfd6q(|qI<;66PoDG=Xk{KxTnHn^Y#`a7xV~E0*<`V?w>){OJd7rj zFh+A6#p8X9>KPUD5@6Re+f@>1IE{P2d5dOobD0MNTJYpBds&*O7vruJZ;1i382Q`Z z0kh!~fUCH#Z!6F~K(SeY^Mguqkq#+$A%rU+G7STF5ADM|d$aV%Sw8p6Gtk9V()aV@ z5tw7&_xtM6-6~!h%x$dw#4eOG^hmFd{P_h=B^|4-NwH&h1T{))qc(J;9wSs08{dsBZ&nU`(7@2A~eFa{D^Go`(0` zUxXKnG;q}^cVnLB;z$G9qRfCJ5sb9zJ78AW+fsg3dcf%(b!4P0Pr^{1$68|e-&z|% z^<2}^n(&{c_9l{#>%>ZXOAb&cQ5^vHL|I2mPPKMNOAgZyJ5(2x9@L5}(`foVv$(#T zhxLc&_e>KEPh{N%unhW7Dwl?u=z-fuAU6a^p+tSx?O@3Ol4%tb2WSMfW{un)uuJr^>Yy5d8u((|i$ z93(`X-pksJU9Z#bz1VB@8lA09uj9vO7MWZ;4HV$>i9)fkxzxWGlVA-^rYm1n=d(tr5%3(7~}I1m>ko_IkC1}*(CGEep$4-8JsxYa z=4pAB6wzFxq^Ln5ep=-~!@nvx(-vZ;fQqS=^Kfj(DU54V~ zN(5RQioBme*a diff --git a/PythonHome/Lib/idlelib/FormatParagraph.py b/PythonHome/Lib/idlelib/FormatParagraph.py new file mode 100644 index 0000000000..9b10c0a760 --- /dev/null +++ b/PythonHome/Lib/idlelib/FormatParagraph.py @@ -0,0 +1,193 @@ +"""Extension to format a paragraph or selection to a max width. + +Does basic, standard text formatting, and also understands Python +comment blocks. Thus, for editing Python source code, this +extension is really only suitable for reformatting these comment +blocks or triple-quoted strings. + +Known problems with comment reformatting: +* If there is a selection marked, and the first line of the + selection is not complete, the block will probably not be detected + as comments, and will have the normal "text formatting" rules + applied. +* If a comment block has leading whitespace that mixes tabs and + spaces, they will not be considered part of the same block. +* Fancy comments, like this bulleted list, aren't handled :-) +""" + +import re +from idlelib.configHandler import idleConf + +class FormatParagraph: + + menudefs = [ + ('format', [ # /s/edit/format dscherer@cmu.edu + ('Format Paragraph', '<>'), + ]) + ] + + def __init__(self, editwin): + self.editwin = editwin + + def close(self): + self.editwin = None + + def format_paragraph_event(self, event, limit=None): + """Formats paragraph to a max width specified in idleConf. + + If text is selected, format_paragraph_event will start breaking lines + at the max width, starting from the beginning selection. + + If no text is selected, format_paragraph_event uses the current + cursor location to determine the paragraph (lines of text surrounded + by blank lines) and formats it. + + The length limit parameter is for testing with a known value. + """ + if limit == None: + limit = idleConf.GetOption( + 'main', 'FormatParagraph', 'paragraph', type='int') + text = self.editwin.text + first, last = self.editwin.get_selection_indices() + if first and last: + data = text.get(first, last) + comment_header = get_comment_header(data) + else: + first, last, comment_header, data = \ + find_paragraph(text, text.index("insert")) + if comment_header: + newdata = reformat_comment(data, limit, comment_header) + else: + newdata = reformat_paragraph(data, limit) + text.tag_remove("sel", "1.0", "end") + + if newdata != data: + text.mark_set("insert", first) + text.undo_block_start() + text.delete(first, last) + text.insert(first, newdata) + text.undo_block_stop() + else: + text.mark_set("insert", last) + text.see("insert") + return "break" + +def find_paragraph(text, mark): + """Returns the start/stop indices enclosing the paragraph that mark is in. + + Also returns the comment format string, if any, and paragraph of text + between the start/stop indices. + """ + lineno, col = map(int, mark.split(".")) + line = text.get("%d.0" % lineno, "%d.end" % lineno) + + # Look for start of next paragraph if the index passed in is a blank line + while text.compare("%d.0" % lineno, "<", "end") and is_all_white(line): + lineno = lineno + 1 + line = text.get("%d.0" % lineno, "%d.end" % lineno) + first_lineno = lineno + comment_header = get_comment_header(line) + comment_header_len = len(comment_header) + + # Once start line found, search for end of paragraph (a blank line) + while get_comment_header(line)==comment_header and \ + not is_all_white(line[comment_header_len:]): + lineno = lineno + 1 + line = text.get("%d.0" % lineno, "%d.end" % lineno) + last = "%d.0" % lineno + + # Search back to beginning of paragraph (first blank line before) + lineno = first_lineno - 1 + line = text.get("%d.0" % lineno, "%d.end" % lineno) + while lineno > 0 and \ + get_comment_header(line)==comment_header and \ + not is_all_white(line[comment_header_len:]): + lineno = lineno - 1 + line = text.get("%d.0" % lineno, "%d.end" % lineno) + first = "%d.0" % (lineno+1) + + return first, last, comment_header, text.get(first, last) + +# This should perhaps be replaced with textwrap.wrap +def reformat_paragraph(data, limit): + """Return data reformatted to specified width (limit).""" + lines = data.split("\n") + i = 0 + n = len(lines) + while i < n and is_all_white(lines[i]): + i = i+1 + if i >= n: + return data + indent1 = get_indent(lines[i]) + if i+1 < n and not is_all_white(lines[i+1]): + indent2 = get_indent(lines[i+1]) + else: + indent2 = indent1 + new = lines[:i] + partial = indent1 + while i < n and not is_all_white(lines[i]): + # XXX Should take double space after period (etc.) into account + words = re.split("(\s+)", lines[i]) + for j in range(0, len(words), 2): + word = words[j] + if not word: + continue # Can happen when line ends in whitespace + if len((partial + word).expandtabs()) > limit and \ + partial != indent1: + new.append(partial.rstrip()) + partial = indent2 + partial = partial + word + " " + if j+1 < len(words) and words[j+1] != " ": + partial = partial + " " + i = i+1 + new.append(partial.rstrip()) + # XXX Should reformat remaining paragraphs as well + new.extend(lines[i:]) + return "\n".join(new) + +def reformat_comment(data, limit, comment_header): + """Return data reformatted to specified width with comment header.""" + + # Remove header from the comment lines + lc = len(comment_header) + data = "\n".join(line[lc:] for line in data.split("\n")) + # Reformat to maxformatwidth chars or a 20 char width, + # whichever is greater. + format_width = max(limit - len(comment_header), 20) + newdata = reformat_paragraph(data, format_width) + # re-split and re-insert the comment header. + newdata = newdata.split("\n") + # If the block ends in a \n, we dont want the comment prefix + # inserted after it. (Im not sure it makes sense to reformat a + # comment block that is not made of complete lines, but whatever!) + # Can't think of a clean solution, so we hack away + block_suffix = "" + if not newdata[-1]: + block_suffix = "\n" + newdata = newdata[:-1] + return '\n'.join(comment_header+line for line in newdata) + block_suffix + +def is_all_white(line): + """Return True if line is empty or all whitespace.""" + + return re.match(r"^\s*$", line) is not None + +def get_indent(line): + """Return the initial space or tab indent of line.""" + return re.match(r"^([ \t]*)", line).group() + +def get_comment_header(line): + """Return string with leading whitespace and '#' from line or ''. + + A null return indicates that the line is not a comment line. A non- + null return, such as ' #', will be used to find the other lines of + a comment block with the same indent. + """ + m = re.match(r"^([ \t]*#*)", line) + if m is None: return "" + return m.group(1) + +if __name__ == "__main__": + import unittest + unittest.main('idlelib.idle_test.test_formatparagraph', + verbosity=2, exit=False) diff --git a/PythonHome/Lib/idlelib/FormatParagraph.pyc b/PythonHome/Lib/idlelib/FormatParagraph.pyc deleted file mode 100644 index 2680d6c3f358c8bd8c2b480b730ec88a46da446b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6912 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 GrepDialop -> OutputWindow -> EditorWindow + +def grep(text, io=None, flist=None): + root = text._root() + engine = SearchEngine.get(root) + if not hasattr(engine, "_grepdialog"): + engine._grepdialog = GrepDialog(root, engine, flist) + dialog = engine._grepdialog + searchphrase = text.get("sel.first", "sel.last") + dialog.open(text, searchphrase, io) + +class GrepDialog(SearchDialogBase): + + title = "Find in Files Dialog" + icon = "Grep" + needwrapbutton = 0 + + def __init__(self, root, engine, flist): + SearchDialogBase.__init__(self, root, engine) + self.flist = flist + self.globvar = StringVar(root) + self.recvar = BooleanVar(root) + + def open(self, text, searchphrase, io=None): + SearchDialogBase.open(self, text, searchphrase) + if io: + path = io.filename or "" + else: + path = "" + dir, base = os.path.split(path) + head, tail = os.path.splitext(base) + if not tail: + tail = ".py" + self.globvar.set(os.path.join(dir, "*" + tail)) + + def create_entries(self): + SearchDialogBase.create_entries(self) + self.globent = self.make_entry("In files:", self.globvar) + + def create_other_buttons(self): + f = self.make_frame() + + btn = Checkbutton(f, anchor="w", + variable=self.recvar, + text="Recurse down subdirectories") + btn.pack(side="top", fill="both") + btn.select() + + def create_command_buttons(self): + SearchDialogBase.create_command_buttons(self) + self.make_button("Search Files", self.default_command, 1) + + def default_command(self, event=None): + prog = self.engine.getprog() + if not prog: + return + path = self.globvar.get() + if not path: + self.top.bell() + return + from idlelib.OutputWindow import OutputWindow # leave here! + save = sys.stdout + try: + sys.stdout = OutputWindow(self.flist) + self.grep_it(prog, path) + finally: + sys.stdout = save + + def grep_it(self, prog, path): + dir, base = os.path.split(path) + list = self.findfiles(dir, base, self.recvar.get()) + list.sort() + self.close() + pat = self.engine.getpat() + print("Searching %r in %s ..." % (pat, path)) + hits = 0 + try: + for fn in list: + try: + with open(fn) as f: + for lineno, line in enumerate(f, 1): + if line[-1:] == '\n': + line = line[:-1] + if prog.search(line): + sys.stdout.write("%s: %s: %s\n" % + (fn, lineno, line)) + hits += 1 + except IOError as msg: + print(msg) + print(("Hits found: %s\n" + "(Hint: right-click to open locations.)" + % hits) if hits else "No hits.") + except AttributeError: + # Tk window has been closed, OutputWindow.text = None, + # so in OW.write, OW.text.insert fails. + pass + + def findfiles(self, dir, base, rec): + try: + names = os.listdir(dir or os.curdir) + except os.error as msg: + print(msg) + return [] + list = [] + subdirs = [] + for name in names: + fn = os.path.join(dir, name) + if os.path.isdir(fn): + subdirs.append(fn) + else: + if fnmatch.fnmatch(name, base): + list.append(fn) + if rec: + for subdir in subdirs: + list.extend(self.findfiles(subdir, base, rec)) + return list + + def close(self, event=None): + if self.top: + self.top.grab_release() + self.top.withdraw() + + +def _grep_dialog(parent): # for htest + from idlelib.PyShell import PyShellFileList + root = Tk() + root.title("Test GrepDialog") + width, height, x, y = list(map(int, re.split('[x+]', parent.geometry()))) + root.geometry("+%d+%d"%(x, y + 150)) + + flist = PyShellFileList(root) + text = Text(root, height=5) + text.pack() + + def show_grep_dialog(): + text.tag_add(SEL, "1.0", END) + grep(text, flist=flist) + text.tag_remove(SEL, "1.0", END) + + button = Button(root, text="Show GrepDialog", command=show_grep_dialog) + button.pack() + root.mainloop() + +if __name__ == "__main__": + import unittest + unittest.main('idlelib.idle_test.test_grep', verbosity=2, exit=False) + + from idlelib.idle_test.htest import run + run(_grep_dialog) diff --git a/PythonHome/Lib/idlelib/GrepDialog.pyc b/PythonHome/Lib/idlelib/GrepDialog.pyc deleted file mode 100644 index a4e27a52608c78258576243d920c012ae1eb82aa..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6126 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 and self.bracketing[i][1] > + self.bracketing[i-1][1] + for i in range(len(self.bracketing))] + + self.set_index(index) + + def set_index(self, index): + """Set the index to which the functions relate. + + The index must be in the same statement. + """ + indexinrawtext = (len(self.rawtext) - + len(self.text.get(index, self.stopatindex))) + if indexinrawtext < 0: + raise ValueError("Index %s precedes the analyzed statement" + % index) + self.indexinrawtext = indexinrawtext + # find the rightmost bracket to which index belongs + self.indexbracket = 0 + while (self.indexbracket < len(self.bracketing)-1 and + self.bracketing[self.indexbracket+1][0] < self.indexinrawtext): + self.indexbracket += 1 + if (self.indexbracket < len(self.bracketing)-1 and + self.bracketing[self.indexbracket+1][0] == self.indexinrawtext and + not self.isopener[self.indexbracket+1]): + self.indexbracket += 1 + + def is_in_string(self): + """Is the index given to the HyperParser in a string?""" + # The bracket to which we belong should be an opener. + # If it's an opener, it has to have a character. + return (self.isopener[self.indexbracket] and + self.rawtext[self.bracketing[self.indexbracket][0]] + in ('"', "'")) + + def is_in_code(self): + """Is the index given to the HyperParser in normal code?""" + return (not self.isopener[self.indexbracket] or + self.rawtext[self.bracketing[self.indexbracket][0]] + not in ('#', '"', "'")) + + def get_surrounding_brackets(self, openers='([{', mustclose=False): + """Return bracket indexes or None. + + If the index given to the HyperParser is surrounded by a + bracket defined in openers (or at least has one before it), + return the indices of the opening bracket and the closing + bracket (or the end of line, whichever comes first). + + If it is not surrounded by brackets, or the end of line comes + before the closing bracket and mustclose is True, returns None. + """ + + bracketinglevel = self.bracketing[self.indexbracket][1] + before = self.indexbracket + while (not self.isopener[before] or + self.rawtext[self.bracketing[before][0]] not in openers or + self.bracketing[before][1] > bracketinglevel): + before -= 1 + if before < 0: + return None + bracketinglevel = min(bracketinglevel, self.bracketing[before][1]) + after = self.indexbracket + 1 + while (after < len(self.bracketing) and + self.bracketing[after][1] >= bracketinglevel): + after += 1 + + beforeindex = self.text.index("%s-%dc" % + (self.stopatindex, len(self.rawtext)-self.bracketing[before][0])) + if (after >= len(self.bracketing) or + self.bracketing[after][0] > len(self.rawtext)): + if mustclose: + return None + afterindex = self.stopatindex + else: + # We are after a real char, so it is a ')' and we give the + # index before it. + afterindex = self.text.index( + "%s-%dc" % (self.stopatindex, + len(self.rawtext)-(self.bracketing[after][0]-1))) + + return beforeindex, afterindex + + # Ascii chars that may be in a white space + _whitespace_chars = " \t\n\\" + # Ascii chars that may be in an identifier + _id_chars = string.ascii_letters + string.digits + "_" + # Ascii chars that may be the first char of an identifier + _id_first_chars = string.ascii_letters + "_" + + # Given a string and pos, return the number of chars in the + # identifier which ends at pos, or 0 if there is no such one. Saved + # words are not identifiers. + def _eat_identifier(self, str, limit, pos): + i = pos + while i > limit and str[i-1] in self._id_chars: + i -= 1 + if (i < pos and (str[i] not in self._id_first_chars or + keyword.iskeyword(str[i:pos]))): + i = pos + return pos - i + + def get_expression(self): + """Return a string with the Python expression which ends at the + given index, which is empty if there is no real one. + """ + if not self.is_in_code(): + raise ValueError("get_expression should only be called" + "if index is inside a code.") + + rawtext = self.rawtext + bracketing = self.bracketing + + brck_index = self.indexbracket + brck_limit = bracketing[brck_index][0] + pos = self.indexinrawtext + + last_identifier_pos = pos + postdot_phase = True + + while 1: + # Eat whitespaces, comments, and if postdot_phase is False - a dot + while 1: + if pos>brck_limit and rawtext[pos-1] in self._whitespace_chars: + # Eat a whitespace + pos -= 1 + elif (not postdot_phase and + pos > brck_limit and rawtext[pos-1] == '.'): + # Eat a dot + pos -= 1 + postdot_phase = True + # The next line will fail if we are *inside* a comment, + # but we shouldn't be. + elif (pos == brck_limit and brck_index > 0 and + rawtext[bracketing[brck_index-1][0]] == '#'): + # Eat a comment + brck_index -= 2 + brck_limit = bracketing[brck_index][0] + pos = bracketing[brck_index+1][0] + else: + # If we didn't eat anything, quit. + break + + if not postdot_phase: + # We didn't find a dot, so the expression end at the + # last identifier pos. + break + + ret = self._eat_identifier(rawtext, brck_limit, pos) + if ret: + # There is an identifier to eat + pos = pos - ret + last_identifier_pos = pos + # Now, to continue the search, we must find a dot. + postdot_phase = False + # (the loop continues now) + + elif pos == brck_limit: + # We are at a bracketing limit. If it is a closing + # bracket, eat the bracket, otherwise, stop the search. + level = bracketing[brck_index][1] + while brck_index > 0 and bracketing[brck_index-1][1] > level: + brck_index -= 1 + if bracketing[brck_index][0] == brck_limit: + # We were not at the end of a closing bracket + break + pos = bracketing[brck_index][0] + brck_index -= 1 + brck_limit = bracketing[brck_index][0] + last_identifier_pos = pos + if rawtext[pos] in "([": + # [] and () may be used after an identifier, so we + # continue. postdot_phase is True, so we don't allow a dot. + pass + else: + # We can't continue after other types of brackets + if rawtext[pos] in "'\"": + # Scan a string prefix + while pos > 0 and rawtext[pos - 1] in "rRbBuU": + pos -= 1 + last_identifier_pos = pos + break + + else: + # We've found an operator or something. + break + + return rawtext[last_identifier_pos:self.indexinrawtext] + + +if __name__ == '__main__': + import unittest + unittest.main('idlelib.idle_test.test_hyperparser', verbosity=2) diff --git a/PythonHome/Lib/idlelib/HyperParser.pyc b/PythonHome/Lib/idlelib/HyperParser.pyc deleted file mode 100644 index ba42c645b7def38c5edef388b3029a818759d92e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6520 zcmb_gTW=&s6|U;J&yKy`i*Ly$=_Fd>&2A>yNGMAZ0^|lkusH372xmjno^IQ1x4Xw( zHM@3VODLNco_I&_hduPYtbRoqo^ zLw%&wJ*B?C-cU(X#Z9&Asj?U^ZK?H^N?K~Ct>Tu7QFhclt#uAYo?2TuL*{=)v04^) z(m3&>_)e4$lGqyN&0t_;ux$0vwfg>~>hBfCW{3V(dIuBI9F+GW3j#j=L9#n63sAvGoaD9| z+4KiRoPf$S2S*`_V~AMfQT70_E{OTYmZO0km5EBA|i!jRK zdavq}#tf}QITgrCS5r$i8 z2^%G)wz6Gy)aE+uc=5Qy{bI_(F}mw&=ZsMAsUs}xas`}q5tB6sXN34H2P@W?eugf+ z+fnAvqzg9mFgZu><}M%>81__oS)&AnWr&sIT(s5c z+juA$Ji>2ii25K#UHgB zM$a;(o3zkak{-bICAy6zFn(Ou)`ts3UIPRzLMijFb9SE~B8I~fTNo)w% zk-@FR+IcM91jlfzDB^HPbi{a6TKf=2!i`ay#o=H(D#JAALf9?b9OVO{db7wAk)Bku z!p>lcjkdyJncOL(9Q3INvLlq0(OpU{do;Ef0zGLTIHppV8fKB9Yf%O zU$^myZtC-TNw@WacOLZ_uc^EBNAyf>uHMmSYc=ndH=wgp<=oM0_{<^%!{Om!78tGS zWBg@*o!EqPwRG(9Gy{Wov6pWu94H)pfbIeYKh!D*8MGlVK+7R}OC78VZD6otGRE8` z()f*xwW}FK;$u zL0q)Q(2m)A@X!8afuMw;XS_wf_b(eC2L%}oG7a*oU@|^gE2wi*B5d#o)&)E&;=Tco zymLWf*7u@pl)M3CEiK(h#7gt=furk6S9OpA;!*G@iWNFb;IkmO1Xod;PkM7COu_%(dGb zTkLr(e9LLfso#YUn2k!D0(9CVf-;F&UvUu4WBP;~)2AeO1ka!&=%ZMX{Zl8wH5Q_2 z>Pe!BsOS`m5wu9n31%XFRuVTmLlEX5lbv3o`JJ^zY(IWEKgBO{?A~d?$08oDa`-isW!&X`b*Fg?W|+gaN51fQ86Kfth|%-aH(*d!TZb|sL|;cmAy5WRet zH?}p>?J%3pUlJbfX7(8pR5T&@(nJcRx{`=PstR8}hSh=ucbwd>&*yjmA8y7qP zx4m+0LZfuj5=`VGRLj<3cY5~RwiktGnZug(WXVdcZL&Xr{Xh`Ey{>APXpNFBy{S2GEPIyHn-i-^sDP0GO~`o;u!*`-|60#kP{BrWY#f3 z{U4zL6d-tAC*I&V@?3t2X_o_{B}tbQ;~%>x;I!Y7TPGm|$Z}9EkjW0%DaE)Wem54rW z_-PH<7@5Eobu1TYg|UPHJoQ=0{98sHHmNBT%Xn$wUeGU{ zlz0Ef`kgTeNLcOsPfoNc<48yrRefTQBAZk0GTvZ#fX;jSkvHyYOV@4h0C^|$@AMf| z!%jBHg;nS~G2vzJ9k*-fXcc?rM~W`gH`L?qLCkyzN37yrROO)l-PF2U#pDtHjGlf9um^izpT3}B2FKyajX5>dzKZC-&GyjxGP zGTX%{LqN*$%!y0OAj&d4OKiHZOiC$UO!?j_Sz=$XU(i87tRD~vQ(iRX@nhv(`FZLI z0q8Q=cy;t$cVW3s4Lr?al1sbP`YQV5TF$s5ZxfvSn_kVU=_kDz-O|3-)t%aszJ%XdJzuMPO?>m1)5X`R z^=h;FDU4k7>L@vK$FL*S(cFaFJJ#FwAlD3`0>x815DEC_^*2f(dd{ z3wY-W#4cZFjgJk%n<&I~?xG~RiOe8P!wmXJkeo2?$LUsTP4F^Te3=Ce6x>8{qA01E zOX&NoH@1LxFnLU2s(@X-(3$VFJI%9Ko8ColrqStCo7s!-;uM-EFspj4>+?5+qu4%+ zaGMYM?hQx65R$45WMcME+|vox!E%XLVHg(!Xya{k1UwefTTzyGIFT&)4u{$(MtGGW g8*x<%bK0E>m6x3vUZD~tXf=^3^zgoO;qUzY50w3B", self.return_event) + top.bind("", self.do_ok) + top.protocol("WM_DELETE_WINDOW", self.wm_delete_window) + top.wm_title("I/O Warning") + top.wm_iconname("I/O Warning") + self.top = top + + l1 = Label(top, + text="Non-ASCII found, yet no encoding declared. Add a line like") + l1.pack(side=TOP, anchor=W) + l2 = Entry(top, font="courier") + l2.insert(0, "# -*- coding: %s -*-" % enc) + # For some reason, the text is not selectable anymore if the + # widget is disabled. + # l2['state'] = DISABLED + l2.pack(side=TOP, anchor = W, fill=X) + l3 = Label(top, text="to your file\n" + "Choose OK to save this file as %s\n" + "Edit your general options to silence this warning" % enc) + l3.pack(side=TOP, anchor = W) + + buttons = Frame(top) + buttons.pack(side=TOP, fill=X) + # Both return and cancel mean the same thing: do nothing + self.default = self.cancel = 0 + b1 = Button(buttons, text="Ok", default="active", + command=self.do_ok) + b1.pack(side=LEFT, fill=BOTH, expand=1) + b2 = Button(buttons, text="Edit my file", + command=self.do_edit) + b2.pack(side=LEFT, fill=BOTH, expand=1) + + self._set_transient(master) + + def do_ok(self): + self.done(0) + + def do_edit(self): + self.done(1) + +def coding_spec(str): + """Return the encoding declaration according to PEP 263. + + Raise LookupError if the encoding is declared but unknown. + """ + # Only consider the first two lines + lst = str.split("\n", 2)[:2] + for line in lst: + match = coding_re.match(line) + if match is not None: + break + else: + return None + name = match.group(1) + # Check whether the encoding is known + import codecs + try: + codecs.lookup(name) + except LookupError: + # The standard encoding error does not indicate the encoding + raise LookupError, "Unknown encoding "+name + return name + + +class IOBinding: + + def __init__(self, editwin): + self.editwin = editwin + self.text = editwin.text + self.__id_open = self.text.bind("<>", self.open) + self.__id_save = self.text.bind("<>", self.save) + self.__id_saveas = self.text.bind("<>", + self.save_as) + self.__id_savecopy = self.text.bind("<>", + self.save_a_copy) + self.fileencoding = None + self.__id_print = self.text.bind("<>", self.print_window) + + def close(self): + # Undo command bindings + self.text.unbind("<>", self.__id_open) + self.text.unbind("<>", self.__id_save) + self.text.unbind("<>",self.__id_saveas) + self.text.unbind("<>", self.__id_savecopy) + self.text.unbind("<>", self.__id_print) + # Break cycles + self.editwin = None + self.text = None + self.filename_change_hook = None + + def get_saved(self): + return self.editwin.get_saved() + + def set_saved(self, flag): + self.editwin.set_saved(flag) + + def reset_undo(self): + self.editwin.reset_undo() + + filename_change_hook = None + + def set_filename_change_hook(self, hook): + self.filename_change_hook = hook + + filename = None + dirname = None + + def set_filename(self, filename): + if filename and os.path.isdir(filename): + self.filename = None + self.dirname = filename + else: + self.filename = filename + self.dirname = None + self.set_saved(1) + if self.filename_change_hook: + self.filename_change_hook() + + def open(self, event=None, editFile=None): + flist = self.editwin.flist + # Save in case parent window is closed (ie, during askopenfile()). + if flist: + if not editFile: + filename = self.askopenfile() + else: + filename=editFile + if filename: + # If editFile is valid and already open, flist.open will + # shift focus to its existing window. + # If the current window exists and is a fresh unnamed, + # unmodified editor window (not an interpreter shell), + # pass self.loadfile to flist.open so it will load the file + # in the current window (if the file is not already open) + # instead of a new window. + if (self.editwin and + not getattr(self.editwin, 'interp', None) and + not self.filename and + self.get_saved()): + flist.open(filename, self.loadfile) + else: + flist.open(filename) + else: + if self.text: + self.text.focus_set() + return "break" + + # Code for use outside IDLE: + if self.get_saved(): + reply = self.maybesave() + if reply == "cancel": + self.text.focus_set() + return "break" + if not editFile: + filename = self.askopenfile() + else: + filename=editFile + if filename: + self.loadfile(filename) + else: + self.text.focus_set() + return "break" + + eol = r"(\r\n)|\n|\r" # \r\n (Windows), \n (UNIX), or \r (Mac) + eol_re = re.compile(eol) + eol_convention = os.linesep # Default + + def loadfile(self, filename): + try: + # open the file in binary mode so that we can handle + # end-of-line convention ourselves. + with open(filename, 'rb') as f: + chars = f.read() + except IOError as msg: + tkMessageBox.showerror("I/O Error", str(msg), master=self.text) + return False + + chars = self.decode(chars) + # We now convert all end-of-lines to '\n's + firsteol = self.eol_re.search(chars) + if firsteol: + self.eol_convention = firsteol.group(0) + if isinstance(self.eol_convention, unicode): + # Make sure it is an ASCII string + self.eol_convention = self.eol_convention.encode("ascii") + chars = self.eol_re.sub(r"\n", chars) + + self.text.delete("1.0", "end") + self.set_filename(None) + self.text.insert("1.0", chars) + self.reset_undo() + self.set_filename(filename) + self.text.mark_set("insert", "1.0") + self.text.yview("insert") + self.updaterecentfileslist(filename) + return True + + def decode(self, chars): + """Create a Unicode string + + If that fails, let Tcl try its best + """ + # Check presence of a UTF-8 signature first + if chars.startswith(BOM_UTF8): + try: + chars = chars[3:].decode("utf-8") + except UnicodeError: + # has UTF-8 signature, but fails to decode... + return chars + else: + # Indicates that this file originally had a BOM + self.fileencoding = BOM_UTF8 + return chars + # Next look for coding specification + try: + enc = coding_spec(chars) + except LookupError as name: + tkMessageBox.showerror( + title="Error loading the file", + message="The encoding '%s' is not known to this Python "\ + "installation. The file may not display correctly" % name, + master = self.text) + enc = None + if enc: + try: + return unicode(chars, enc) + except UnicodeError: + pass + # If it is ASCII, we need not to record anything + try: + return unicode(chars, 'ascii') + except UnicodeError: + pass + # Finally, try the locale's encoding. This is deprecated; + # the user should declare a non-ASCII encoding + try: + chars = unicode(chars, encoding) + self.fileencoding = encoding + except UnicodeError: + pass + return chars + + def maybesave(self): + if self.get_saved(): + return "yes" + message = "Do you want to save %s before closing?" % ( + self.filename or "this untitled document") + confirm = tkMessageBox.askyesnocancel( + title="Save On Close", + message=message, + default=tkMessageBox.YES, + master=self.text) + if confirm: + reply = "yes" + self.save(None) + if not self.get_saved(): + reply = "cancel" + elif confirm is None: + reply = "cancel" + else: + reply = "no" + self.text.focus_set() + return reply + + def save(self, event): + if not self.filename: + self.save_as(event) + else: + if self.writefile(self.filename): + self.set_saved(True) + try: + self.editwin.store_file_breaks() + except AttributeError: # may be a PyShell + pass + self.text.focus_set() + return "break" + + def save_as(self, event): + filename = self.asksavefile() + if filename: + if self.writefile(filename): + self.set_filename(filename) + self.set_saved(1) + try: + self.editwin.store_file_breaks() + except AttributeError: + pass + self.text.focus_set() + self.updaterecentfileslist(filename) + return "break" + + def save_a_copy(self, event): + filename = self.asksavefile() + if filename: + self.writefile(filename) + self.text.focus_set() + self.updaterecentfileslist(filename) + return "break" + + def writefile(self, filename): + self.fixlastline() + chars = self.encode(self.text.get("1.0", "end-1c")) + if self.eol_convention != "\n": + chars = chars.replace("\n", self.eol_convention) + try: + with open(filename, "wb") as f: + f.write(chars) + return True + except IOError as msg: + tkMessageBox.showerror("I/O Error", str(msg), + master=self.text) + return False + + def encode(self, chars): + if isinstance(chars, types.StringType): + # This is either plain ASCII, or Tk was returning mixed-encoding + # text to us. Don't try to guess further. + return chars + # See whether there is anything non-ASCII in it. + # If not, no need to figure out the encoding. + try: + return chars.encode('ascii') + except UnicodeError: + pass + # If there is an encoding declared, try this first. + try: + enc = coding_spec(chars) + failed = None + except LookupError as msg: + failed = msg + enc = None + if enc: + try: + return chars.encode(enc) + except UnicodeError: + failed = "Invalid encoding '%s'" % enc + if failed: + tkMessageBox.showerror( + "I/O Error", + "%s. Saving as UTF-8" % failed, + master = self.text) + # If there was a UTF-8 signature, use that. This should not fail + if self.fileencoding == BOM_UTF8 or failed: + return BOM_UTF8 + chars.encode("utf-8") + # Try the original file encoding next, if any + if self.fileencoding: + try: + return chars.encode(self.fileencoding) + except UnicodeError: + tkMessageBox.showerror( + "I/O Error", + "Cannot save this as '%s' anymore. Saving as UTF-8" \ + % self.fileencoding, + master = self.text) + return BOM_UTF8 + chars.encode("utf-8") + # Nothing was declared, and we had not determined an encoding + # on loading. Recommend an encoding line. + config_encoding = idleConf.GetOption("main","EditorWindow", + "encoding") + if config_encoding == 'utf-8': + # User has requested that we save files as UTF-8 + return BOM_UTF8 + chars.encode("utf-8") + ask_user = True + try: + chars = chars.encode(encoding) + enc = encoding + if config_encoding == 'locale': + ask_user = False + except UnicodeError: + chars = BOM_UTF8 + chars.encode("utf-8") + enc = "utf-8" + if not ask_user: + return chars + dialog = EncodingMessage(self.editwin.top, enc) + dialog.go() + if dialog.num == 1: + # User asked us to edit the file + encline = "# -*- coding: %s -*-\n" % enc + firstline = self.text.get("1.0", "2.0") + if firstline.startswith("#!"): + # Insert encoding after #! line + self.text.insert("2.0", encline) + else: + self.text.insert("1.0", encline) + return self.encode(self.text.get("1.0", "end-1c")) + return chars + + def fixlastline(self): + c = self.text.get("end-2c") + if c != '\n': + self.text.insert("end-1c", "\n") + + def print_window(self, event): + confirm = tkMessageBox.askokcancel( + title="Print", + message="Print to Default Printer", + default=tkMessageBox.OK, + master=self.text) + if not confirm: + self.text.focus_set() + return "break" + tempfilename = None + saved = self.get_saved() + if saved: + filename = self.filename + # shell undo is reset after every prompt, looks saved, probably isn't + if not saved or filename is None: + (tfd, tempfilename) = tempfile.mkstemp(prefix='IDLE_tmp_') + filename = tempfilename + os.close(tfd) + if not self.writefile(tempfilename): + os.unlink(tempfilename) + return "break" + platform = os.name + printPlatform = True + if platform == 'posix': #posix platform + command = idleConf.GetOption('main','General', + 'print-command-posix') + command = command + " 2>&1" + elif platform == 'nt': #win32 platform + command = idleConf.GetOption('main','General','print-command-win') + else: #no printing for this platform + printPlatform = False + if printPlatform: #we can try to print for this platform + command = command % pipes.quote(filename) + pipe = os.popen(command, "r") + # things can get ugly on NT if there is no printer available. + output = pipe.read().strip() + status = pipe.close() + if status: + output = "Printing failed (exit status 0x%x)\n" % \ + status + output + if output: + output = "Printing command: %s\n" % repr(command) + output + tkMessageBox.showerror("Print status", output, master=self.text) + else: #no printing for this platform + message = "Printing is not enabled for this platform: %s" % platform + tkMessageBox.showinfo("Print status", message, master=self.text) + if tempfilename: + os.unlink(tempfilename) + return "break" + + opendialog = None + savedialog = None + + filetypes = [ + ("Python files", "*.py *.pyw", "TEXT"), + ("Text files", "*.txt", "TEXT"), + ("All files", "*"), + ] + + def askopenfile(self): + dir, base = self.defaultfilename("open") + if not self.opendialog: + self.opendialog = tkFileDialog.Open(master=self.text, + filetypes=self.filetypes) + filename = self.opendialog.show(initialdir=dir, initialfile=base) + if isinstance(filename, unicode): + filename = filename.encode(filesystemencoding) + return filename + + def defaultfilename(self, mode="open"): + if self.filename: + return os.path.split(self.filename) + elif self.dirname: + return self.dirname, "" + else: + try: + pwd = os.getcwd() + except os.error: + pwd = "" + return pwd, "" + + def asksavefile(self): + dir, base = self.defaultfilename("save") + if not self.savedialog: + self.savedialog = tkFileDialog.SaveAs(master=self.text, + filetypes=self.filetypes) + filename = self.savedialog.show(initialdir=dir, initialfile=base) + if isinstance(filename, unicode): + filename = filename.encode(filesystemencoding) + return filename + + def updaterecentfileslist(self,filename): + "Update recent file list on all editor windows" + self.editwin.update_recent_files_list(filename) + +def _io_binding(parent): + root = Tk() + root.title("Test IOBinding") + width, height, x, y = list(map(int, re.split('[x+]', parent.geometry()))) + root.geometry("+%d+%d"%(x, y + 150)) + class MyEditWin: + def __init__(self, text): + self.text = text + self.flist = None + self.text.bind("", self.open) + self.text.bind("", self.save) + def get_saved(self): return 0 + def set_saved(self, flag): pass + def reset_undo(self): pass + def open(self, event): + self.text.event_generate("<>") + def save(self, event): + self.text.event_generate("<>") + + text = Text(root) + text.pack() + text.focus_set() + editwin = MyEditWin(text) + io = IOBinding(editwin) + +if __name__ == "__main__": + from idlelib.idle_test.htest import run + run(_io_binding) diff --git a/PythonHome/Lib/idlelib/IOBinding.pyc b/PythonHome/Lib/idlelib/IOBinding.pyc deleted file mode 100644 index d96ef6d365870f04318a85e5b2f8b1a7399081aa..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 16827 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 event (default Alt-N). + history_prev - Bound to <> event (default Alt-P). + ''' + def __init__(self, text): + '''Initialize data attributes and bind event methods. + + .text - Idle wrapper of tk Text widget, with .bell(). + .history - source statements, possibly with multiple lines. + .prefix - source already entered at prompt; filters history list. + .pointer - index into history. + .cyclic - wrap around history list (or not). + ''' + self.text = text + self.history = [] + self.prefix = None + self.pointer = None + self.cyclic = idleConf.GetOption("main", "History", "cyclic", 1, "bool") + text.bind("<>", self.history_prev) + text.bind("<>", self.history_next) + + def history_next(self, event): + "Fetch later statement; start with ealiest if cyclic." + self.fetch(reverse=False) + return "break" + + def history_prev(self, event): + "Fetch earlier statement; start with most recent." + self.fetch(reverse=True) + return "break" + + def fetch(self, reverse): + '''Fetch statememt and replace current line in text widget. + + Set prefix and pointer as needed for successive fetches. + Reset them to None, None when returning to the start line. + Sound bell when return to start line or cannot leave a line + because cyclic is False. + ''' + nhist = len(self.history) + pointer = self.pointer + prefix = self.prefix + if pointer is not None and prefix is not None: + if self.text.compare("insert", "!=", "end-1c") or \ + self.text.get("iomark", "end-1c") != self.history[pointer]: + pointer = prefix = None + self.text.mark_set("insert", "end-1c") # != after cursor move + if pointer is None or prefix is None: + prefix = self.text.get("iomark", "end-1c") + if reverse: + pointer = nhist # will be decremented + else: + if self.cyclic: + pointer = -1 # will be incremented + else: # abort history_next + self.text.bell() + return + nprefix = len(prefix) + while 1: + pointer += -1 if reverse else 1 + if pointer < 0 or pointer >= nhist: + self.text.bell() + if not self.cyclic and pointer < 0: # abort history_prev + return + else: + if self.text.get("iomark", "end-1c") != prefix: + self.text.delete("iomark", "end-1c") + self.text.insert("iomark", prefix) + pointer = prefix = None + break + item = self.history[pointer] + if item[:nprefix] == prefix and len(item) > nprefix: + self.text.delete("iomark", "end-1c") + self.text.insert("iomark", item) + break + self.text.see("insert") + self.text.tag_remove("sel", "1.0", "end") + self.pointer = pointer + self.prefix = prefix + + def store(self, source): + "Store Shell input statement into history list." + source = source.strip() + if len(source) > 2: + # avoid duplicates + try: + self.history.remove(source) + except ValueError: + pass + self.history.append(source) + self.pointer = None + self.prefix = None + +if __name__ == "__main__": + from unittest import main + main('idlelib.idle_test.test_idlehistory', verbosity=2, exit=False) diff --git a/PythonHome/Lib/idlelib/IdleHistory.pyc b/PythonHome/Lib/idlelib/IdleHistory.pyc deleted file mode 100644 index 945a55dc87f452a488a4d505a1ba70ba30e6d648..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3954 zcmb7H+io1k5v`uRaVb)kELpIV!00G1Yg=4cK!PBULO2$zNI}2|vqlmLLI$%lz2s=; zvg+=Y$bfueejqP?&KLL>@(=lj{6SvwmYk}dFFItpl=o;Jk^PI1_o?hr z)u$JIQl?M&fbuQMhm>!V8PK_kR1Ln@XfoR6vwnr%|roiq;O+E7i3|hhq?U?FwJnjJ+1MQ$1 z+K7dQHqZo`atHc!q|<8^g(lFDmj)D1Mr+_@^;PAW(Jd~ z51Nm%v@A`oXSS*IvlFqw*cxYiv-FFl|7a{+X2xen;PP1B!ZY9CQl(ff>O;M-W>y^Q zw6rG8Pc&?6tjPn9*0M=$jy+g?-Yn}}`$j)}*skpH%KpAKZ`dcJ+|1Ht>Gf|)zjx5e zvEqSq-h4X`Uio$&&srW?1WWS67JbB4Ezz7RIweYo4$(&kZrYL#927cT@;!P5r$}&e zNJU8)b*2THV2;Z8qb7H)SJ|^;9}FqM`_`t5g|WJsX+PIr^2*yHKQ#Vch~M!P!98j% zAiG;r!iwJv3U^O08btZDJPDgCxS_yZ(PdE^h`{^#H*Vd1!QvZ!hdPLerds$1dRCN( z1$S}3N?fQ-PEEnF0%@SKIYx`fXhqy0%TBVg$Uw#V>eNaMtu$eldem55H>vc3p9#+W6~A@Ez{|FG~yQ^y^i5=o%G-@&M5marU`Ciwgjhp*5(Q_kWZMk73- zaX&$C{POq3^d%!xi8qJHlYn63#fgAck`#!&BoQ>c&YOor75+X{x75WYVaeo@uz5I) z1)aSD4l4!dnv9sj{TxjIhZ4|Y*VyoYyOyI7C~6Su22LtwI=EmghJlI*4TI|iR{%NY zK|dY}@W{gBv~)%mVis5C5?jbgU&Rg~c{`5B(e%5V~5?Zj!15hyC#`;aWNKVHzqB=%BUl7ci$E;XI+aW$b#PYP+{8Nq zUWo<}BTH+f6J44Vf~2C@MgE(bEL}Qi9kNp4w1Cw55Xk^V?Tqz~A^WGlcAOJTo$uYx z!eUdUb}j|wf#jnC>*PCV0PT+7_s5^g7`sOAtQJdC$IL3`JQ8yi8uP`MR3Mm|A?>EH z1am+cAehfbC9vE^x`F;8M{Y{vO?(H`?cv66^B_G;tf`teW+eQt^C669g1tZ-FW=OH#OLS-Y1 zatwv~?+Siu<-mut(W&%5OLhpNZ7B&xqS@*f7b$oOC(T(U), for all types of events. +Key/Button Press/Release events can have modifiers. +The recognized modifiers are Shift, Control, Option and Command for Mac, and +Control, Alt, Shift, Meta/M for other platforms. + +For all events which were handled by MultiCall, a new member is added to the +event instance passed to the binded functions - mc_type. This is one of the +event type constants defined in this module (such as MC_KEYPRESS). +For Key/Button events (which are handled by MultiCall and may receive +modifiers), another member is added - mc_state. This member gives the state +of the recognized modifiers, as a combination of the modifier constants +also defined in this module (for example, MC_SHIFT). +Using these members is absolutely portable. + +The order by which events are called is defined by these rules: +1. A more-specific event will be called before a less-specific event. +2. A recently-binded event will be called before a previously-binded event, + unless this conflicts with the first rule. +Each function will be called at most once for each event. +""" + +import sys +import string +import re +import Tkinter + +# the event type constants, which define the meaning of mc_type +MC_KEYPRESS=0; MC_KEYRELEASE=1; MC_BUTTONPRESS=2; MC_BUTTONRELEASE=3; +MC_ACTIVATE=4; MC_CIRCULATE=5; MC_COLORMAP=6; MC_CONFIGURE=7; +MC_DEACTIVATE=8; MC_DESTROY=9; MC_ENTER=10; MC_EXPOSE=11; MC_FOCUSIN=12; +MC_FOCUSOUT=13; MC_GRAVITY=14; MC_LEAVE=15; MC_MAP=16; MC_MOTION=17; +MC_MOUSEWHEEL=18; MC_PROPERTY=19; MC_REPARENT=20; MC_UNMAP=21; MC_VISIBILITY=22; +# the modifier state constants, which define the meaning of mc_state +MC_SHIFT = 1<<0; MC_CONTROL = 1<<2; MC_ALT = 1<<3; MC_META = 1<<5 +MC_OPTION = 1<<6; MC_COMMAND = 1<<7 + +# define the list of modifiers, to be used in complex event types. +if sys.platform == "darwin": + _modifiers = (("Shift",), ("Control",), ("Option",), ("Command",)) + _modifier_masks = (MC_SHIFT, MC_CONTROL, MC_OPTION, MC_COMMAND) +else: + _modifiers = (("Control",), ("Alt",), ("Shift",), ("Meta", "M")) + _modifier_masks = (MC_CONTROL, MC_ALT, MC_SHIFT, MC_META) + +# a dictionary to map a modifier name into its number +_modifier_names = dict([(name, number) + for number in range(len(_modifiers)) + for name in _modifiers[number]]) + +# A binder is a class which binds functions to one type of event. It has two +# methods: bind and unbind, which get a function and a parsed sequence, as +# returned by _parse_sequence(). There are two types of binders: +# _SimpleBinder handles event types with no modifiers and no detail. +# No Python functions are called when no events are binded. +# _ComplexBinder handles event types with modifiers and a detail. +# A Python function is called each time an event is generated. + +class _SimpleBinder: + def __init__(self, type, widget, widgetinst): + self.type = type + self.sequence = '<'+_types[type][0]+'>' + self.widget = widget + self.widgetinst = widgetinst + self.bindedfuncs = [] + self.handlerid = None + + def bind(self, triplet, func): + if not self.handlerid: + def handler(event, l = self.bindedfuncs, mc_type = self.type): + event.mc_type = mc_type + wascalled = {} + for i in range(len(l)-1, -1, -1): + func = l[i] + if func not in wascalled: + wascalled[func] = True + r = func(event) + if r: + return r + self.handlerid = self.widget.bind(self.widgetinst, + self.sequence, handler) + self.bindedfuncs.append(func) + + def unbind(self, triplet, func): + self.bindedfuncs.remove(func) + if not self.bindedfuncs: + self.widget.unbind(self.widgetinst, self.sequence, self.handlerid) + self.handlerid = None + + def __del__(self): + if self.handlerid: + self.widget.unbind(self.widgetinst, self.sequence, self.handlerid) + +# An int in range(1 << len(_modifiers)) represents a combination of modifiers +# (if the least significent bit is on, _modifiers[0] is on, and so on). +# _state_subsets gives for each combination of modifiers, or *state*, +# a list of the states which are a subset of it. This list is ordered by the +# number of modifiers is the state - the most specific state comes first. +_states = range(1 << len(_modifiers)) +_state_names = [''.join(m[0]+'-' + for i, m in enumerate(_modifiers) + if (1 << i) & s) + for s in _states] + +def expand_substates(states): + '''For each item of states return a list containing all combinations of + that item with individual bits reset, sorted by the number of set bits. + ''' + def nbits(n): + "number of bits set in n base 2" + nb = 0 + while n: + n, rem = divmod(n, 2) + nb += rem + return nb + statelist = [] + for state in states: + substates = list(set(state & x for x in states)) + substates.sort(key=nbits, reverse=True) + statelist.append(substates) + return statelist + +_state_subsets = expand_substates(_states) + +# _state_codes gives for each state, the portable code to be passed as mc_state +_state_codes = [] +for s in _states: + r = 0 + for i in range(len(_modifiers)): + if (1 << i) & s: + r |= _modifier_masks[i] + _state_codes.append(r) + +class _ComplexBinder: + # This class binds many functions, and only unbinds them when it is deleted. + # self.handlerids is the list of seqs and ids of binded handler functions. + # The binded functions sit in a dictionary of lists of lists, which maps + # a detail (or None) and a state into a list of functions. + # When a new detail is discovered, handlers for all the possible states + # are binded. + + def __create_handler(self, lists, mc_type, mc_state): + def handler(event, lists = lists, + mc_type = mc_type, mc_state = mc_state, + ishandlerrunning = self.ishandlerrunning, + doafterhandler = self.doafterhandler): + ishandlerrunning[:] = [True] + event.mc_type = mc_type + event.mc_state = mc_state + wascalled = {} + r = None + for l in lists: + for i in range(len(l)-1, -1, -1): + func = l[i] + if func not in wascalled: + wascalled[func] = True + r = l[i](event) + if r: + break + if r: + break + ishandlerrunning[:] = [] + # Call all functions in doafterhandler and remove them from list + for f in doafterhandler: + f() + doafterhandler[:] = [] + if r: + return r + return handler + + def __init__(self, type, widget, widgetinst): + self.type = type + self.typename = _types[type][0] + self.widget = widget + self.widgetinst = widgetinst + self.bindedfuncs = {None: [[] for s in _states]} + self.handlerids = [] + # we don't want to change the lists of functions while a handler is + # running - it will mess up the loop and anyway, we usually want the + # change to happen from the next event. So we have a list of functions + # for the handler to run after it finishes calling the binded functions. + # It calls them only once. + # ishandlerrunning is a list. An empty one means no, otherwise - yes. + # this is done so that it would be mutable. + self.ishandlerrunning = [] + self.doafterhandler = [] + for s in _states: + lists = [self.bindedfuncs[None][i] for i in _state_subsets[s]] + handler = self.__create_handler(lists, type, _state_codes[s]) + seq = '<'+_state_names[s]+self.typename+'>' + self.handlerids.append((seq, self.widget.bind(self.widgetinst, + seq, handler))) + + def bind(self, triplet, func): + if triplet[2] not in self.bindedfuncs: + self.bindedfuncs[triplet[2]] = [[] for s in _states] + for s in _states: + lists = [ self.bindedfuncs[detail][i] + for detail in (triplet[2], None) + for i in _state_subsets[s] ] + handler = self.__create_handler(lists, self.type, + _state_codes[s]) + seq = "<%s%s-%s>"% (_state_names[s], self.typename, triplet[2]) + self.handlerids.append((seq, self.widget.bind(self.widgetinst, + seq, handler))) + doit = lambda: self.bindedfuncs[triplet[2]][triplet[0]].append(func) + if not self.ishandlerrunning: + doit() + else: + self.doafterhandler.append(doit) + + def unbind(self, triplet, func): + doit = lambda: self.bindedfuncs[triplet[2]][triplet[0]].remove(func) + if not self.ishandlerrunning: + doit() + else: + self.doafterhandler.append(doit) + + def __del__(self): + for seq, id in self.handlerids: + self.widget.unbind(self.widgetinst, seq, id) + +# define the list of event types to be handled by MultiEvent. the order is +# compatible with the definition of event type constants. +_types = ( + ("KeyPress", "Key"), ("KeyRelease",), ("ButtonPress", "Button"), + ("ButtonRelease",), ("Activate",), ("Circulate",), ("Colormap",), + ("Configure",), ("Deactivate",), ("Destroy",), ("Enter",), ("Expose",), + ("FocusIn",), ("FocusOut",), ("Gravity",), ("Leave",), ("Map",), + ("Motion",), ("MouseWheel",), ("Property",), ("Reparent",), ("Unmap",), + ("Visibility",), +) + +# which binder should be used for every event type? +_binder_classes = (_ComplexBinder,) * 4 + (_SimpleBinder,) * (len(_types)-4) + +# A dictionary to map a type name into its number +_type_names = dict([(name, number) + for number in range(len(_types)) + for name in _types[number]]) + +_keysym_re = re.compile(r"^\w+$") +_button_re = re.compile(r"^[1-5]$") +def _parse_sequence(sequence): + """Get a string which should describe an event sequence. If it is + successfully parsed as one, return a tuple containing the state (as an int), + the event type (as an index of _types), and the detail - None if none, or a + string if there is one. If the parsing is unsuccessful, return None. + """ + if not sequence or sequence[0] != '<' or sequence[-1] != '>': + return None + words = string.split(sequence[1:-1], '-') + + modifiers = 0 + while words and words[0] in _modifier_names: + modifiers |= 1 << _modifier_names[words[0]] + del words[0] + + if words and words[0] in _type_names: + type = _type_names[words[0]] + del words[0] + else: + return None + + if _binder_classes[type] is _SimpleBinder: + if modifiers or words: + return None + else: + detail = None + else: + # _ComplexBinder + if type in [_type_names[s] for s in ("KeyPress", "KeyRelease")]: + type_re = _keysym_re + else: + type_re = _button_re + + if not words: + detail = None + elif len(words) == 1 and type_re.match(words[0]): + detail = words[0] + else: + return None + + return modifiers, type, detail + +def _triplet_to_sequence(triplet): + if triplet[2]: + return '<'+_state_names[triplet[0]]+_types[triplet[1]][0]+'-'+ \ + triplet[2]+'>' + else: + return '<'+_state_names[triplet[0]]+_types[triplet[1]][0]+'>' + +_multicall_dict = {} +def MultiCallCreator(widget): + """Return a MultiCall class which inherits its methods from the + given widget class (for example, Tkinter.Text). This is used + instead of a templating mechanism. + """ + if widget in _multicall_dict: + return _multicall_dict[widget] + + class MultiCall (widget): + assert issubclass(widget, Tkinter.Misc) + + def __init__(self, *args, **kwargs): + widget.__init__(self, *args, **kwargs) + # a dictionary which maps a virtual event to a tuple with: + # 0. the function binded + # 1. a list of triplets - the sequences it is binded to + self.__eventinfo = {} + self.__binders = [_binder_classes[i](i, widget, self) + for i in range(len(_types))] + + def bind(self, sequence=None, func=None, add=None): + #print "bind(%s, %s, %s) called." % (sequence, func, add) + if type(sequence) is str and len(sequence) > 2 and \ + sequence[:2] == "<<" and sequence[-2:] == ">>": + if sequence in self.__eventinfo: + ei = self.__eventinfo[sequence] + if ei[0] is not None: + for triplet in ei[1]: + self.__binders[triplet[1]].unbind(triplet, ei[0]) + ei[0] = func + if ei[0] is not None: + for triplet in ei[1]: + self.__binders[triplet[1]].bind(triplet, func) + else: + self.__eventinfo[sequence] = [func, []] + return widget.bind(self, sequence, func, add) + + def unbind(self, sequence, funcid=None): + if type(sequence) is str and len(sequence) > 2 and \ + sequence[:2] == "<<" and sequence[-2:] == ">>" and \ + sequence in self.__eventinfo: + func, triplets = self.__eventinfo[sequence] + if func is not None: + for triplet in triplets: + self.__binders[triplet[1]].unbind(triplet, func) + self.__eventinfo[sequence][0] = None + return widget.unbind(self, sequence, funcid) + + def event_add(self, virtual, *sequences): + #print "event_add(%s,%s) was called"%(repr(virtual),repr(sequences)) + if virtual not in self.__eventinfo: + self.__eventinfo[virtual] = [None, []] + + func, triplets = self.__eventinfo[virtual] + for seq in sequences: + triplet = _parse_sequence(seq) + if triplet is None: + #print >> sys.stderr, "Seq. %s was added by Tkinter."%seq + widget.event_add(self, virtual, seq) + else: + if func is not None: + self.__binders[triplet[1]].bind(triplet, func) + triplets.append(triplet) + + def event_delete(self, virtual, *sequences): + if virtual not in self.__eventinfo: + return + func, triplets = self.__eventinfo[virtual] + for seq in sequences: + triplet = _parse_sequence(seq) + if triplet is None: + #print >> sys.stderr, "Seq. %s was deleted by Tkinter."%seq + widget.event_delete(self, virtual, seq) + else: + if func is not None: + self.__binders[triplet[1]].unbind(triplet, func) + triplets.remove(triplet) + + def event_info(self, virtual=None): + if virtual is None or virtual not in self.__eventinfo: + return widget.event_info(self, virtual) + else: + return tuple(map(_triplet_to_sequence, + self.__eventinfo[virtual][1])) + \ + widget.event_info(self, virtual) + + def __del__(self): + for virtual in self.__eventinfo: + func, triplets = self.__eventinfo[virtual] + if func: + for triplet in triplets: + self.__binders[triplet[1]].unbind(triplet, func) + + + _multicall_dict[widget] = MultiCall + return MultiCall + + +def _multi_call(parent): + root = Tkinter.Tk() + root.title("Test MultiCall") + width, height, x, y = list(map(int, re.split('[x+]', parent.geometry()))) + root.geometry("+%d+%d"%(x, y + 150)) + text = MultiCallCreator(Tkinter.Text)(root) + text.pack() + def bindseq(seq, n=[0]): + def handler(event): + print seq + text.bind("<>"%n[0], handler) + text.event_add("<>"%n[0], seq) + n[0] += 1 + bindseq("") + bindseq("") + bindseq("") + bindseq("") + bindseq("") + bindseq("") + bindseq("") + bindseq("") + bindseq("") + bindseq("") + bindseq("") + bindseq("") + root.mainloop() + +if __name__ == "__main__": + from idlelib.idle_test.htest import run + run(_multi_call) diff --git a/PythonHome/Lib/idlelib/MultiCall.pyc b/PythonHome/Lib/idlelib/MultiCall.pyc deleted file mode 100644 index f1a593ab92c92a15abac2b67aa79b9305da03895..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 15859 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 XYqPt5(WOUqDm{1+_0tTxsoc2|=s1cO0+17i(v% zq>}yQh{6M}{04py|AZd^-#KH`_AS`nvvcOmoXdAEuKnF<|M}OO-jLRx8s6XFG2ekC z_$kVW`iVzc(MVBJqZ^_X(U0dIC3R-bYozOxG-&Ek70M-_vIgZoo%^J;Pr61cMXG?h zCiQ|Xs80XECs0^fCXehL(6f1F)1Hm(+?>SKdp?~&Y#xGW7!)_)+>K)6aFOkMbmP%^ zgTh`=$GM>g!qG7E0+0CuWPz(h(=DnF*)ZZ*DuQ3uqe+bxa$w=n?;fcX3{eEl1fSW- zZqNX=tgu@a8h3!q)bi%@D$cd#z@jKEQX56q2b0AEotc2$kZVR~BN61WvAPls)2jet z5@J5V>iFU`9bBYIrZc?X$K-hSI%IqN7&b?02j6?j@_NXwv4|z#;xPz~V@4nogx#d- zjKc;C(0~}S2_KL~%NeRI>$IrTM3T9{4k-oRU51vYMdvN^;reic5}yDW9~PvVFxi#J z21zOjW+W;Eqh0KAF&vkb!y`?!EUdn^0iO$*2&AWsoq*MQ)qU}-D|Pa{oSwzQsYr%p zF-k8bEg{<#X@OLPyR3_AN_0sc{vXV?h08|UNbYVkvjakESADGZ)SlN-UGaFGb+(GE zw{awj@-mrcU_&kuNtk$c`s{f>JiyjlS7ddov@?`kNQRT_dprJ+ci0|7CXxr(K_RT9 zs(}}>fW*S|1X*%b;Injvbm6DyqE1VXmNh~$mkq9ziO+SxS;v(c9gIBM=iX&elPiT8 zgbW_5rBA?V0i{?sY0;!fn++(tz25ze=vNfq4$lV^3e2iC4{clj@oh?4WIL3!36o$& zo_a$vZno(cM6*S9S9%wEaOe&#a8-Fr*lw{&cUkJy-?#v;CVS!x`|eg!pj;YVLGh>S z$3GiJ@A2mee(4`rnh!ww+SsF0<_j3{%MANOa=j$;*EK<(ahq4{l>_ zZCQxEJWh+OEN21tfe2@DrD2`5R%K~jZqme#MLO2$<=Bd@YoX4Q5sz;-Gahaf4aAC| z>EQkplG}8u-NV7?o$85@F|I1Z8c4O&6Lnv8WN^1ZF-+9Hw_88NyN&O9pm1nW1tkd0~vBm`cq)6D?!iU^(A)0LlDaoX8reZ%=H7F=280KOOPusT*rw Rb9xK|-uCwIwhlOge*txIhQa^< diff --git a/PythonHome/Lib/idlelib/ObjectBrowser.py b/PythonHome/Lib/idlelib/ObjectBrowser.py new file mode 100644 index 0000000000..e69365c144 --- /dev/null +++ b/PythonHome/Lib/idlelib/ObjectBrowser.py @@ -0,0 +1,156 @@ +# XXX TO DO: +# - popup menu +# - support partial or total redisplay +# - more doc strings +# - tooltips + +# object browser + +# XXX TO DO: +# - for classes/modules, add "open source" to object browser + +import re + +from idlelib.TreeWidget import TreeItem, TreeNode, ScrolledCanvas + +from repr import Repr + +myrepr = Repr() +myrepr.maxstring = 100 +myrepr.maxother = 100 + +class ObjectTreeItem(TreeItem): + def __init__(self, labeltext, object, setfunction=None): + self.labeltext = labeltext + self.object = object + self.setfunction = setfunction + def GetLabelText(self): + return self.labeltext + def GetText(self): + return myrepr.repr(self.object) + def GetIconName(self): + if not self.IsExpandable(): + return "python" + def IsEditable(self): + return self.setfunction is not None + def SetText(self, text): + try: + value = eval(text) + self.setfunction(value) + except: + pass + else: + self.object = value + def IsExpandable(self): + return not not dir(self.object) + def GetSubList(self): + keys = dir(self.object) + sublist = [] + for key in keys: + try: + value = getattr(self.object, key) + except AttributeError: + continue + item = make_objecttreeitem( + str(key) + " =", + value, + lambda value, key=key, object=self.object: + setattr(object, key, value)) + sublist.append(item) + return sublist + +class InstanceTreeItem(ObjectTreeItem): + def IsExpandable(self): + return True + def GetSubList(self): + sublist = ObjectTreeItem.GetSubList(self) + sublist.insert(0, + make_objecttreeitem("__class__ =", self.object.__class__)) + return sublist + +class ClassTreeItem(ObjectTreeItem): + def IsExpandable(self): + return True + def GetSubList(self): + sublist = ObjectTreeItem.GetSubList(self) + if len(self.object.__bases__) == 1: + item = make_objecttreeitem("__bases__[0] =", + self.object.__bases__[0]) + else: + item = make_objecttreeitem("__bases__ =", self.object.__bases__) + sublist.insert(0, item) + return sublist + +class AtomicObjectTreeItem(ObjectTreeItem): + def IsExpandable(self): + return 0 + +class SequenceTreeItem(ObjectTreeItem): + def IsExpandable(self): + return len(self.object) > 0 + def keys(self): + return range(len(self.object)) + def GetSubList(self): + sublist = [] + for key in self.keys(): + try: + value = self.object[key] + except KeyError: + continue + def setfunction(value, key=key, object=self.object): + object[key] = value + item = make_objecttreeitem("%r:" % (key,), value, setfunction) + sublist.append(item) + return sublist + +class DictTreeItem(SequenceTreeItem): + def keys(self): + keys = self.object.keys() + try: + keys.sort() + except: + pass + return keys + +from types import * + +dispatch = { + IntType: AtomicObjectTreeItem, + LongType: AtomicObjectTreeItem, + FloatType: AtomicObjectTreeItem, + StringType: AtomicObjectTreeItem, + TupleType: SequenceTreeItem, + ListType: SequenceTreeItem, + DictType: DictTreeItem, + InstanceType: InstanceTreeItem, + ClassType: ClassTreeItem, +} + +def make_objecttreeitem(labeltext, object, setfunction=None): + t = type(object) + if t in dispatch: + c = dispatch[t] + else: + c = ObjectTreeItem + return c(labeltext, object, setfunction) + + +def _object_browser(parent): + import sys + from Tkinter import Tk + root = Tk() + root.title("Test ObjectBrowser") + width, height, x, y = list(map(int, re.split('[x+]', parent.geometry()))) + root.geometry("+%d+%d"%(x, y + 150)) + root.configure(bd=0, bg="yellow") + root.focus_set() + sc = ScrolledCanvas(root, bg="white", highlightthickness=0, takefocus=1) + sc.frame.pack(expand=1, fill="both") + item = make_objecttreeitem("sys", sys) + node = TreeNode(sc.canvas, None, item) + node.update() + root.mainloop() + +if __name__ == '__main__': + from idlelib.idle_test.htest import run + run(_object_browser) diff --git a/PythonHome/Lib/idlelib/ObjectBrowser.pyc b/PythonHome/Lib/idlelib/ObjectBrowser.pyc deleted file mode 100644 index 73a8fe6726aa5f905a105fae2df52ad24f395b66..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6647 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 diff --git a/PythonHome/Lib/idlelib/OutputWindow.py b/PythonHome/Lib/idlelib/OutputWindow.py new file mode 100644 index 0000000000..e18d846d8d --- /dev/null +++ b/PythonHome/Lib/idlelib/OutputWindow.py @@ -0,0 +1,149 @@ +from Tkinter import * +from idlelib.EditorWindow import EditorWindow +import re +import tkMessageBox +from idlelib import IOBinding + +class OutputWindow(EditorWindow): + + """An editor window that can serve as an output file. + + Also the future base class for the Python shell window. + This class has no input facilities. + """ + + def __init__(self, *args): + EditorWindow.__init__(self, *args) + self.text.bind("<>", self.goto_file_line) + + # Customize EditorWindow + + def ispythonsource(self, filename): + # No colorization needed + return 0 + + def short_title(self): + return "Output" + + def maybesave(self): + # Override base class method -- don't ask any questions + if self.get_saved(): + return "yes" + else: + return "no" + + # Act as output file + + def write(self, s, tags=(), mark="insert"): + # Tk assumes that byte strings are Latin-1; + # we assume that they are in the locale's encoding + if isinstance(s, str): + try: + s = unicode(s, IOBinding.encoding) + except UnicodeError: + # some other encoding; let Tcl deal with it + pass + self.text.insert(mark, s, tags) + self.text.see(mark) + self.text.update() + + def writelines(self, lines): + for line in lines: + self.write(line) + + def flush(self): + pass + + # Our own right-button menu + + rmenu_specs = [ + ("Cut", "<>", "rmenu_check_cut"), + ("Copy", "<>", "rmenu_check_copy"), + ("Paste", "<>", "rmenu_check_paste"), + (None, None, None), + ("Go to file/line", "<>", None), + ] + + file_line_pats = [ + # order of patterns matters + r'file "([^"]*)", line (\d+)', + r'([^\s]+)\((\d+)\)', + r'^(\s*\S.*?):\s*(\d+):', # Win filename, maybe starting with spaces + r'([^\s]+):\s*(\d+):', # filename or path, ltrim + r'^\s*(\S.*?):\s*(\d+):', # Win abs path with embedded spaces, ltrim + ] + + file_line_progs = None + + def goto_file_line(self, event=None): + if self.file_line_progs is None: + l = [] + for pat in self.file_line_pats: + l.append(re.compile(pat, re.IGNORECASE)) + self.file_line_progs = l + # x, y = self.event.x, self.event.y + # self.text.mark_set("insert", "@%d,%d" % (x, y)) + line = self.text.get("insert linestart", "insert lineend") + result = self._file_line_helper(line) + if not result: + # Try the previous line. This is handy e.g. in tracebacks, + # where you tend to right-click on the displayed source line + line = self.text.get("insert -1line linestart", + "insert -1line lineend") + result = self._file_line_helper(line) + if not result: + tkMessageBox.showerror( + "No special line", + "The line you point at doesn't look like " + "a valid file name followed by a line number.", + master=self.text) + return + filename, lineno = result + edit = self.flist.open(filename) + edit.gotoline(lineno) + + def _file_line_helper(self, line): + for prog in self.file_line_progs: + match = prog.search(line) + if match: + filename, lineno = match.group(1, 2) + try: + f = open(filename, "r") + f.close() + break + except IOError: + continue + else: + return None + try: + return filename, int(lineno) + except TypeError: + return None + +# These classes are currently not used but might come in handy + +class OnDemandOutputWindow: + + tagdefs = { + # XXX Should use IdlePrefs.ColorPrefs + "stdout": {"foreground": "blue"}, + "stderr": {"foreground": "#007700"}, + } + + def __init__(self, flist): + self.flist = flist + self.owin = None + + def write(self, s, tags, mark): + if not self.owin: + self.setup() + self.owin.write(s, tags, mark) + + def setup(self): + self.owin = owin = OutputWindow(self.flist) + text = owin.text + for tag, cnf in self.tagdefs.items(): + if cnf: + text.tag_configure(tag, **cnf) + text.tag_raise('sel') + self.write = self.owin.write diff --git a/PythonHome/Lib/idlelib/OutputWindow.pyc b/PythonHome/Lib/idlelib/OutputWindow.pyc deleted file mode 100644 index 011d7bdf91f981f0a69306f1a98e90092c5a57c3..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5007 zcmbVQTXP&o6+W{!X%)$GjBkk@d!k^nlCkVi;7~zjh%aSaz}gv!k`Z!-(N3>4((KH7 zy4RK{>B-@ND&Uz1UU}gM@DKP!@DAU1dMyc)R9URly{Au~?mm6)z4d?2O#OZJH_JU4 zf9m-D37Rd@rT7md7g-@xlRS_?P1b4>a9o$XE^BqA0^E?bhQbZWn=)w0S_^bdF*WH2 zlD6b4kyj$WTAPp*|7}Sp4^flcZMidrGqZo=(+L1Mb_*Vy2KXS&Tv@GVMOwb>dUPA; zN009Ul@*(gM2|;qIC7ro@KO_)xQk~0jLwLxfgkiW-VR*x4mAaEfw}@sNgE2ZB)ufK z1^LI-m3J-y$IAX1?r~Yt4V*jt8v-u%reQzJ&EnKl zh|lM_EkSF-{>Y6g6K*8dguOhmHtd&`&OF(3TP60{GI>7UeNor0Y-M&#yM_IWGRz7H zGVCY4EYDnKtf%WyDK#`2%0o1}fX<0*2eL1+AIKj92>@-^WE*l->~=$5d81kGaBbI~ zLBF)LS-SEDFK{Ez3UlX9rwMeVx}O9T$61lNICc#ToY{2>Y(OUN6fj&Jb9Kzsy0H>i zllK)!s!iJgp=f760JOON^K4^1OLLRs`?#?z4)-FSGmB;kNN_snky|$MbPr8uaH;V< zGNAnKdVEB#9XqmBBm;AjkZwq$!k_Ul}-Uz1mLZ|}fP68maw{}{I! z@E9wX^_pD`a89F~1%oardPYTLUF8_0Mn%>uQxj2KYDcEP_;qairJsFJRb>^atI&=7 z2FB>MN5eF6ro$_HW26;W??B0>2L?&Cb0VAIQ7@~^nQPqaG&-rz2KC^4FjJdAKlT&q znoZ?A2VnOSMRfn!x8wlwRYRe?AfM+GvU*G`YN~WkwHnVj52aswp4G#Fd0SUjAuG?i z$M>*u?9?+~W5^WOF?RHv|IdBMbw3~3t=l}&JB}*o-pE;McxkCOa(C`HhM8($ic#F# zGQFJ`Sk=F03yv zF8p}@GeA1^na26o^vBS;K&jqXpaGXx;sw=^{sq9>4m7kgDb*LUDKx0v8;Y;Nz~C zl9{HlZ=!_BZ6oh%sel59JWpWfK>eR*Hf0^>wB*1~PRsU;?1M#|hQKi?+oxn7E8re# zi!_3+dYg}Bss_Z2%2{T=V@Ok^_QDbB#wV&U)v}UP+GFx#b6iEk=$4@!nqHRV{)83a zR!~IfCVS;59F|$(LR27WX>9Sa3-hwv!Ss#^lki27XQ`T1$b5%FBhSm1CJi_CFspkM zqrrx$7BxN%Xs1<&=c)@Frtf%ImE-u-EeoT$@YrPHtgcUnL-4KXq%s;Zd*xsVdsT;j z^sxIldT{UacgtNzyF>1KX&7MD#rk<> zyZ4F)USM7;)?AMrCN8?l1DKa8V@J7*82EL}^+l=v&O+}b!8l?N z>7rR(70d=L#NRNOuAd`ZpAOoJYau?jYE!{PFddxnbqrUM8+EI{0oeVmTB*Q;b~Hr8 zgOJjY7h#fcsJc{B>`}@c`Uy?ALHF3Z!psA2LB&k}Y0;LMK9TXBtUezdX3yuEJ*Nby zr_b><I@CA+szo0GtG^JDzAchfGSmM zlB&0*dfTkZ(J=Y}XBbF&d1<}1JbLW2=K`nd=wRBa_m#b&(Wwr_qNZT|1on4(Dj6hY2G37^AK)&bt2l1lgh6VKP!Th-11tYI7QO91qHL zghD)4myF}I?8UK`(-8~GXoekgN5m{2h3r0Lr+OfX&u|PxHoDFks#T3WqR5V9tk7H3 z@{}7@sqd3kt5s{a+KqO--JYGncdHH|^RL}JgzBx@^d)x|YaSQ(%^)e#4M9!X{yxDT;_dZX=)E=13nuw~;e$^P$<)cOG#14(3aFLNQIg{HQ*S1{?Xv zM>4$E42>AEjxK9misznMz(==kefsIGTd&cGRhl#D6>RrNeI6Z)Q%!eZivV~yszWK9 z==`b~zPV7x)brvoqmtz9}$S4<07#M+#&b77&w0c zjgSp5RlF4-YCLsWlHAt&X$gXx-G6pXQ$FTUT{NV+sYMDRr3TJFvJk#0_-Ac`Vgc5} z>`%#HjG6#yLy1DQQMLXxh1ac*dq+B?TztZ#!MkKLHGQjsLd`y~j@}1s+$)QIwuxT` zG~y9cC7Cr|ki4rGiy uKR-k_FdOmJplil-`Yel7?mX?pJZj)v@}cq$Q-|_8g(NVIztgqzFa862_11C# diff --git a/PythonHome/Lib/idlelib/ParenMatch.py b/PythonHome/Lib/idlelib/ParenMatch.py new file mode 100644 index 0000000000..19bad8ce38 --- /dev/null +++ b/PythonHome/Lib/idlelib/ParenMatch.py @@ -0,0 +1,178 @@ +"""ParenMatch -- An IDLE extension for parenthesis matching. + +When you hit a right paren, the cursor should move briefly to the left +paren. Paren here is used generically; the matching applies to +parentheses, square brackets, and curly braces. +""" + +from idlelib.HyperParser import HyperParser +from idlelib.configHandler import idleConf + +_openers = {')':'(',']':'[','}':'{'} +CHECK_DELAY = 100 # miliseconds + +class ParenMatch: + """Highlight matching parentheses + + There are three supported style of paren matching, based loosely + on the Emacs options. The style is select based on the + HILITE_STYLE attribute; it can be changed used the set_style + method. + + The supported styles are: + + default -- When a right paren is typed, highlight the matching + left paren for 1/2 sec. + + expression -- When a right paren is typed, highlight the entire + expression from the left paren to the right paren. + + TODO: + - extend IDLE with configuration dialog to change options + - implement rest of Emacs highlight styles (see below) + - print mismatch warning in IDLE status window + + Note: In Emacs, there are several styles of highlight where the + matching paren is highlighted whenever the cursor is immediately + to the right of a right paren. I don't know how to do that in Tk, + so I haven't bothered. + """ + menudefs = [ + ('edit', [ + ("Show surrounding parens", "<>"), + ]) + ] + STYLE = idleConf.GetOption('extensions','ParenMatch','style', + default='expression') + FLASH_DELAY = idleConf.GetOption('extensions','ParenMatch','flash-delay', + type='int',default=500) + HILITE_CONFIG = idleConf.GetHighlight(idleConf.CurrentTheme(),'hilite') + BELL = idleConf.GetOption('extensions','ParenMatch','bell', + type='bool',default=1) + + RESTORE_VIRTUAL_EVENT_NAME = "<>" + # We want the restore event be called before the usual return and + # backspace events. + RESTORE_SEQUENCES = ("", "", + "", "") + + def __init__(self, editwin): + self.editwin = editwin + self.text = editwin.text + # Bind the check-restore event to the function restore_event, + # so that we can then use activate_restore (which calls event_add) + # and deactivate_restore (which calls event_delete). + editwin.text.bind(self.RESTORE_VIRTUAL_EVENT_NAME, + self.restore_event) + self.counter = 0 + self.is_restore_active = 0 + self.set_style(self.STYLE) + + def activate_restore(self): + if not self.is_restore_active: + for seq in self.RESTORE_SEQUENCES: + self.text.event_add(self.RESTORE_VIRTUAL_EVENT_NAME, seq) + self.is_restore_active = True + + def deactivate_restore(self): + if self.is_restore_active: + for seq in self.RESTORE_SEQUENCES: + self.text.event_delete(self.RESTORE_VIRTUAL_EVENT_NAME, seq) + self.is_restore_active = False + + def set_style(self, style): + self.STYLE = style + if style == "default": + self.create_tag = self.create_tag_default + self.set_timeout = self.set_timeout_last + elif style == "expression": + self.create_tag = self.create_tag_expression + self.set_timeout = self.set_timeout_none + + def flash_paren_event(self, event): + indices = (HyperParser(self.editwin, "insert") + .get_surrounding_brackets()) + if indices is None: + self.warn_mismatched() + return + self.activate_restore() + self.create_tag(indices) + self.set_timeout_last() + + def paren_closed_event(self, event): + # If it was a shortcut and not really a closing paren, quit. + closer = self.text.get("insert-1c") + if closer not in _openers: + return + hp = HyperParser(self.editwin, "insert-1c") + if not hp.is_in_code(): + return + indices = hp.get_surrounding_brackets(_openers[closer], True) + if indices is None: + self.warn_mismatched() + return + self.activate_restore() + self.create_tag(indices) + self.set_timeout() + + def restore_event(self, event=None): + self.text.tag_delete("paren") + self.deactivate_restore() + self.counter += 1 # disable the last timer, if there is one. + + def handle_restore_timer(self, timer_count): + if timer_count == self.counter: + self.restore_event() + + def warn_mismatched(self): + if self.BELL: + self.text.bell() + + # any one of the create_tag_XXX methods can be used depending on + # the style + + def create_tag_default(self, indices): + """Highlight the single paren that matches""" + self.text.tag_add("paren", indices[0]) + self.text.tag_config("paren", self.HILITE_CONFIG) + + def create_tag_expression(self, indices): + """Highlight the entire expression""" + if self.text.get(indices[1]) in (')', ']', '}'): + rightindex = indices[1]+"+1c" + else: + rightindex = indices[1] + self.text.tag_add("paren", indices[0], rightindex) + self.text.tag_config("paren", self.HILITE_CONFIG) + + # any one of the set_timeout_XXX methods can be used depending on + # the style + + def set_timeout_none(self): + """Highlight will remain until user input turns it off + or the insert has moved""" + # After CHECK_DELAY, call a function which disables the "paren" tag + # if the event is for the most recent timer and the insert has changed, + # or schedules another call for itself. + self.counter += 1 + def callme(callme, self=self, c=self.counter, + index=self.text.index("insert")): + if index != self.text.index("insert"): + self.handle_restore_timer(c) + else: + self.editwin.text_frame.after(CHECK_DELAY, callme, callme) + self.editwin.text_frame.after(CHECK_DELAY, callme, callme) + + def set_timeout_last(self): + """The last highlight created will be removed after .5 sec""" + # associate a counter with an event; only disable the "paren" + # tag if the event is for the most recent timer. + self.counter += 1 + self.editwin.text_frame.after( + self.FLASH_DELAY, + lambda self=self, c=self.counter: self.handle_restore_timer(c)) + + +if __name__ == '__main__': + import unittest + unittest.main('idlelib.idle_test.test_parenmatch', verbosity=2) diff --git a/PythonHome/Lib/idlelib/ParenMatch.pyc b/PythonHome/Lib/idlelib/ParenMatch.pyc deleted file mode 100644 index c3aa4989dbb6970b35ececdfa2e203f7c8d1b5ad..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6874 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 diff --git a/PythonHome/Lib/idlelib/Percolator.py b/PythonHome/Lib/idlelib/Percolator.py new file mode 100644 index 0000000000..e0e8cade0d --- /dev/null +++ b/PythonHome/Lib/idlelib/Percolator.py @@ -0,0 +1,103 @@ +from idlelib.WidgetRedirector import WidgetRedirector +from idlelib.Delegator import Delegator + +class Percolator: + + def __init__(self, text): + # XXX would be nice to inherit from Delegator + self.text = text + self.redir = WidgetRedirector(text) + self.top = self.bottom = Delegator(text) + self.bottom.insert = self.redir.register("insert", self.insert) + self.bottom.delete = self.redir.register("delete", self.delete) + self.filters = [] + + def close(self): + while self.top is not self.bottom: + self.removefilter(self.top) + self.top = None + self.bottom.setdelegate(None); self.bottom = None + self.redir.close(); self.redir = None + self.text = None + + def insert(self, index, chars, tags=None): + # Could go away if inheriting from Delegator + self.top.insert(index, chars, tags) + + def delete(self, index1, index2=None): + # Could go away if inheriting from Delegator + self.top.delete(index1, index2) + + def insertfilter(self, filter): + # Perhaps rename to pushfilter()? + assert isinstance(filter, Delegator) + assert filter.delegate is None + filter.setdelegate(self.top) + self.top = filter + + def removefilter(self, filter): + # XXX Perhaps should only support popfilter()? + assert isinstance(filter, Delegator) + assert filter.delegate is not None + f = self.top + if f is filter: + self.top = filter.delegate + filter.setdelegate(None) + else: + while f.delegate is not filter: + assert f is not self.bottom + f.resetcache() + f = f.delegate + f.setdelegate(filter.delegate) + filter.setdelegate(None) + + +def _percolator(parent): + import Tkinter as tk + import re + class Tracer(Delegator): + def __init__(self, name): + self.name = name + Delegator.__init__(self, None) + def insert(self, *args): + print self.name, ": insert", args + self.delegate.insert(*args) + def delete(self, *args): + print self.name, ": delete", args + self.delegate.delete(*args) + root = tk.Tk() + root.title("Test Percolator") + width, height, x, y = list(map(int, re.split('[x+]', parent.geometry()))) + root.geometry("+%d+%d"%(x, y + 150)) + text = tk.Text(root) + p = Percolator(text) + t1 = Tracer("t1") + t2 = Tracer("t2") + + def toggle1(): + if var1.get() == 0: + var1.set(1) + p.insertfilter(t1) + elif var1.get() == 1: + var1.set(0) + p.removefilter(t1) + + def toggle2(): + if var2.get() == 0: + var2.set(1) + p.insertfilter(t2) + elif var2.get() == 1: + var2.set(0) + p.removefilter(t2) + + text.pack() + var1 = tk.IntVar() + cb1 = tk.Checkbutton(root, text="Tracer1", command=toggle1, variable=var1) + cb1.pack() + var2 = tk.IntVar() + cb2 = tk.Checkbutton(root, text="Tracer2", command=toggle2, variable=var2) + cb2.pack() + +if __name__ == "__main__": + from idlelib.idle_test.htest import run + run(_percolator) diff --git a/PythonHome/Lib/idlelib/Percolator.pyc b/PythonHome/Lib/idlelib/Percolator.pyc deleted file mode 100644 index b13cbae41baf1959d846a2aa80cce78eb6936796..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4383 zcmd5<>uwuG6h5=IW3TJbP)NB6Xt^3H1yX(>0YX5F0un@MQm9BvEoXP)Y+|p|-6^C} z{HH;*Nc=`T0?)v6@FqL}eBYUM99mEli61zb*}0rKbLKmjIaB*%zWwX(ch?fBel>hQ zKq)g+DgKQNMMg%}jTrVL8AdXy$$Aa_nxwI$b@^W8K;-N7x}*(u)*IsHB%PC;ND8NX znlfz4s3q$yF|H-9AqU`?gJVn9x^3*1{fS@Kpyd}(UCq*g^VX$V;SxVC!c2^r%Wmif zeGGXn`@$8;c*ySIAtDTagi>BcpI$Cy&cImc2TMSo^;kB6p8SfNLU&oYpd*0$JzJaPBmR14gYCqo9 zMH^%9$0OfTia}O-S6I$l<-n6~W-;*hrfi9v2Yv37uF$ruP7{f_H83Ou@v13D1r&Y zgBjhd$yK02c&3Egu*EQ0O$5Lj1pfg0RHM*+SOm`o7gN!Z01ptI>x3& zfqEJP0S!Pzi-i5u;GpFDV^GQ5HZ*}L|m>+9?gpA`9hH*;df-5YNz$ zAyv63K9W0%<~D+b$WBYj*N+SaXNEDs{;D7Vx1PaG^U(m6mGDsC&l4AX?-5LVSkh;+ zasF{pAdb<>4sD3@mdaOUsng9s2nKlkldJ892oaV(55^_;lV}lkwO}-?{Y_85Ve%nZ z#7D4z7dB)9i^D%0v?awgHh>!a5ip^x$PlUgn(VzxQceeV{zX@UOOxJR-kD+y8U#RC zf1t(=H*d&QcIGPn74$RiN8sm0Vb8Ks|D)~MCs`@H>f4Gjp-?py4vw7klPx#1JNp!8 z$zb#NklT6Czk*V7zW{S=I`~_N&H(bZnFs8vT}oI*#k@aqy`GBE>y5_gts%OWVMilD zkeNEtm~83py30%`Z9OaoTbevwL1XV+6vuI^Q}5K{X2LTP8N$Jh${ZuOq<|>y{|OqQ zZK!G7n{bXzjNsA?SN}xS38g||6Wn%nVF0eHcOb05Yd!8aRVh*gMuC{5@HGA#xn7qE ztY}UqO_{WGJuW&Z8mn58Hsy)UNX||b-X;M$lUNXf_rc1@kMLeNDoh4#_^sw9Y)5ie zNl(i?9M{w) z9og^51IqvcSR5`}&}FA|8D+0c=4F3=x=aoCQQ*F+S&#;~D@8v+Zi7MnQ9~c0lrN(C z*Q5p+4YHd$bCw$D)VZgDZjGy-MFqj=nrhleN6^Op(8JMCTnC-r0<_KGLu!vSl37f$ z=h#I#UJ{@t{Vu3WvKQQG36DhqS+1g#FQKA+h^)ZoRv_!jC+q`E4KP22%X>|QSk+MW z&bbibg5#b8gW&2!U?!`creB=+PJ16*DtQqt{~LL$M2!L}gh5_{GLzSyXBXv|*mCuU zD2K9kd7WD-+&;%j^`~3vMi@E?dtMyxpp?9e=S*CSYb7J-6<7Lmvs6!azqWVb8>PGO za*F@#XV4*Hpjr-}iwQdV}UDnz|yZ71W=sGp~LNdoVzzk%ls;S59V!{{-tOV+`E9OIi`HD_Y`X*7e9Jt8_Zf4S zPPEusY_-ukj|_%&mAj1kS>Ee~*EyvuZsn`WCL}n_fvN}L()~~R@HFMMH>J2decFc` zhxpl#Suu)vCUH|retRCVXK9PIUBO(~7LDUYOg+GRA>DeP!9dM&0cqM}Z^cVU*UVqA Ckmf-E diff --git a/PythonHome/Lib/idlelib/PyParse.py b/PythonHome/Lib/idlelib/PyParse.py new file mode 100644 index 0000000000..1a9db6743c --- /dev/null +++ b/PythonHome/Lib/idlelib/PyParse.py @@ -0,0 +1,594 @@ +import re +import sys + +# Reason last stmt is continued (or C_NONE if it's not). +(C_NONE, C_BACKSLASH, C_STRING_FIRST_LINE, + C_STRING_NEXT_LINES, C_BRACKET) = range(5) + +if 0: # for throwaway debugging output + def dump(*stuff): + sys.__stdout__.write(" ".join(map(str, stuff)) + "\n") + +# Find what looks like the start of a popular stmt. + +_synchre = re.compile(r""" + ^ + [ \t]* + (?: while + | else + | def + | return + | assert + | break + | class + | continue + | elif + | try + | except + | raise + | import + | yield + ) + \b +""", re.VERBOSE | re.MULTILINE).search + +# Match blank line or non-indenting comment line. + +_junkre = re.compile(r""" + [ \t]* + (?: \# \S .* )? + \n +""", re.VERBOSE).match + +# Match any flavor of string; the terminating quote is optional +# so that we're robust in the face of incomplete program text. + +_match_stringre = re.compile(r""" + \""" [^"\\]* (?: + (?: \\. | "(?!"") ) + [^"\\]* + )* + (?: \""" )? + +| " [^"\\\n]* (?: \\. [^"\\\n]* )* "? + +| ''' [^'\\]* (?: + (?: \\. | '(?!'') ) + [^'\\]* + )* + (?: ''' )? + +| ' [^'\\\n]* (?: \\. [^'\\\n]* )* '? +""", re.VERBOSE | re.DOTALL).match + +# Match a line that starts with something interesting; +# used to find the first item of a bracket structure. + +_itemre = re.compile(r""" + [ \t]* + [^\s#\\] # if we match, m.end()-1 is the interesting char +""", re.VERBOSE).match + +# Match start of stmts that should be followed by a dedent. + +_closere = re.compile(r""" + \s* + (?: return + | break + | continue + | raise + | pass + ) + \b +""", re.VERBOSE).match + +# Chew up non-special chars as quickly as possible. If match is +# successful, m.end() less 1 is the index of the last boring char +# matched. If match is unsuccessful, the string starts with an +# interesting char. + +_chew_ordinaryre = re.compile(r""" + [^[\](){}#'"\\]+ +""", re.VERBOSE).match + +# Build translation table to map uninteresting chars to "x", open +# brackets to "(", and close brackets to ")". + +_tran = ['x'] * 256 +for ch in "({[": + _tran[ord(ch)] = '(' +for ch in ")}]": + _tran[ord(ch)] = ')' +for ch in "\"'\\\n#": + _tran[ord(ch)] = ch +_tran = ''.join(_tran) +del ch + +try: + UnicodeType = type(unicode("")) +except NameError: + UnicodeType = None + +class Parser: + + def __init__(self, indentwidth, tabwidth): + self.indentwidth = indentwidth + self.tabwidth = tabwidth + + def set_str(self, str): + assert len(str) == 0 or str[-1] == '\n' + if type(str) is UnicodeType: + # The parse functions have no idea what to do with Unicode, so + # replace all Unicode characters with "x". This is "safe" + # so long as the only characters germane to parsing the structure + # of Python are 7-bit ASCII. It's *necessary* because Unicode + # strings don't have a .translate() method that supports + # deletechars. + uniphooey = str + str = [] + push = str.append + for raw in map(ord, uniphooey): + push(raw < 127 and chr(raw) or "x") + str = "".join(str) + self.str = str + self.study_level = 0 + + # Return index of a good place to begin parsing, as close to the + # end of the string as possible. This will be the start of some + # popular stmt like "if" or "def". Return None if none found: + # the caller should pass more prior context then, if possible, or + # if not (the entire program text up until the point of interest + # has already been tried) pass 0 to set_lo. + # + # This will be reliable iff given a reliable is_char_in_string + # function, meaning that when it says "no", it's absolutely + # guaranteed that the char is not in a string. + + def find_good_parse_start(self, is_char_in_string=None, + _synchre=_synchre): + str, pos = self.str, None + + if not is_char_in_string: + # no clue -- make the caller pass everything + return None + + # Peek back from the end for a good place to start, + # but don't try too often; pos will be left None, or + # bumped to a legitimate synch point. + limit = len(str) + for tries in range(5): + i = str.rfind(":\n", 0, limit) + if i < 0: + break + i = str.rfind('\n', 0, i) + 1 # start of colon line + m = _synchre(str, i, limit) + if m and not is_char_in_string(m.start()): + pos = m.start() + break + limit = i + if pos is None: + # Nothing looks like a block-opener, or stuff does + # but is_char_in_string keeps returning true; most likely + # we're in or near a giant string, the colorizer hasn't + # caught up enough to be helpful, or there simply *aren't* + # any interesting stmts. In any of these cases we're + # going to have to parse the whole thing to be sure, so + # give it one last try from the start, but stop wasting + # time here regardless of the outcome. + m = _synchre(str) + if m and not is_char_in_string(m.start()): + pos = m.start() + return pos + + # Peeking back worked; look forward until _synchre no longer + # matches. + i = pos + 1 + while 1: + m = _synchre(str, i) + if m: + s, i = m.span() + if not is_char_in_string(s): + pos = s + else: + break + return pos + + # Throw away the start of the string. Intended to be called with + # find_good_parse_start's result. + + def set_lo(self, lo): + assert lo == 0 or self.str[lo-1] == '\n' + if lo > 0: + self.str = self.str[lo:] + + # As quickly as humanly possible , find the line numbers (0- + # based) of the non-continuation lines. + # Creates self.{goodlines, continuation}. + + def _study1(self): + if self.study_level >= 1: + return + self.study_level = 1 + + # Map all uninteresting characters to "x", all open brackets + # to "(", all close brackets to ")", then collapse runs of + # uninteresting characters. This can cut the number of chars + # by a factor of 10-40, and so greatly speed the following loop. + str = self.str + str = str.translate(_tran) + str = str.replace('xxxxxxxx', 'x') + str = str.replace('xxxx', 'x') + str = str.replace('xx', 'x') + str = str.replace('xx', 'x') + str = str.replace('\nx', '\n') + # note that replacing x\n with \n would be incorrect, because + # x may be preceded by a backslash + + # March over the squashed version of the program, accumulating + # the line numbers of non-continued stmts, and determining + # whether & why the last stmt is a continuation. + continuation = C_NONE + level = lno = 0 # level is nesting level; lno is line number + self.goodlines = goodlines = [0] + push_good = goodlines.append + i, n = 0, len(str) + while i < n: + ch = str[i] + i = i+1 + + # cases are checked in decreasing order of frequency + if ch == 'x': + continue + + if ch == '\n': + lno = lno + 1 + if level == 0: + push_good(lno) + # else we're in an unclosed bracket structure + continue + + if ch == '(': + level = level + 1 + continue + + if ch == ')': + if level: + level = level - 1 + # else the program is invalid, but we can't complain + continue + + if ch == '"' or ch == "'": + # consume the string + quote = ch + if str[i-1:i+2] == quote * 3: + quote = quote * 3 + firstlno = lno + w = len(quote) - 1 + i = i+w + while i < n: + ch = str[i] + i = i+1 + + if ch == 'x': + continue + + if str[i-1:i+w] == quote: + i = i+w + break + + if ch == '\n': + lno = lno + 1 + if w == 0: + # unterminated single-quoted string + if level == 0: + push_good(lno) + break + continue + + if ch == '\\': + assert i < n + if str[i] == '\n': + lno = lno + 1 + i = i+1 + continue + + # else comment char or paren inside string + + else: + # didn't break out of the loop, so we're still + # inside a string + if (lno - 1) == firstlno: + # before the previous \n in str, we were in the first + # line of the string + continuation = C_STRING_FIRST_LINE + else: + continuation = C_STRING_NEXT_LINES + continue # with outer loop + + if ch == '#': + # consume the comment + i = str.find('\n', i) + assert i >= 0 + continue + + assert ch == '\\' + assert i < n + if str[i] == '\n': + lno = lno + 1 + if i+1 == n: + continuation = C_BACKSLASH + i = i+1 + + # The last stmt may be continued for all 3 reasons. + # String continuation takes precedence over bracket + # continuation, which beats backslash continuation. + if (continuation != C_STRING_FIRST_LINE + and continuation != C_STRING_NEXT_LINES and level > 0): + continuation = C_BRACKET + self.continuation = continuation + + # Push the final line number as a sentinel value, regardless of + # whether it's continued. + assert (continuation == C_NONE) == (goodlines[-1] == lno) + if goodlines[-1] != lno: + push_good(lno) + + def get_continuation_type(self): + self._study1() + return self.continuation + + # study1 was sufficient to determine the continuation status, + # but doing more requires looking at every character. study2 + # does this for the last interesting statement in the block. + # Creates: + # self.stmt_start, stmt_end + # slice indices of last interesting stmt + # self.stmt_bracketing + # the bracketing structure of the last interesting stmt; + # for example, for the statement "say(boo) or die", stmt_bracketing + # will be [(0, 0), (3, 1), (8, 0)]. Strings and comments are + # treated as brackets, for the matter. + # self.lastch + # last non-whitespace character before optional trailing + # comment + # self.lastopenbracketpos + # if continuation is C_BRACKET, index of last open bracket + + def _study2(self): + if self.study_level >= 2: + return + self._study1() + self.study_level = 2 + + # Set p and q to slice indices of last interesting stmt. + str, goodlines = self.str, self.goodlines + i = len(goodlines) - 1 + p = len(str) # index of newest line + while i: + assert p + # p is the index of the stmt at line number goodlines[i]. + # Move p back to the stmt at line number goodlines[i-1]. + q = p + for nothing in range(goodlines[i-1], goodlines[i]): + # tricky: sets p to 0 if no preceding newline + p = str.rfind('\n', 0, p-1) + 1 + # The stmt str[p:q] isn't a continuation, but may be blank + # or a non-indenting comment line. + if _junkre(str, p): + i = i-1 + else: + break + if i == 0: + # nothing but junk! + assert p == 0 + q = p + self.stmt_start, self.stmt_end = p, q + + # Analyze this stmt, to find the last open bracket (if any) + # and last interesting character (if any). + lastch = "" + stack = [] # stack of open bracket indices + push_stack = stack.append + bracketing = [(p, 0)] + while p < q: + # suck up all except ()[]{}'"#\\ + m = _chew_ordinaryre(str, p, q) + if m: + # we skipped at least one boring char + newp = m.end() + # back up over totally boring whitespace + i = newp - 1 # index of last boring char + while i >= p and str[i] in " \t\n": + i = i-1 + if i >= p: + lastch = str[i] + p = newp + if p >= q: + break + + ch = str[p] + + if ch in "([{": + push_stack(p) + bracketing.append((p, len(stack))) + lastch = ch + p = p+1 + continue + + if ch in ")]}": + if stack: + del stack[-1] + lastch = ch + p = p+1 + bracketing.append((p, len(stack))) + continue + + if ch == '"' or ch == "'": + # consume string + # Note that study1 did this with a Python loop, but + # we use a regexp here; the reason is speed in both + # cases; the string may be huge, but study1 pre-squashed + # strings to a couple of characters per line. study1 + # also needed to keep track of newlines, and we don't + # have to. + bracketing.append((p, len(stack)+1)) + lastch = ch + p = _match_stringre(str, p, q).end() + bracketing.append((p, len(stack))) + continue + + if ch == '#': + # consume comment and trailing newline + bracketing.append((p, len(stack)+1)) + p = str.find('\n', p, q) + 1 + assert p > 0 + bracketing.append((p, len(stack))) + continue + + assert ch == '\\' + p = p+1 # beyond backslash + assert p < q + if str[p] != '\n': + # the program is invalid, but can't complain + lastch = ch + str[p] + p = p+1 # beyond escaped char + + # end while p < q: + + self.lastch = lastch + if stack: + self.lastopenbracketpos = stack[-1] + self.stmt_bracketing = tuple(bracketing) + + # Assuming continuation is C_BRACKET, return the number + # of spaces the next line should be indented. + + def compute_bracket_indent(self): + self._study2() + assert self.continuation == C_BRACKET + j = self.lastopenbracketpos + str = self.str + n = len(str) + origi = i = str.rfind('\n', 0, j) + 1 + j = j+1 # one beyond open bracket + # find first list item; set i to start of its line + while j < n: + m = _itemre(str, j) + if m: + j = m.end() - 1 # index of first interesting char + extra = 0 + break + else: + # this line is junk; advance to next line + i = j = str.find('\n', j) + 1 + else: + # nothing interesting follows the bracket; + # reproduce the bracket line's indentation + a level + j = i = origi + while str[j] in " \t": + j = j+1 + extra = self.indentwidth + return len(str[i:j].expandtabs(self.tabwidth)) + extra + + # Return number of physical lines in last stmt (whether or not + # it's an interesting stmt! this is intended to be called when + # continuation is C_BACKSLASH). + + def get_num_lines_in_stmt(self): + self._study1() + goodlines = self.goodlines + return goodlines[-1] - goodlines[-2] + + # Assuming continuation is C_BACKSLASH, return the number of spaces + # the next line should be indented. Also assuming the new line is + # the first one following the initial line of the stmt. + + def compute_backslash_indent(self): + self._study2() + assert self.continuation == C_BACKSLASH + str = self.str + i = self.stmt_start + while str[i] in " \t": + i = i+1 + startpos = i + + # See whether the initial line starts an assignment stmt; i.e., + # look for an = operator + endpos = str.find('\n', startpos) + 1 + found = level = 0 + while i < endpos: + ch = str[i] + if ch in "([{": + level = level + 1 + i = i+1 + elif ch in ")]}": + if level: + level = level - 1 + i = i+1 + elif ch == '"' or ch == "'": + i = _match_stringre(str, i, endpos).end() + elif ch == '#': + break + elif level == 0 and ch == '=' and \ + (i == 0 or str[i-1] not in "=<>!") and \ + str[i+1] != '=': + found = 1 + break + else: + i = i+1 + + if found: + # found a legit =, but it may be the last interesting + # thing on the line + i = i+1 # move beyond the = + found = re.match(r"\s*\\", str[i:endpos]) is None + + if not found: + # oh well ... settle for moving beyond the first chunk + # of non-whitespace chars + i = startpos + while str[i] not in " \t\n": + i = i+1 + + return len(str[self.stmt_start:i].expandtabs(\ + self.tabwidth)) + 1 + + # Return the leading whitespace on the initial line of the last + # interesting stmt. + + def get_base_indent_string(self): + self._study2() + i, n = self.stmt_start, self.stmt_end + j = i + str = self.str + while j < n and str[j] in " \t": + j = j + 1 + return str[i:j] + + # Did the last interesting stmt open a block? + + def is_block_opener(self): + self._study2() + return self.lastch == ':' + + # Did the last interesting stmt close a block? + + def is_block_closer(self): + self._study2() + return _closere(self.str, self.stmt_start) is not None + + # index of last open bracket ({[, or None if none + lastopenbracketpos = None + + def get_last_open_bracket_pos(self): + self._study2() + return self.lastopenbracketpos + + # the structure of the bracketing of the last interesting statement, + # in the format defined in _study2, or None if the text didn't contain + # anything + stmt_bracketing = None + + def get_last_stmt_bracketing(self): + self._study2() + return self.stmt_bracketing diff --git a/PythonHome/Lib/idlelib/PyParse.pyc b/PythonHome/Lib/idlelib/PyParse.pyc deleted file mode 100644 index d40b320400dc9672129020e382e1a9b91f1f0443..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 9749 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 Y#y3}MxQC8?wEYZf+p_T$7P&a>sys.__stderr__, "** IDLE can't import Tkinter. " \ + "Your Python may not be configured for Tk. **" + sys.exit(1) +import tkMessageBox + +from idlelib.EditorWindow import EditorWindow, fixwordbreaks +from idlelib.FileList import FileList +from idlelib.ColorDelegator import ColorDelegator +from idlelib.UndoDelegator import UndoDelegator +from idlelib.OutputWindow import OutputWindow +from idlelib.configHandler import idleConf +from idlelib import idlever +from idlelib import rpc +from idlelib import Debugger +from idlelib import RemoteDebugger +from idlelib import macosxSupport + +IDENTCHARS = string.ascii_letters + string.digits + "_" +HOST = '127.0.0.1' # python execution server on localhost loopback +PORT = 0 # someday pass in host, port for remote debug capability + +try: + from signal import SIGTERM +except ImportError: + SIGTERM = 15 + +# Override warnings module to write to warning_stream. Initialize to send IDLE +# internal warnings to the console. ScriptBinding.check_syntax() will +# temporarily redirect the stream to the shell window to display warnings when +# checking user's code. +warning_stream = sys.__stderr__ # None, at least on Windows, if no console. +import warnings + +def idle_formatwarning(message, category, filename, lineno, line=None): + """Format warnings the IDLE way.""" + + s = "\nWarning (from warnings module):\n" + s += ' File \"%s\", line %s\n' % (filename, lineno) + if line is None: + line = linecache.getline(filename, lineno) + line = line.strip() + if line: + s += " %s\n" % line + s += "%s: %s\n" % (category.__name__, message) + return s + +def idle_showwarning( + message, category, filename, lineno, file=None, line=None): + """Show Idle-format warning (after replacing warnings.showwarning). + + The differences are the formatter called, the file=None replacement, + which can be None, the capture of the consequence AttributeError, + and the output of a hard-coded prompt. + """ + if file is None: + file = warning_stream + try: + file.write(idle_formatwarning( + message, category, filename, lineno, line=line)) + file.write(">>> ") + except (AttributeError, IOError): + pass # if file (probably __stderr__) is invalid, skip warning. + +_warnings_showwarning = None + +def capture_warnings(capture): + "Replace warning.showwarning with idle_showwarning, or reverse." + + global _warnings_showwarning + if capture: + if _warnings_showwarning is None: + _warnings_showwarning = warnings.showwarning + warnings.showwarning = idle_showwarning + else: + if _warnings_showwarning is not None: + warnings.showwarning = _warnings_showwarning + _warnings_showwarning = None + +capture_warnings(True) + +def extended_linecache_checkcache(filename=None, + orig_checkcache=linecache.checkcache): + """Extend linecache.checkcache to preserve the entries + + Rather than repeating the linecache code, patch it to save the + entries, call the original linecache.checkcache() + (skipping them), and then restore the saved entries. + + orig_checkcache is bound at definition time to the original + method, allowing it to be patched. + """ + cache = linecache.cache + save = {} + for key in list(cache): + if key[:1] + key[-1:] == '<>': + save[key] = cache.pop(key) + orig_checkcache(filename) + cache.update(save) + +# Patch linecache.checkcache(): +linecache.checkcache = extended_linecache_checkcache + + +class PyShellEditorWindow(EditorWindow): + "Regular text edit window in IDLE, supports breakpoints" + + def __init__(self, *args): + self.breakpoints = [] + EditorWindow.__init__(self, *args) + self.text.bind("<>", self.set_breakpoint_here) + self.text.bind("<>", self.clear_breakpoint_here) + self.text.bind("<>", self.flist.open_shell) + + self.breakpointPath = os.path.join(idleConf.GetUserCfgDir(), + 'breakpoints.lst') + # whenever a file is changed, restore breakpoints + def filename_changed_hook(old_hook=self.io.filename_change_hook, + self=self): + self.restore_file_breaks() + old_hook() + self.io.set_filename_change_hook(filename_changed_hook) + if self.io.filename: + self.restore_file_breaks() + + rmenu_specs = [ + ("Cut", "<>", "rmenu_check_cut"), + ("Copy", "<>", "rmenu_check_copy"), + ("Paste", "<>", "rmenu_check_paste"), + ("Set Breakpoint", "<>", None), + ("Clear Breakpoint", "<>", None) + ] + + def set_breakpoint(self, lineno): + text = self.text + filename = self.io.filename + text.tag_add("BREAK", "%d.0" % lineno, "%d.0" % (lineno+1)) + try: + i = self.breakpoints.index(lineno) + except ValueError: # only add if missing, i.e. do once + self.breakpoints.append(lineno) + try: # update the subprocess debugger + debug = self.flist.pyshell.interp.debugger + debug.set_breakpoint_here(filename, lineno) + except: # but debugger may not be active right now.... + pass + + def set_breakpoint_here(self, event=None): + text = self.text + filename = self.io.filename + if not filename: + text.bell() + return + lineno = int(float(text.index("insert"))) + self.set_breakpoint(lineno) + + def clear_breakpoint_here(self, event=None): + text = self.text + filename = self.io.filename + if not filename: + text.bell() + return + lineno = int(float(text.index("insert"))) + try: + self.breakpoints.remove(lineno) + except: + pass + text.tag_remove("BREAK", "insert linestart",\ + "insert lineend +1char") + try: + debug = self.flist.pyshell.interp.debugger + debug.clear_breakpoint_here(filename, lineno) + except: + pass + + def clear_file_breaks(self): + if self.breakpoints: + text = self.text + filename = self.io.filename + if not filename: + text.bell() + return + self.breakpoints = [] + text.tag_remove("BREAK", "1.0", END) + try: + debug = self.flist.pyshell.interp.debugger + debug.clear_file_breaks(filename) + except: + pass + + def store_file_breaks(self): + "Save breakpoints when file is saved" + # XXX 13 Dec 2002 KBK Currently the file must be saved before it can + # be run. The breaks are saved at that time. If we introduce + # a temporary file save feature the save breaks functionality + # needs to be re-verified, since the breaks at the time the + # temp file is created may differ from the breaks at the last + # permanent save of the file. Currently, a break introduced + # after a save will be effective, but not persistent. + # This is necessary to keep the saved breaks synched with the + # saved file. + # + # Breakpoints are set as tagged ranges in the text. Certain + # kinds of edits cause these ranges to be deleted: Inserting + # or deleting a line just before a breakpoint, and certain + # deletions prior to a breakpoint. These issues need to be + # investigated and understood. It's not clear if they are + # Tk issues or IDLE issues, or whether they can actually + # be fixed. Since a modified file has to be saved before it is + # run, and since self.breakpoints (from which the subprocess + # debugger is loaded) is updated during the save, the visible + # breaks stay synched with the subprocess even if one of these + # unexpected breakpoint deletions occurs. + breaks = self.breakpoints + filename = self.io.filename + try: + with open(self.breakpointPath,"r") as old_file: + lines = old_file.readlines() + except IOError: + lines = [] + try: + with open(self.breakpointPath,"w") as new_file: + for line in lines: + if not line.startswith(filename + '='): + new_file.write(line) + self.update_breakpoints() + breaks = self.breakpoints + if breaks: + new_file.write(filename + '=' + str(breaks) + '\n') + except IOError as err: + if not getattr(self.root, "breakpoint_error_displayed", False): + self.root.breakpoint_error_displayed = True + tkMessageBox.showerror(title='IDLE Error', + message='Unable to update breakpoint list:\n%s' + % str(err), + parent=self.text) + + def restore_file_breaks(self): + self.text.update() # this enables setting "BREAK" tags to be visible + if self.io is None: + # can happen if IDLE closes due to the .update() call + return + filename = self.io.filename + if filename is None: + return + if os.path.isfile(self.breakpointPath): + lines = open(self.breakpointPath,"r").readlines() + for line in lines: + if line.startswith(filename + '='): + breakpoint_linenumbers = eval(line[len(filename)+1:]) + for breakpoint_linenumber in breakpoint_linenumbers: + self.set_breakpoint(breakpoint_linenumber) + + def update_breakpoints(self): + "Retrieves all the breakpoints in the current window" + text = self.text + ranges = text.tag_ranges("BREAK") + linenumber_list = self.ranges_to_linenumbers(ranges) + self.breakpoints = linenumber_list + + def ranges_to_linenumbers(self, ranges): + lines = [] + for index in range(0, len(ranges), 2): + lineno = int(float(ranges[index].string)) + end = int(float(ranges[index+1].string)) + while lineno < end: + lines.append(lineno) + lineno += 1 + return lines + +# XXX 13 Dec 2002 KBK Not used currently +# def saved_change_hook(self): +# "Extend base method - clear breaks if module is modified" +# if not self.get_saved(): +# self.clear_file_breaks() +# EditorWindow.saved_change_hook(self) + + def _close(self): + "Extend base method - clear breaks when module is closed" + self.clear_file_breaks() + EditorWindow._close(self) + + +class PyShellFileList(FileList): + "Extend base class: IDLE supports a shell and breakpoints" + + # override FileList's class variable, instances return PyShellEditorWindow + # instead of EditorWindow when new edit windows are created. + EditorWindow = PyShellEditorWindow + + pyshell = None + + def open_shell(self, event=None): + if self.pyshell: + self.pyshell.top.wakeup() + else: + self.pyshell = PyShell(self) + if self.pyshell: + if not self.pyshell.begin(): + return None + return self.pyshell + + +class ModifiedColorDelegator(ColorDelegator): + "Extend base class: colorizer for the shell window itself" + + def __init__(self): + ColorDelegator.__init__(self) + self.LoadTagDefs() + + def recolorize_main(self): + self.tag_remove("TODO", "1.0", "iomark") + self.tag_add("SYNC", "1.0", "iomark") + ColorDelegator.recolorize_main(self) + + def LoadTagDefs(self): + ColorDelegator.LoadTagDefs(self) + theme = idleConf.GetOption('main','Theme','name') + self.tagdefs.update({ + "stdin": {'background':None,'foreground':None}, + "stdout": idleConf.GetHighlight(theme, "stdout"), + "stderr": idleConf.GetHighlight(theme, "stderr"), + "console": idleConf.GetHighlight(theme, "console"), + }) + + def removecolors(self): + # Don't remove shell color tags before "iomark" + for tag in self.tagdefs: + self.tag_remove(tag, "iomark", "end") + +class ModifiedUndoDelegator(UndoDelegator): + "Extend base class: forbid insert/delete before the I/O mark" + + def insert(self, index, chars, tags=None): + try: + if self.delegate.compare(index, "<", "iomark"): + self.delegate.bell() + return + except TclError: + pass + UndoDelegator.insert(self, index, chars, tags) + + def delete(self, index1, index2=None): + try: + if self.delegate.compare(index1, "<", "iomark"): + self.delegate.bell() + return + except TclError: + pass + UndoDelegator.delete(self, index1, index2) + + +class MyRPCClient(rpc.RPCClient): + + def handle_EOF(self): + "Override the base class - just re-raise EOFError" + raise EOFError + + +class ModifiedInterpreter(InteractiveInterpreter): + + def __init__(self, tkconsole): + self.tkconsole = tkconsole + locals = sys.modules['__main__'].__dict__ + InteractiveInterpreter.__init__(self, locals=locals) + self.save_warnings_filters = None + self.restarting = False + self.subprocess_arglist = None + self.port = PORT + self.original_compiler_flags = self.compile.compiler.flags + + _afterid = None + rpcclt = None + rpcpid = None + + def spawn_subprocess(self): + if self.subprocess_arglist is None: + self.subprocess_arglist = self.build_subprocess_arglist() + args = self.subprocess_arglist + self.rpcpid = os.spawnv(os.P_NOWAIT, sys.executable, args) + + def build_subprocess_arglist(self): + assert (self.port!=0), ( + "Socket should have been assigned a port number.") + w = ['-W' + s for s in sys.warnoptions] + if 1/2 > 0: # account for new division + w.append('-Qnew') + # Maybe IDLE is installed and is being accessed via sys.path, + # or maybe it's not installed and the idle.py script is being + # run from the IDLE source directory. + del_exitf = idleConf.GetOption('main', 'General', 'delete-exitfunc', + default=False, type='bool') + if __name__ == 'idlelib.PyShell': + command = "__import__('idlelib.run').run.main(%r)" % (del_exitf,) + else: + command = "__import__('run').main(%r)" % (del_exitf,) + if sys.platform[:3] == 'win' and ' ' in sys.executable: + # handle embedded space in path by quoting the argument + decorated_exec = '"%s"' % sys.executable + else: + decorated_exec = sys.executable + return [decorated_exec] + w + ["-c", command, str(self.port)] + + def start_subprocess(self): + addr = (HOST, self.port) + # GUI makes several attempts to acquire socket, listens for connection + for i in range(3): + time.sleep(i) + try: + self.rpcclt = MyRPCClient(addr) + break + except socket.error as err: + pass + else: + self.display_port_binding_error() + return None + # if PORT was 0, system will assign an 'ephemeral' port. Find it out: + self.port = self.rpcclt.listening_sock.getsockname()[1] + # if PORT was not 0, probably working with a remote execution server + if PORT != 0: + # To allow reconnection within the 2MSL wait (cf. Stevens TCP + # V1, 18.6), set SO_REUSEADDR. Note that this can be problematic + # on Windows since the implementation allows two active sockets on + # the same address! + self.rpcclt.listening_sock.setsockopt(socket.SOL_SOCKET, + socket.SO_REUSEADDR, 1) + self.spawn_subprocess() + #time.sleep(20) # test to simulate GUI not accepting connection + # Accept the connection from the Python execution server + self.rpcclt.listening_sock.settimeout(10) + try: + self.rpcclt.accept() + except socket.timeout as err: + self.display_no_subprocess_error() + return None + self.rpcclt.register("console", self.tkconsole) + self.rpcclt.register("stdin", self.tkconsole.stdin) + self.rpcclt.register("stdout", self.tkconsole.stdout) + self.rpcclt.register("stderr", self.tkconsole.stderr) + self.rpcclt.register("flist", self.tkconsole.flist) + self.rpcclt.register("linecache", linecache) + self.rpcclt.register("interp", self) + self.transfer_path(with_cwd=True) + self.poll_subprocess() + return self.rpcclt + + def restart_subprocess(self, with_cwd=False): + if self.restarting: + return self.rpcclt + self.restarting = True + # close only the subprocess debugger + debug = self.getdebugger() + if debug: + try: + # Only close subprocess debugger, don't unregister gui_adap! + RemoteDebugger.close_subprocess_debugger(self.rpcclt) + except: + pass + # Kill subprocess, spawn a new one, accept connection. + self.rpcclt.close() + self.unix_terminate() + console = self.tkconsole + was_executing = console.executing + console.executing = False + self.spawn_subprocess() + try: + self.rpcclt.accept() + except socket.timeout as err: + self.display_no_subprocess_error() + return None + self.transfer_path(with_cwd=with_cwd) + console.stop_readline() + # annotate restart in shell window and mark it + console.text.delete("iomark", "end-1c") + if was_executing: + console.write('\n') + console.showprompt() + halfbar = ((int(console.width) - 16) // 2) * '=' + console.write(halfbar + ' RESTART ' + halfbar) + console.text.mark_set("restart", "end-1c") + console.text.mark_gravity("restart", "left") + console.showprompt() + # restart subprocess debugger + if debug: + # Restarted debugger connects to current instance of debug GUI + gui = RemoteDebugger.restart_subprocess_debugger(self.rpcclt) + # reload remote debugger breakpoints for all PyShellEditWindows + debug.load_breakpoints() + self.compile.compiler.flags = self.original_compiler_flags + self.restarting = False + return self.rpcclt + + def __request_interrupt(self): + self.rpcclt.remotecall("exec", "interrupt_the_server", (), {}) + + def interrupt_subprocess(self): + threading.Thread(target=self.__request_interrupt).start() + + def kill_subprocess(self): + if self._afterid is not None: + self.tkconsole.text.after_cancel(self._afterid) + try: + self.rpcclt.close() + except AttributeError: # no socket + pass + self.unix_terminate() + self.tkconsole.executing = False + self.rpcclt = None + + def unix_terminate(self): + "UNIX: make sure subprocess is terminated and collect status" + if hasattr(os, 'kill'): + try: + os.kill(self.rpcpid, SIGTERM) + except OSError: + # process already terminated: + return + else: + try: + os.waitpid(self.rpcpid, 0) + except OSError: + return + + def transfer_path(self, with_cwd=False): + if with_cwd: # Issue 13506 + path = [''] # include Current Working Directory + path.extend(sys.path) + else: + path = sys.path + + self.runcommand("""if 1: + import sys as _sys + _sys.path = %r + del _sys + \n""" % (path,)) + + active_seq = None + + def poll_subprocess(self): + clt = self.rpcclt + if clt is None: + return + try: + response = clt.pollresponse(self.active_seq, wait=0.05) + except (EOFError, IOError, KeyboardInterrupt): + # lost connection or subprocess terminated itself, restart + # [the KBI is from rpc.SocketIO.handle_EOF()] + if self.tkconsole.closing: + return + response = None + self.restart_subprocess() + if response: + self.tkconsole.resetoutput() + self.active_seq = None + how, what = response + console = self.tkconsole.console + if how == "OK": + if what is not None: + print >>console, repr(what) + elif how == "EXCEPTION": + if self.tkconsole.getvar("<>"): + self.remote_stack_viewer() + elif how == "ERROR": + errmsg = "PyShell.ModifiedInterpreter: Subprocess ERROR:\n" + print >>sys.__stderr__, errmsg, what + print >>console, errmsg, what + # we received a response to the currently active seq number: + try: + self.tkconsole.endexecuting() + except AttributeError: # shell may have closed + pass + # Reschedule myself + if not self.tkconsole.closing: + self._afterid = self.tkconsole.text.after( + self.tkconsole.pollinterval, self.poll_subprocess) + + debugger = None + + def setdebugger(self, debugger): + self.debugger = debugger + + def getdebugger(self): + return self.debugger + + def open_remote_stack_viewer(self): + """Initiate the remote stack viewer from a separate thread. + + This method is called from the subprocess, and by returning from this + method we allow the subprocess to unblock. After a bit the shell + requests the subprocess to open the remote stack viewer which returns a + static object looking at the last exception. It is queried through + the RPC mechanism. + + """ + self.tkconsole.text.after(300, self.remote_stack_viewer) + return + + def remote_stack_viewer(self): + from idlelib import RemoteObjectBrowser + oid = self.rpcclt.remotequeue("exec", "stackviewer", ("flist",), {}) + if oid is None: + self.tkconsole.root.bell() + return + item = RemoteObjectBrowser.StubObjectTreeItem(self.rpcclt, oid) + from idlelib.TreeWidget import ScrolledCanvas, TreeNode + top = Toplevel(self.tkconsole.root) + theme = idleConf.GetOption('main','Theme','name') + background = idleConf.GetHighlight(theme, 'normal')['background'] + sc = ScrolledCanvas(top, bg=background, highlightthickness=0) + sc.frame.pack(expand=1, fill="both") + node = TreeNode(sc.canvas, None, item) + node.expand() + # XXX Should GC the remote tree when closing the window + + gid = 0 + + def execsource(self, source): + "Like runsource() but assumes complete exec source" + filename = self.stuffsource(source) + self.execfile(filename, source) + + def execfile(self, filename, source=None): + "Execute an existing file" + if source is None: + source = open(filename, "r").read() + try: + code = compile(source, filename, "exec") + except (OverflowError, SyntaxError): + self.tkconsole.resetoutput() + tkerr = self.tkconsole.stderr + print>>tkerr, '*** Error in script or command!\n' + print>>tkerr, 'Traceback (most recent call last):' + InteractiveInterpreter.showsyntaxerror(self, filename) + self.tkconsole.showprompt() + else: + self.runcode(code) + + def runsource(self, source): + "Extend base class method: Stuff the source in the line cache first" + filename = self.stuffsource(source) + self.more = 0 + self.save_warnings_filters = warnings.filters[:] + warnings.filterwarnings(action="error", category=SyntaxWarning) + if isinstance(source, types.UnicodeType): + from idlelib import IOBinding + try: + source = source.encode(IOBinding.encoding) + except UnicodeError: + self.tkconsole.resetoutput() + self.write("Unsupported characters in input\n") + return + try: + # InteractiveInterpreter.runsource() calls its runcode() method, + # which is overridden (see below) + return InteractiveInterpreter.runsource(self, source, filename) + finally: + if self.save_warnings_filters is not None: + warnings.filters[:] = self.save_warnings_filters + self.save_warnings_filters = None + + def stuffsource(self, source): + "Stuff source in the filename cache" + filename = "" % self.gid + self.gid = self.gid + 1 + lines = source.split("\n") + linecache.cache[filename] = len(source)+1, 0, lines, filename + return filename + + def prepend_syspath(self, filename): + "Prepend sys.path with file's directory if not already included" + self.runcommand("""if 1: + _filename = %r + import sys as _sys + from os.path import dirname as _dirname + _dir = _dirname(_filename) + if not _dir in _sys.path: + _sys.path.insert(0, _dir) + del _filename, _sys, _dirname, _dir + \n""" % (filename,)) + + def showsyntaxerror(self, filename=None): + """Extend base class method: Add Colorizing + + Color the offending position instead of printing it and pointing at it + with a caret. + + """ + text = self.tkconsole.text + stuff = self.unpackerror() + if stuff: + msg, lineno, offset, line = stuff + if lineno == 1: + pos = "iomark + %d chars" % (offset-1) + else: + pos = "iomark linestart + %d lines + %d chars" % \ + (lineno-1, offset-1) + text.tag_add("ERROR", pos) + text.see(pos) + char = text.get(pos) + if char and char in IDENTCHARS: + text.tag_add("ERROR", pos + " wordstart", pos) + self.tkconsole.resetoutput() + self.write("SyntaxError: %s\n" % str(msg)) + else: + self.tkconsole.resetoutput() + InteractiveInterpreter.showsyntaxerror(self, filename) + self.tkconsole.showprompt() + + def unpackerror(self): + type, value, tb = sys.exc_info() + ok = type is SyntaxError + if ok: + try: + msg, (dummy_filename, lineno, offset, line) = value + if not offset: + offset = 0 + except: + ok = 0 + if ok: + return msg, lineno, offset, line + else: + return None + + def showtraceback(self): + "Extend base class method to reset output properly" + self.tkconsole.resetoutput() + self.checklinecache() + InteractiveInterpreter.showtraceback(self) + if self.tkconsole.getvar("<>"): + self.tkconsole.open_stack_viewer() + + def checklinecache(self): + c = linecache.cache + for key in c.keys(): + if key[:1] + key[-1:] != "<>": + del c[key] + + def runcommand(self, code): + "Run the code without invoking the debugger" + # The code better not raise an exception! + if self.tkconsole.executing: + self.display_executing_dialog() + return 0 + if self.rpcclt: + self.rpcclt.remotequeue("exec", "runcode", (code,), {}) + else: + exec code in self.locals + return 1 + + def runcode(self, code): + "Override base class method" + if self.tkconsole.executing: + self.interp.restart_subprocess() + self.checklinecache() + if self.save_warnings_filters is not None: + warnings.filters[:] = self.save_warnings_filters + self.save_warnings_filters = None + debugger = self.debugger + try: + self.tkconsole.beginexecuting() + if not debugger and self.rpcclt is not None: + self.active_seq = self.rpcclt.asyncqueue("exec", "runcode", + (code,), {}) + elif debugger: + debugger.run(code, self.locals) + else: + exec code in self.locals + except SystemExit: + if not self.tkconsole.closing: + if tkMessageBox.askyesno( + "Exit?", + "Do you want to exit altogether?", + default="yes", + master=self.tkconsole.text): + raise + else: + self.showtraceback() + else: + raise + except: + if use_subprocess: + print >>self.tkconsole.stderr, \ + "IDLE internal error in runcode()" + self.showtraceback() + self.tkconsole.endexecuting() + else: + if self.tkconsole.canceled: + self.tkconsole.canceled = False + print >>self.tkconsole.stderr, "KeyboardInterrupt" + else: + self.showtraceback() + finally: + if not use_subprocess: + try: + self.tkconsole.endexecuting() + except AttributeError: # shell may have closed + pass + + def write(self, s): + "Override base class method" + self.tkconsole.stderr.write(s) + + def display_port_binding_error(self): + tkMessageBox.showerror( + "Port Binding Error", + "IDLE can't bind to a TCP/IP port, which is necessary to " + "communicate with its Python execution server. This might be " + "because no networking is installed on this computer. " + "Run IDLE with the -n command line switch to start without a " + "subprocess and refer to Help/IDLE Help 'Running without a " + "subprocess' for further details.", + master=self.tkconsole.text) + + def display_no_subprocess_error(self): + tkMessageBox.showerror( + "Subprocess Startup Error", + "IDLE's subprocess didn't make connection. Either IDLE can't " + "start a subprocess or personal firewall software is blocking " + "the connection.", + master=self.tkconsole.text) + + def display_executing_dialog(self): + tkMessageBox.showerror( + "Already executing", + "The Python Shell window is already executing a command; " + "please wait until it is finished.", + master=self.tkconsole.text) + + +class PyShell(OutputWindow): + + shell_title = "Python " + python_version() + " Shell" + + # Override classes + ColorDelegator = ModifiedColorDelegator + UndoDelegator = ModifiedUndoDelegator + + # Override menus + menu_specs = [ + ("file", "_File"), + ("edit", "_Edit"), + ("debug", "_Debug"), + ("options", "_Options"), + ("windows", "_Windows"), + ("help", "_Help"), + ] + + if sys.platform == "darwin": + menu_specs[-2] = ("windows", "_Window") + + + # New classes + from idlelib.IdleHistory import History + + def __init__(self, flist=None): + if use_subprocess: + ms = self.menu_specs + if ms[2][0] != "shell": + ms.insert(2, ("shell", "She_ll")) + self.interp = ModifiedInterpreter(self) + if flist is None: + root = Tk() + fixwordbreaks(root) + root.withdraw() + flist = PyShellFileList(root) + # + OutputWindow.__init__(self, flist, None, None) + # +## self.config(usetabs=1, indentwidth=8, context_use_ps1=1) + self.usetabs = True + # indentwidth must be 8 when using tabs. See note in EditorWindow: + self.indentwidth = 8 + self.context_use_ps1 = True + # + text = self.text + text.configure(wrap="char") + text.bind("<>", self.enter_callback) + text.bind("<>", self.linefeed_callback) + text.bind("<>", self.cancel_callback) + text.bind("<>", self.eof_callback) + text.bind("<>", self.open_stack_viewer) + text.bind("<>", self.toggle_debugger) + text.bind("<>", self.toggle_jit_stack_viewer) + if use_subprocess: + text.bind("<>", self.view_restart_mark) + text.bind("<>", self.restart_shell) + # + self.save_stdout = sys.stdout + self.save_stderr = sys.stderr + self.save_stdin = sys.stdin + from idlelib import IOBinding + self.stdin = PseudoInputFile(self, "stdin", IOBinding.encoding) + self.stdout = PseudoOutputFile(self, "stdout", IOBinding.encoding) + self.stderr = PseudoOutputFile(self, "stderr", IOBinding.encoding) + self.console = PseudoOutputFile(self, "console", IOBinding.encoding) + if not use_subprocess: + sys.stdout = self.stdout + sys.stderr = self.stderr + sys.stdin = self.stdin + # + self.history = self.History(self.text) + # + self.pollinterval = 50 # millisec + + def get_standard_extension_names(self): + return idleConf.GetExtensions(shell_only=True) + + reading = False + executing = False + canceled = False + endoffile = False + closing = False + _stop_readline_flag = False + + def set_warning_stream(self, stream): + global warning_stream + warning_stream = stream + + def get_warning_stream(self): + return warning_stream + + def toggle_debugger(self, event=None): + if self.executing: + tkMessageBox.showerror("Don't debug now", + "You can only toggle the debugger when idle", + master=self.text) + self.set_debugger_indicator() + return "break" + else: + db = self.interp.getdebugger() + if db: + self.close_debugger() + else: + self.open_debugger() + + def set_debugger_indicator(self): + db = self.interp.getdebugger() + self.setvar("<>", not not db) + + def toggle_jit_stack_viewer(self, event=None): + pass # All we need is the variable + + def close_debugger(self): + db = self.interp.getdebugger() + if db: + self.interp.setdebugger(None) + db.close() + if self.interp.rpcclt: + RemoteDebugger.close_remote_debugger(self.interp.rpcclt) + self.resetoutput() + self.console.write("[DEBUG OFF]\n") + sys.ps1 = ">>> " + self.showprompt() + self.set_debugger_indicator() + + def open_debugger(self): + if self.interp.rpcclt: + dbg_gui = RemoteDebugger.start_remote_debugger(self.interp.rpcclt, + self) + else: + dbg_gui = Debugger.Debugger(self) + self.interp.setdebugger(dbg_gui) + dbg_gui.load_breakpoints() + sys.ps1 = "[DEBUG ON]\n>>> " + self.showprompt() + self.set_debugger_indicator() + + def beginexecuting(self): + "Helper for ModifiedInterpreter" + self.resetoutput() + self.executing = 1 + + def endexecuting(self): + "Helper for ModifiedInterpreter" + self.executing = 0 + self.canceled = 0 + self.showprompt() + + def close(self): + "Extend EditorWindow.close()" + if self.executing: + response = tkMessageBox.askokcancel( + "Kill?", + "The program is still running!\n Do you want to kill it?", + default="ok", + parent=self.text) + if response is False: + return "cancel" + self.stop_readline() + self.canceled = True + self.closing = True + return EditorWindow.close(self) + + def _close(self): + "Extend EditorWindow._close(), shut down debugger and execution server" + self.close_debugger() + if use_subprocess: + self.interp.kill_subprocess() + # Restore std streams + sys.stdout = self.save_stdout + sys.stderr = self.save_stderr + sys.stdin = self.save_stdin + # Break cycles + self.interp = None + self.console = None + self.flist.pyshell = None + self.history = None + EditorWindow._close(self) + + def ispythonsource(self, filename): + "Override EditorWindow method: never remove the colorizer" + return True + + def short_title(self): + return self.shell_title + + COPYRIGHT = \ + 'Type "copyright", "credits" or "license()" for more information.' + + def begin(self): + self.resetoutput() + if use_subprocess: + nosub = '' + client = self.interp.start_subprocess() + if not client: + self.close() + return False + else: + nosub = "==== No Subprocess ====" + self.write("Python %s on %s\n%s\n%s" % + (sys.version, sys.platform, self.COPYRIGHT, nosub)) + self.showprompt() + import Tkinter + Tkinter._default_root = None # 03Jan04 KBK What's this? + return True + + def stop_readline(self): + if not self.reading: # no nested mainloop to exit. + return + self._stop_readline_flag = True + self.top.quit() + + def readline(self): + save = self.reading + try: + self.reading = 1 + self.top.mainloop() # nested mainloop() + finally: + self.reading = save + if self._stop_readline_flag: + self._stop_readline_flag = False + return "" + line = self.text.get("iomark", "end-1c") + if len(line) == 0: # may be EOF if we quit our mainloop with Ctrl-C + line = "\n" + if isinstance(line, unicode): + from idlelib import IOBinding + try: + line = line.encode(IOBinding.encoding) + except UnicodeError: + pass + self.resetoutput() + if self.canceled: + self.canceled = 0 + if not use_subprocess: + raise KeyboardInterrupt + if self.endoffile: + self.endoffile = 0 + line = "" + return line + + def isatty(self): + return True + + def cancel_callback(self, event=None): + try: + if self.text.compare("sel.first", "!=", "sel.last"): + return # Active selection -- always use default binding + except: + pass + if not (self.executing or self.reading): + self.resetoutput() + self.interp.write("KeyboardInterrupt\n") + self.showprompt() + return "break" + self.endoffile = 0 + self.canceled = 1 + if (self.executing and self.interp.rpcclt): + if self.interp.getdebugger(): + self.interp.restart_subprocess() + else: + self.interp.interrupt_subprocess() + if self.reading: + self.top.quit() # exit the nested mainloop() in readline() + return "break" + + def eof_callback(self, event): + if self.executing and not self.reading: + return # Let the default binding (delete next char) take over + if not (self.text.compare("iomark", "==", "insert") and + self.text.compare("insert", "==", "end-1c")): + return # Let the default binding (delete next char) take over + if not self.executing: + self.resetoutput() + self.close() + else: + self.canceled = 0 + self.endoffile = 1 + self.top.quit() + return "break" + + def linefeed_callback(self, event): + # Insert a linefeed without entering anything (still autoindented) + if self.reading: + self.text.insert("insert", "\n") + self.text.see("insert") + else: + self.newline_and_indent_event(event) + return "break" + + def enter_callback(self, event): + if self.executing and not self.reading: + return # Let the default binding (insert '\n') take over + # If some text is selected, recall the selection + # (but only if this before the I/O mark) + try: + sel = self.text.get("sel.first", "sel.last") + if sel: + if self.text.compare("sel.last", "<=", "iomark"): + self.recall(sel, event) + return "break" + except: + pass + # If we're strictly before the line containing iomark, recall + # the current line, less a leading prompt, less leading or + # trailing whitespace + if self.text.compare("insert", "<", "iomark linestart"): + # Check if there's a relevant stdin range -- if so, use it + prev = self.text.tag_prevrange("stdin", "insert") + if prev and self.text.compare("insert", "<", prev[1]): + self.recall(self.text.get(prev[0], prev[1]), event) + return "break" + next = self.text.tag_nextrange("stdin", "insert") + if next and self.text.compare("insert lineend", ">=", next[0]): + self.recall(self.text.get(next[0], next[1]), event) + return "break" + # No stdin mark -- just get the current line, less any prompt + indices = self.text.tag_nextrange("console", "insert linestart") + if indices and \ + self.text.compare(indices[0], "<=", "insert linestart"): + self.recall(self.text.get(indices[1], "insert lineend"), event) + else: + self.recall(self.text.get("insert linestart", "insert lineend"), event) + return "break" + # If we're between the beginning of the line and the iomark, i.e. + # in the prompt area, move to the end of the prompt + if self.text.compare("insert", "<", "iomark"): + self.text.mark_set("insert", "iomark") + # If we're in the current input and there's only whitespace + # beyond the cursor, erase that whitespace first + s = self.text.get("insert", "end-1c") + if s and not s.strip(): + self.text.delete("insert", "end-1c") + # If we're in the current input before its last line, + # insert a newline right at the insert point + if self.text.compare("insert", "<", "end-1c linestart"): + self.newline_and_indent_event(event) + return "break" + # We're in the last line; append a newline and submit it + self.text.mark_set("insert", "end-1c") + if self.reading: + self.text.insert("insert", "\n") + self.text.see("insert") + else: + self.newline_and_indent_event(event) + self.text.tag_add("stdin", "iomark", "end-1c") + self.text.update_idletasks() + if self.reading: + self.top.quit() # Break out of recursive mainloop() in raw_input() + else: + self.runit() + return "break" + + def recall(self, s, event): + # remove leading and trailing empty or whitespace lines + s = re.sub(r'^\s*\n', '' , s) + s = re.sub(r'\n\s*$', '', s) + lines = s.split('\n') + self.text.undo_block_start() + try: + self.text.tag_remove("sel", "1.0", "end") + self.text.mark_set("insert", "end-1c") + prefix = self.text.get("insert linestart", "insert") + if prefix.rstrip().endswith(':'): + self.newline_and_indent_event(event) + prefix = self.text.get("insert linestart", "insert") + self.text.insert("insert", lines[0].strip()) + if len(lines) > 1: + orig_base_indent = re.search(r'^([ \t]*)', lines[0]).group(0) + new_base_indent = re.search(r'^([ \t]*)', prefix).group(0) + for line in lines[1:]: + if line.startswith(orig_base_indent): + # replace orig base indentation with new indentation + line = new_base_indent + line[len(orig_base_indent):] + self.text.insert('insert', '\n'+line.rstrip()) + finally: + self.text.see("insert") + self.text.undo_block_stop() + + def runit(self): + line = self.text.get("iomark", "end-1c") + # Strip off last newline and surrounding whitespace. + # (To allow you to hit return twice to end a statement.) + i = len(line) + while i > 0 and line[i-1] in " \t": + i = i-1 + if i > 0 and line[i-1] == "\n": + i = i-1 + while i > 0 and line[i-1] in " \t": + i = i-1 + line = line[:i] + more = self.interp.runsource(line) + + def open_stack_viewer(self, event=None): + if self.interp.rpcclt: + return self.interp.remote_stack_viewer() + try: + sys.last_traceback + except: + tkMessageBox.showerror("No stack trace", + "There is no stack trace yet.\n" + "(sys.last_traceback is not defined)", + master=self.text) + return + from idlelib.StackViewer import StackBrowser + sv = StackBrowser(self.root, self.flist) + + def view_restart_mark(self, event=None): + self.text.see("iomark") + self.text.see("restart") + + def restart_shell(self, event=None): + "Callback for Run/Restart Shell Cntl-F6" + self.interp.restart_subprocess(with_cwd=True) + + def showprompt(self): + self.resetoutput() + try: + s = str(sys.ps1) + except: + s = "" + self.console.write(s) + self.text.mark_set("insert", "end-1c") + self.set_line_and_column() + self.io.reset_undo() + + def resetoutput(self): + source = self.text.get("iomark", "end-1c") + if self.history: + self.history.store(source) + if self.text.get("end-2c") != "\n": + self.text.insert("end-1c", "\n") + self.text.mark_set("iomark", "end-1c") + self.set_line_and_column() + sys.stdout.softspace = 0 + + def write(self, s, tags=()): + try: + self.text.mark_gravity("iomark", "right") + OutputWindow.write(self, s, tags, "iomark") + self.text.mark_gravity("iomark", "left") + except: + pass + if self.canceled: + self.canceled = 0 + if not use_subprocess: + raise KeyboardInterrupt + + def rmenu_check_cut(self): + try: + if self.text.compare('sel.first', '<', 'iomark'): + return 'disabled' + except TclError: # no selection, so the index 'sel.first' doesn't exist + return 'disabled' + return super(PyShell, self).rmenu_check_cut() + + def rmenu_check_paste(self): + if self.text.compare('insert', '<', 'iomark'): + return 'disabled' + return super(PyShell, self).rmenu_check_paste() + +class PseudoFile(io.TextIOBase): + + def __init__(self, shell, tags, encoding=None): + self.shell = shell + self.tags = tags + self.softspace = 0 + self._encoding = encoding + + @property + def encoding(self): + return self._encoding + + @property + def name(self): + return '<%s>' % self.tags + + def isatty(self): + return True + + +class PseudoOutputFile(PseudoFile): + + def writable(self): + return True + + def write(self, s): + if self.closed: + raise ValueError("write to closed file") + if type(s) not in (unicode, str, bytearray): + # See issue #19481 + if isinstance(s, unicode): + s = unicode.__getslice__(s, None, None) + elif isinstance(s, str): + s = str.__str__(s) + elif isinstance(s, bytearray): + s = bytearray.__str__(s) + else: + raise TypeError('must be string, not ' + type(s).__name__) + return self.shell.write(s, self.tags) + + +class PseudoInputFile(PseudoFile): + + def __init__(self, shell, tags, encoding=None): + PseudoFile.__init__(self, shell, tags, encoding) + self._line_buffer = '' + + def readable(self): + return True + + def read(self, size=-1): + if self.closed: + raise ValueError("read from closed file") + if size is None: + size = -1 + elif not isinstance(size, int): + raise TypeError('must be int, not ' + type(size).__name__) + result = self._line_buffer + self._line_buffer = '' + if size < 0: + while True: + line = self.shell.readline() + if not line: break + result += line + else: + while len(result) < size: + line = self.shell.readline() + if not line: break + result += line + self._line_buffer = result[size:] + result = result[:size] + return result + + def readline(self, size=-1): + if self.closed: + raise ValueError("read from closed file") + if size is None: + size = -1 + elif not isinstance(size, int): + raise TypeError('must be int, not ' + type(size).__name__) + line = self._line_buffer or self.shell.readline() + if size < 0: + size = len(line) + eol = line.find('\n', 0, size) + if eol >= 0: + size = eol + 1 + self._line_buffer = line[size:] + return line[:size] + + def close(self): + self.shell.close() + + +usage_msg = """\ + +USAGE: idle [-deins] [-t title] [file]* + idle [-dns] [-t title] (-c cmd | -r file) [arg]* + idle [-dns] [-t title] - [arg]* + + -h print this help message and exit + -n run IDLE without a subprocess (see Help/IDLE Help for details) + +The following options will override the IDLE 'settings' configuration: + + -e open an edit window + -i open a shell window + +The following options imply -i and will open a shell: + + -c cmd run the command in a shell, or + -r file run script from file + + -d enable the debugger + -s run $IDLESTARTUP or $PYTHONSTARTUP before anything else + -t title set title of shell window + +A default edit window will be bypassed when -c, -r, or - are used. + +[arg]* are passed to the command (-c) or script (-r) in sys.argv[1:]. + +Examples: + +idle + Open an edit window or shell depending on IDLE's configuration. + +idle foo.py foobar.py + Edit the files, also open a shell if configured to start with shell. + +idle -est "Baz" foo.py + Run $IDLESTARTUP or $PYTHONSTARTUP, edit foo.py, and open a shell + window with the title "Baz". + +idle -c "import sys; print sys.argv" "foo" + Open a shell window and run the command, passing "-c" in sys.argv[0] + and "foo" in sys.argv[1]. + +idle -d -s -r foo.py "Hello World" + Open a shell window, run a startup script, enable the debugger, and + run foo.py, passing "foo.py" in sys.argv[0] and "Hello World" in + sys.argv[1]. + +echo "import sys; print sys.argv" | idle - "foobar" + Open a shell window, run the script piped in, passing '' in sys.argv[0] + and "foobar" in sys.argv[1]. +""" + +def main(): + global flist, root, use_subprocess + + capture_warnings(True) + use_subprocess = True + enable_shell = False + enable_edit = False + debug = False + cmd = None + script = None + startup = False + try: + opts, args = getopt.getopt(sys.argv[1:], "c:deihnr:st:") + except getopt.error as msg: + sys.stderr.write("Error: %s\n" % str(msg)) + sys.stderr.write(usage_msg) + sys.exit(2) + for o, a in opts: + if o == '-c': + cmd = a + enable_shell = True + if o == '-d': + debug = True + enable_shell = True + if o == '-e': + enable_edit = True + if o == '-h': + sys.stdout.write(usage_msg) + sys.exit() + if o == '-i': + enable_shell = True + if o == '-n': + use_subprocess = False + if o == '-r': + script = a + if os.path.isfile(script): + pass + else: + print "No script file: ", script + sys.exit() + enable_shell = True + if o == '-s': + startup = True + enable_shell = True + if o == '-t': + PyShell.shell_title = a + enable_shell = True + if args and args[0] == '-': + cmd = sys.stdin.read() + enable_shell = True + # process sys.argv and sys.path: + for i in range(len(sys.path)): + sys.path[i] = os.path.abspath(sys.path[i]) + if args and args[0] == '-': + sys.argv = [''] + args[1:] + elif cmd: + sys.argv = ['-c'] + args + elif script: + sys.argv = [script] + args + elif args: + enable_edit = True + pathx = [] + for filename in args: + pathx.append(os.path.dirname(filename)) + for dir in pathx: + dir = os.path.abspath(dir) + if dir not in sys.path: + sys.path.insert(0, dir) + else: + dir = os.getcwd() + if not dir in sys.path: + sys.path.insert(0, dir) + # check the IDLE settings configuration (but command line overrides) + edit_start = idleConf.GetOption('main', 'General', + 'editor-on-startup', type='bool') + enable_edit = enable_edit or edit_start + enable_shell = enable_shell or not enable_edit + # start editor and/or shell windows: + root = Tk(className="Idle") + + # set application icon + icondir = os.path.join(os.path.dirname(__file__), 'Icons') + if system() == 'Windows': + iconfile = os.path.join(icondir, 'idle.ico') + root.wm_iconbitmap(default=iconfile) + elif TkVersion >= 8.5: + ext = '.png' if TkVersion >= 8.6 else '.gif' + iconfiles = [os.path.join(icondir, 'idle_%d%s' % (size, ext)) + for size in (16, 32, 48)] + icons = [PhotoImage(file=iconfile) for iconfile in iconfiles] + root.tk.call('wm', 'iconphoto', str(root), "-default", *icons) + + fixwordbreaks(root) + root.withdraw() + flist = PyShellFileList(root) + macosxSupport.setupApp(root, flist) + + if enable_edit: + if not (cmd or script): + for filename in args[:]: + if flist.open(filename) is None: + # filename is a directory actually, disconsider it + args.remove(filename) + if not args: + flist.new() + + if enable_shell: + shell = flist.open_shell() + if not shell: + return # couldn't open shell + if macosxSupport.isAquaTk() and flist.dict: + # On OSX: when the user has double-clicked on a file that causes + # IDLE to be launched the shell window will open just in front of + # the file she wants to see. Lower the interpreter window when + # there are open files. + shell.top.lower() + else: + shell = flist.pyshell + + # Handle remaining options. If any of these are set, enable_shell + # was set also, so shell must be true to reach here. + if debug: + shell.open_debugger() + if startup: + filename = os.environ.get("IDLESTARTUP") or \ + os.environ.get("PYTHONSTARTUP") + if filename and os.path.isfile(filename): + shell.interp.execfile(filename) + if cmd or script: + shell.interp.runcommand("""if 1: + import sys as _sys + _sys.argv = %r + del _sys + \n""" % (sys.argv,)) + if cmd: + shell.interp.execsource(cmd) + elif script: + shell.interp.prepend_syspath(script) + shell.interp.execfile(script) + elif shell: + # If there is a shell window and no cmd or script in progress, + # check for problematic OS X Tk versions and print a warning + # message in the IDLE shell window; this is less intrusive + # than always opening a separate window. + tkversionwarning = macosxSupport.tkVersionWarning(root) + if tkversionwarning: + shell.interp.runcommand("print('%s')" % tkversionwarning) + + while flist.inversedict: # keep IDLE running while files are open. + root.mainloop() + root.destroy() + capture_warnings(False) + +if __name__ == "__main__": + sys.modules['PyShell'] = sys.modules['__main__'] + main() + +capture_warnings(False) # Make sure turned off; see issue 18081 diff --git a/PythonHome/Lib/idlelib/PyShell.pyc b/PythonHome/Lib/idlelib/PyShell.pyc deleted file mode 100644 index 167b5742f1eb580c6b06be093280f46ee41ba700..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 50039 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 a_1DSo@cWIuJ9h2dHBXuEoZ!9jq5mKJXVXCd diff --git a/PythonHome/Lib/idlelib/RemoteDebugger.py b/PythonHome/Lib/idlelib/RemoteDebugger.py new file mode 100644 index 0000000000..647285fe4e --- /dev/null +++ b/PythonHome/Lib/idlelib/RemoteDebugger.py @@ -0,0 +1,380 @@ +"""Support for remote Python debugging. + +Some ASCII art to describe the structure: + + IN PYTHON SUBPROCESS # IN IDLE PROCESS + # + # oid='gui_adapter' + +----------+ # +------------+ +-----+ + | GUIProxy |--remote#call-->| GUIAdapter |--calls-->| GUI | ++-----+--calls-->+----------+ # +------------+ +-----+ +| Idb | # / ++-----+<-calls--+------------+ # +----------+<--calls-/ + | IdbAdapter |<--remote#call--| IdbProxy | + +------------+ # +----------+ + oid='idb_adapter' # + +The purpose of the Proxy and Adapter classes is to translate certain +arguments and return values that cannot be transported through the RPC +barrier, in particular frame and traceback objects. + +""" + +import types +from idlelib import rpc +from idlelib import Debugger + +debugging = 0 + +idb_adap_oid = "idb_adapter" +gui_adap_oid = "gui_adapter" + +#======================================= +# +# In the PYTHON subprocess: + +frametable = {} +dicttable = {} +codetable = {} +tracebacktable = {} + +def wrap_frame(frame): + fid = id(frame) + frametable[fid] = frame + return fid + +def wrap_info(info): + "replace info[2], a traceback instance, by its ID" + if info is None: + return None + else: + traceback = info[2] + assert isinstance(traceback, types.TracebackType) + traceback_id = id(traceback) + tracebacktable[traceback_id] = traceback + modified_info = (info[0], info[1], traceback_id) + return modified_info + +class GUIProxy: + + def __init__(self, conn, gui_adap_oid): + self.conn = conn + self.oid = gui_adap_oid + + def interaction(self, message, frame, info=None): + # calls rpc.SocketIO.remotecall() via run.MyHandler instance + # pass frame and traceback object IDs instead of the objects themselves + self.conn.remotecall(self.oid, "interaction", + (message, wrap_frame(frame), wrap_info(info)), + {}) + +class IdbAdapter: + + def __init__(self, idb): + self.idb = idb + + #----------called by an IdbProxy---------- + + def set_step(self): + self.idb.set_step() + + def set_quit(self): + self.idb.set_quit() + + def set_continue(self): + self.idb.set_continue() + + def set_next(self, fid): + frame = frametable[fid] + self.idb.set_next(frame) + + def set_return(self, fid): + frame = frametable[fid] + self.idb.set_return(frame) + + def get_stack(self, fid, tbid): + ##print >>sys.__stderr__, "get_stack(%r, %r)" % (fid, tbid) + frame = frametable[fid] + if tbid is None: + tb = None + else: + tb = tracebacktable[tbid] + stack, i = self.idb.get_stack(frame, tb) + ##print >>sys.__stderr__, "get_stack() ->", stack + stack = [(wrap_frame(frame), k) for frame, k in stack] + ##print >>sys.__stderr__, "get_stack() ->", stack + return stack, i + + def run(self, cmd): + import __main__ + self.idb.run(cmd, __main__.__dict__) + + def set_break(self, filename, lineno): + msg = self.idb.set_break(filename, lineno) + return msg + + def clear_break(self, filename, lineno): + msg = self.idb.clear_break(filename, lineno) + return msg + + def clear_all_file_breaks(self, filename): + msg = self.idb.clear_all_file_breaks(filename) + return msg + + #----------called by a FrameProxy---------- + + def frame_attr(self, fid, name): + frame = frametable[fid] + return getattr(frame, name) + + def frame_globals(self, fid): + frame = frametable[fid] + dict = frame.f_globals + did = id(dict) + dicttable[did] = dict + return did + + def frame_locals(self, fid): + frame = frametable[fid] + dict = frame.f_locals + did = id(dict) + dicttable[did] = dict + return did + + def frame_code(self, fid): + frame = frametable[fid] + code = frame.f_code + cid = id(code) + codetable[cid] = code + return cid + + #----------called by a CodeProxy---------- + + def code_name(self, cid): + code = codetable[cid] + return code.co_name + + def code_filename(self, cid): + code = codetable[cid] + return code.co_filename + + #----------called by a DictProxy---------- + + def dict_keys(self, did): + dict = dicttable[did] + return dict.keys() + + def dict_item(self, did, key): + dict = dicttable[did] + value = dict[key] + value = repr(value) + return value + +#----------end class IdbAdapter---------- + + +def start_debugger(rpchandler, gui_adap_oid): + """Start the debugger and its RPC link in the Python subprocess + + Start the subprocess side of the split debugger and set up that side of the + RPC link by instantiating the GUIProxy, Idb debugger, and IdbAdapter + objects and linking them together. Register the IdbAdapter with the + RPCServer to handle RPC requests from the split debugger GUI via the + IdbProxy. + + """ + gui_proxy = GUIProxy(rpchandler, gui_adap_oid) + idb = Debugger.Idb(gui_proxy) + idb_adap = IdbAdapter(idb) + rpchandler.register(idb_adap_oid, idb_adap) + return idb_adap_oid + + +#======================================= +# +# In the IDLE process: + + +class FrameProxy: + + def __init__(self, conn, fid): + self._conn = conn + self._fid = fid + self._oid = "idb_adapter" + self._dictcache = {} + + def __getattr__(self, name): + if name[:1] == "_": + raise AttributeError, name + if name == "f_code": + return self._get_f_code() + if name == "f_globals": + return self._get_f_globals() + if name == "f_locals": + return self._get_f_locals() + return self._conn.remotecall(self._oid, "frame_attr", + (self._fid, name), {}) + + def _get_f_code(self): + cid = self._conn.remotecall(self._oid, "frame_code", (self._fid,), {}) + return CodeProxy(self._conn, self._oid, cid) + + def _get_f_globals(self): + did = self._conn.remotecall(self._oid, "frame_globals", + (self._fid,), {}) + return self._get_dict_proxy(did) + + def _get_f_locals(self): + did = self._conn.remotecall(self._oid, "frame_locals", + (self._fid,), {}) + return self._get_dict_proxy(did) + + def _get_dict_proxy(self, did): + if did in self._dictcache: + return self._dictcache[did] + dp = DictProxy(self._conn, self._oid, did) + self._dictcache[did] = dp + return dp + + +class CodeProxy: + + def __init__(self, conn, oid, cid): + self._conn = conn + self._oid = oid + self._cid = cid + + def __getattr__(self, name): + if name == "co_name": + return self._conn.remotecall(self._oid, "code_name", + (self._cid,), {}) + if name == "co_filename": + return self._conn.remotecall(self._oid, "code_filename", + (self._cid,), {}) + + +class DictProxy: + + def __init__(self, conn, oid, did): + self._conn = conn + self._oid = oid + self._did = did + + def keys(self): + return self._conn.remotecall(self._oid, "dict_keys", (self._did,), {}) + + def __getitem__(self, key): + return self._conn.remotecall(self._oid, "dict_item", + (self._did, key), {}) + + def __getattr__(self, name): + ##print >>sys.__stderr__, "failed DictProxy.__getattr__:", name + raise AttributeError, name + + +class GUIAdapter: + + def __init__(self, conn, gui): + self.conn = conn + self.gui = gui + + def interaction(self, message, fid, modified_info): + ##print "interaction: (%s, %s, %s)" % (message, fid, modified_info) + frame = FrameProxy(self.conn, fid) + self.gui.interaction(message, frame, modified_info) + + +class IdbProxy: + + def __init__(self, conn, shell, oid): + self.oid = oid + self.conn = conn + self.shell = shell + + def call(self, methodname, *args, **kwargs): + ##print "**IdbProxy.call %s %s %s" % (methodname, args, kwargs) + value = self.conn.remotecall(self.oid, methodname, args, kwargs) + ##print "**IdbProxy.call %s returns %r" % (methodname, value) + return value + + def run(self, cmd, locals): + # Ignores locals on purpose! + seq = self.conn.asyncqueue(self.oid, "run", (cmd,), {}) + self.shell.interp.active_seq = seq + + def get_stack(self, frame, tbid): + # passing frame and traceback IDs, not the objects themselves + stack, i = self.call("get_stack", frame._fid, tbid) + stack = [(FrameProxy(self.conn, fid), k) for fid, k in stack] + return stack, i + + def set_continue(self): + self.call("set_continue") + + def set_step(self): + self.call("set_step") + + def set_next(self, frame): + self.call("set_next", frame._fid) + + def set_return(self, frame): + self.call("set_return", frame._fid) + + def set_quit(self): + self.call("set_quit") + + def set_break(self, filename, lineno): + msg = self.call("set_break", filename, lineno) + return msg + + def clear_break(self, filename, lineno): + msg = self.call("clear_break", filename, lineno) + return msg + + def clear_all_file_breaks(self, filename): + msg = self.call("clear_all_file_breaks", filename) + return msg + +def start_remote_debugger(rpcclt, pyshell): + """Start the subprocess debugger, initialize the debugger GUI and RPC link + + Request the RPCServer start the Python subprocess debugger and link. Set + up the Idle side of the split debugger by instantiating the IdbProxy, + debugger GUI, and debugger GUIAdapter objects and linking them together. + + Register the GUIAdapter with the RPCClient to handle debugger GUI + interaction requests coming from the subprocess debugger via the GUIProxy. + + The IdbAdapter will pass execution and environment requests coming from the + Idle debugger GUI to the subprocess debugger via the IdbProxy. + + """ + global idb_adap_oid + + idb_adap_oid = rpcclt.remotecall("exec", "start_the_debugger",\ + (gui_adap_oid,), {}) + idb_proxy = IdbProxy(rpcclt, pyshell, idb_adap_oid) + gui = Debugger.Debugger(pyshell, idb_proxy) + gui_adap = GUIAdapter(rpcclt, gui) + rpcclt.register(gui_adap_oid, gui_adap) + return gui + +def close_remote_debugger(rpcclt): + """Shut down subprocess debugger and Idle side of debugger RPC link + + Request that the RPCServer shut down the subprocess debugger and link. + Unregister the GUIAdapter, which will cause a GC on the Idle process + debugger and RPC link objects. (The second reference to the debugger GUI + is deleted in PyShell.close_remote_debugger().) + + """ + close_subprocess_debugger(rpcclt) + rpcclt.unregister(gui_adap_oid) + +def close_subprocess_debugger(rpcclt): + rpcclt.remotecall("exec", "stop_the_debugger", (idb_adap_oid,), {}) + +def restart_subprocess_debugger(rpcclt): + idb_adap_oid_ret = rpcclt.remotecall("exec", "start_the_debugger",\ + (gui_adap_oid,), {}) + assert idb_adap_oid_ret == idb_adap_oid, 'Idb restarted with different oid' diff --git a/PythonHome/Lib/idlelib/RemoteDebugger.pyc b/PythonHome/Lib/idlelib/RemoteDebugger.pyc deleted file mode 100644 index d33e1fcc18b5a12fb442c7921fb09f1078fa51f3..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 15420 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 YmuPZ=g(mJixb;*UjkOOO7x*0iZ$$hNssI20 diff --git a/PythonHome/Lib/idlelib/RstripExtension.py b/PythonHome/Lib/idlelib/RstripExtension.py new file mode 100644 index 0000000000..2ce3c7eafe --- /dev/null +++ b/PythonHome/Lib/idlelib/RstripExtension.py @@ -0,0 +1,33 @@ +'Provides "Strip trailing whitespace" under the "Format" menu.' + +class RstripExtension: + + menudefs = [ + ('format', [None, ('Strip trailing whitespace', '<>'), ] ), ] + + def __init__(self, editwin): + self.editwin = editwin + self.editwin.text.bind("<>", self.do_rstrip) + + def do_rstrip(self, event=None): + + text = self.editwin.text + undo = self.editwin.undo + + undo.undo_block_start() + + end_line = int(float(text.index('end'))) + for cur in range(1, end_line): + txt = text.get('%i.0' % cur, '%i.end' % cur) + raw = len(txt) + cut = len(txt.rstrip()) + # Since text.delete() marks file as changed, even if not, + # only call it when needed to actually delete something. + if cut < raw: + text.delete('%i.%i' % (cur, cut), '%i.end' % cur) + + undo.undo_block_stop() + +if __name__ == "__main__": + import unittest + unittest.main('idlelib.idle_test.test_rstrip', verbosity=2, exit=False) diff --git a/PythonHome/Lib/idlelib/RstripExtension.pyc b/PythonHome/Lib/idlelib/RstripExtension.pyc deleted file mode 100644 index 1e73c0fe4fa72a0a3bd0093023d336502beaab3c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1553 zcmbVM+invv5FLAyv`tfiKvbfD6jdt93lZYERESHTXat)FL{((Av0I#OcFWpni-p$RGi1Yrp{u}%|BLzIU? zRm|UMjm{>_4iz@3@m)N9b41hGQPdE8)M*tN;t9Lc27&CP!RFJ2xjt-i3|?8J3El-d zA}&r2x6GvnW2__jKX_8_cL?t*#@G^!k_66uFD8(#uwG#n?i;>)KkyzDYy_qcb;EbK z2IP)YHj-;c<(Ba(zF0B)c{w;TA!bz+zepgi0u`2**-S$QkxgE!vf|LmDNHiwu8?}1 zrB+nyau=Pn!A}9o;|^ygWtig4oxoUNrMw|o1$cv2n*|w+D+v-&ON_qCPGug9<3CnR z%II4dVHJXOOSN=U-%_h;O|{guq@^}=PYUy2TdE^;W(8SfBWFx(B7!la(vEZfJJ|=55sF+2HRL zyDa9tD4luYs{Jzf_`!283SM{S=T|KB7_2e292g^^(=|TGe8%WO_9s>xTQa+y<-z?A VG4Z)MySgo@ZVuAW*KZ?Z>MK)pN|^uv diff --git a/PythonHome/Lib/idlelib/ScriptBinding.py b/PythonHome/Lib/idlelib/ScriptBinding.py new file mode 100644 index 0000000000..ab2a3f29b9 --- /dev/null +++ b/PythonHome/Lib/idlelib/ScriptBinding.py @@ -0,0 +1,222 @@ +"""Extension to execute code outside the Python shell window. + +This adds the following commands: + +- Check module does a full syntax check of the current module. + It also runs the tabnanny to catch any inconsistent tabs. + +- Run module executes the module's code in the __main__ namespace. The window + must have been saved previously. The module is added to sys.modules, and is + also added to the __main__ namespace. + +XXX GvR Redesign this interface (yet again) as follows: + +- Present a dialog box for ``Run Module'' + +- Allow specify command line arguments in the dialog box + +""" + +import os +import re +import string +import tabnanny +import tokenize +import tkMessageBox +from idlelib import PyShell + +from idlelib.configHandler import idleConf +from idlelib import macosxSupport + +IDENTCHARS = string.ascii_letters + string.digits + "_" + +indent_message = """Error: Inconsistent indentation detected! + +1) Your indentation is outright incorrect (easy to fix), OR + +2) Your indentation mixes tabs and spaces. + +To fix case 2, change all tabs to spaces by using Edit->Select All followed \ +by Format->Untabify Region and specify the number of columns used by each tab. +""" + +class ScriptBinding: + + menudefs = [ + ('run', [None, + ('Check Module', '<>'), + ('Run Module', '<>'), ]), ] + + def __init__(self, editwin): + self.editwin = editwin + # Provide instance variables referenced by Debugger + # XXX This should be done differently + self.flist = self.editwin.flist + self.root = self.editwin.root + + if macosxSupport.isCocoaTk(): + self.editwin.text_frame.bind('<>', self._run_module_event) + + def check_module_event(self, event): + filename = self.getfilename() + if not filename: + return 'break' + if not self.checksyntax(filename): + return 'break' + if not self.tabnanny(filename): + return 'break' + + def tabnanny(self, filename): + f = open(filename, 'r') + try: + tabnanny.process_tokens(tokenize.generate_tokens(f.readline)) + except tokenize.TokenError as msg: + msgtxt, (lineno, start) = msg + self.editwin.gotoline(lineno) + self.errorbox("Tabnanny Tokenizing Error", + "Token Error: %s" % msgtxt) + return False + except tabnanny.NannyNag as nag: + # The error messages from tabnanny are too confusing... + self.editwin.gotoline(nag.get_lineno()) + self.errorbox("Tab/space error", indent_message) + return False + return True + + def checksyntax(self, filename): + self.shell = shell = self.flist.open_shell() + saved_stream = shell.get_warning_stream() + shell.set_warning_stream(shell.stderr) + with open(filename, 'r') as f: + source = f.read() + if '\r' in source: + source = re.sub(r"\r\n", "\n", source) + source = re.sub(r"\r", "\n", source) + if source and source[-1] != '\n': + source = source + '\n' + text = self.editwin.text + text.tag_remove("ERROR", "1.0", "end") + try: + try: + # If successful, return the compiled code + return compile(source, filename, "exec") + except (SyntaxError, OverflowError, ValueError) as err: + try: + msg, (errorfilename, lineno, offset, line) = err + if not errorfilename: + err.args = msg, (filename, lineno, offset, line) + err.filename = filename + self.colorize_syntax_error(msg, lineno, offset) + except: + msg = "*** " + str(err) + self.errorbox("Syntax error", + "There's an error in your program:\n" + msg) + return False + finally: + shell.set_warning_stream(saved_stream) + + def colorize_syntax_error(self, msg, lineno, offset): + text = self.editwin.text + pos = "0.0 + %d lines + %d chars" % (lineno-1, offset-1) + text.tag_add("ERROR", pos) + char = text.get(pos) + if char and char in IDENTCHARS: + text.tag_add("ERROR", pos + " wordstart", pos) + if '\n' == text.get(pos): # error at line end + text.mark_set("insert", pos) + else: + text.mark_set("insert", pos + "+1c") + text.see(pos) + + def run_module_event(self, event): + """Run the module after setting up the environment. + + First check the syntax. If OK, make sure the shell is active and + then transfer the arguments, set the run environment's working + directory to the directory of the module being executed and also + add that directory to its sys.path if not already included. + + """ + filename = self.getfilename() + if not filename: + return 'break' + code = self.checksyntax(filename) + if not code: + return 'break' + if not self.tabnanny(filename): + return 'break' + interp = self.shell.interp + if PyShell.use_subprocess: + interp.restart_subprocess(with_cwd=False) + dirname = os.path.dirname(filename) + # XXX Too often this discards arguments the user just set... + interp.runcommand("""if 1: + __file__ = {filename!r} + import sys as _sys + from os.path import basename as _basename + if (not _sys.argv or + _basename(_sys.argv[0]) != _basename(__file__)): + _sys.argv = [__file__] + import os as _os + _os.chdir({dirname!r}) + del _sys, _basename, _os + \n""".format(filename=filename, dirname=dirname)) + interp.prepend_syspath(filename) + # XXX KBK 03Jul04 When run w/o subprocess, runtime warnings still + # go to __stderr__. With subprocess, they go to the shell. + # Need to change streams in PyShell.ModifiedInterpreter. + interp.runcode(code) + return 'break' + + if macosxSupport.isCocoaTk(): + # Tk-Cocoa in MacOSX is broken until at least + # Tk 8.5.9, and without this rather + # crude workaround IDLE would hang when a user + # tries to run a module using the keyboard shortcut + # (the menu item works fine). + _run_module_event = run_module_event + + def run_module_event(self, event): + self.editwin.text_frame.after(200, + lambda: self.editwin.text_frame.event_generate('<>')) + return 'break' + + def getfilename(self): + """Get source filename. If not saved, offer to save (or create) file + + The debugger requires a source file. Make sure there is one, and that + the current version of the source buffer has been saved. If the user + declines to save or cancels the Save As dialog, return None. + + If the user has configured IDLE for Autosave, the file will be + silently saved if it already exists and is dirty. + + """ + filename = self.editwin.io.filename + if not self.editwin.get_saved(): + autosave = idleConf.GetOption('main', 'General', + 'autosave', type='bool') + if autosave and filename: + self.editwin.io.save(None) + else: + confirm = self.ask_save_dialog() + self.editwin.text.focus_set() + if confirm: + self.editwin.io.save(None) + filename = self.editwin.io.filename + else: + filename = None + return filename + + def ask_save_dialog(self): + msg = "Source Must Be Saved\n" + 5*' ' + "OK to Save?" + confirm = tkMessageBox.askokcancel(title="Save Before Run or Check", + message=msg, + default=tkMessageBox.OK, + master=self.editwin.text) + return confirm + + def errorbox(self, title, message): + # XXX This should really be a function of EditorWindow... + tkMessageBox.showerror(title, message, master=self.editwin.text) + self.editwin.text.focus_set() diff --git a/PythonHome/Lib/idlelib/ScriptBinding.pyc b/PythonHome/Lib/idlelib/ScriptBinding.pyc deleted file mode 100644 index ef44401723f2f669350bffa96736323de8caaa87..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 7973 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", self.click_event) + listbox.bind("", self.double_click_event) + listbox.bind("", self.popup_event) + listbox.bind("", self.up_event) + listbox.bind("", self.down_event) + # Mark as empty + self.clear() + + def close(self): + self.frame.destroy() + + def clear(self): + self.listbox.delete(0, "end") + self.empty = 1 + self.listbox.insert("end", self.default) + + def append(self, item): + if self.empty: + self.listbox.delete(0, "end") + self.empty = 0 + self.listbox.insert("end", str(item)) + + def get(self, index): + return self.listbox.get(index) + + def click_event(self, event): + self.listbox.activate("@%d,%d" % (event.x, event.y)) + index = self.listbox.index("active") + self.select(index) + self.on_select(index) + return "break" + + def double_click_event(self, event): + index = self.listbox.index("active") + self.select(index) + self.on_double(index) + return "break" + + menu = None + + def popup_event(self, event): + if not self.menu: + self.make_menu() + menu = self.menu + self.listbox.activate("@%d,%d" % (event.x, event.y)) + index = self.listbox.index("active") + self.select(index) + menu.tk_popup(event.x_root, event.y_root) + + def make_menu(self): + menu = Menu(self.listbox, tearoff=0) + self.menu = menu + self.fill_menu() + + def up_event(self, event): + index = self.listbox.index("active") + if self.listbox.selection_includes(index): + index = index - 1 + else: + index = self.listbox.size() - 1 + if index < 0: + self.listbox.bell() + else: + self.select(index) + self.on_select(index) + return "break" + + def down_event(self, event): + index = self.listbox.index("active") + if self.listbox.selection_includes(index): + index = index + 1 + else: + index = 0 + if index >= self.listbox.size(): + self.listbox.bell() + else: + self.select(index) + self.on_select(index) + return "break" + + def select(self, index): + self.listbox.focus_set() + self.listbox.activate(index) + self.listbox.selection_clear(0, "end") + self.listbox.selection_set(index) + self.listbox.see(index) + + # Methods to override for specific actions + + def fill_menu(self): + pass + + def on_select(self, index): + pass + + def on_double(self, index): + pass + + +def _scrolled_list(parent): + root = Tk() + root.title("Test ScrolledList") + width, height, x, y = list(map(int, re.split('[x+]', parent.geometry()))) + root.geometry("+%d+%d"%(x, y + 150)) + class MyScrolledList(ScrolledList): + def fill_menu(self): self.menu.add_command(label="right click") + def on_select(self, index): print "select", self.get(index) + def on_double(self, index): print "double", self.get(index) + + scrolled_list = MyScrolledList(root) + for i in range(30): + scrolled_list.append("Item %02d" % i) + + root.mainloop() + +if __name__ == '__main__': + from idlelib.idle_test.htest import run + run(_scrolled_list) diff --git a/PythonHome/Lib/idlelib/ScrolledList.pyc b/PythonHome/Lib/idlelib/ScrolledList.pyc deleted file mode 100644 index dadf68bc644dfb82f5276e4b5ce5381b1cbb9109..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5974 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 E0>P9K{Qv*} diff --git a/PythonHome/Lib/idlelib/SearchDialog.py b/PythonHome/Lib/idlelib/SearchDialog.py new file mode 100644 index 0000000000..2aadb8431f --- /dev/null +++ b/PythonHome/Lib/idlelib/SearchDialog.py @@ -0,0 +1,89 @@ +from Tkinter import * + +from idlelib import SearchEngine +from idlelib.SearchDialogBase import SearchDialogBase + +def _setup(text): + root = text._root() + engine = SearchEngine.get(root) + if not hasattr(engine, "_searchdialog"): + engine._searchdialog = SearchDialog(root, engine) + return engine._searchdialog + +def find(text): + pat = text.get("sel.first", "sel.last") + return _setup(text).open(text,pat) + +def find_again(text): + return _setup(text).find_again(text) + +def find_selection(text): + return _setup(text).find_selection(text) + +class SearchDialog(SearchDialogBase): + + def create_widgets(self): + f = SearchDialogBase.create_widgets(self) + self.make_button("Find Next", self.default_command, 1) + + def default_command(self, event=None): + if not self.engine.getprog(): + return + self.find_again(self.text) + + def find_again(self, text): + if not self.engine.getpat(): + self.open(text) + return False + if not self.engine.getprog(): + return False + res = self.engine.search_text(text) + if res: + line, m = res + i, j = m.span() + first = "%d.%d" % (line, i) + last = "%d.%d" % (line, j) + try: + selfirst = text.index("sel.first") + sellast = text.index("sel.last") + if selfirst == first and sellast == last: + text.bell() + return False + except TclError: + pass + text.tag_remove("sel", "1.0", "end") + text.tag_add("sel", first, last) + text.mark_set("insert", self.engine.isback() and first or last) + text.see("insert") + return True + else: + text.bell() + return False + + def find_selection(self, text): + pat = text.get("sel.first", "sel.last") + if pat: + self.engine.setcookedpat(pat) + return self.find_again(text) + +def _search_dialog(parent): + root = Tk() + root.title("Test SearchDialog") + width, height, x, y = list(map(int, re.split('[x+]', parent.geometry()))) + root.geometry("+%d+%d"%(x, y + 150)) + text = Text(root) + text.pack() + text.insert("insert","This is a sample string.\n"*10) + + def show_find(): + text.tag_add(SEL, "1.0", END) + s = _setup(text) + s.open(text) + text.tag_remove(SEL, "1.0", END) + + button = Button(root, text="Search", command=show_find) + button.pack() + +if __name__ == '__main__': + from idlelib.idle_test.htest import run + run(_search_dialog) diff --git a/PythonHome/Lib/idlelib/SearchDialog.pyc b/PythonHome/Lib/idlelib/SearchDialog.pyc deleted file mode 100644 index 4c64ee1e388eb2d90fb46ffc998eb246f75d1be9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3811 zcmbtX-EJF26h7m>*lyDFkG6m+MW6_mBJ)!&xIh$|rsAUV#X1rYf>vAa#NK4Rwst0M zBPCaknl1 ztK#`Niu(ywihm=y$Oc;#$&HLFvRM(sepT|SjBB!4L%$|ZMKOf>i zr8_j-cc&r;hDRS(#8>5@LP(A(;_isA@fAkUMIF}#(xI_ahkzAq)$>cJW2e%jdTytI z5ntzUIhpuKrRVuW>-_?rqr@fNm;OYJAaKM<9acCNm3`v1!CgEzwLx37q{GVHK-JxP zkUiYW(%j~F23W#=-RZtAgLHmx$_-qb%gmx##@}m3(V-SRa}C9D+kg%rfIC3#fDr}( z5Rt+JMW?Tl_FRkWY~J0@O6Og3*2@#;bwWfSqI0NJm&w!?3S7jQKwD&*c-2O$GpIyt zwzC30f`i!+b1A4oq^XXoav2S;+E8#9Q8nnRuk?ZlDitB&c5yOHvO-_0Y_B3yw2VzI zqBtHe|3ex&y-EW}?Z9V~|0)rq;R?!3qKJ++K+zwiyo=)AM`aP!Ft%ur!uM-*|EGpQ z4-a@6V!o=4hD7}i4SMW3#9!gQi3Z?41{!WdN77hgqpI#yRbDymI`;wnN)N7{(Rv;3 z7g0P=7Y6kf*r6(i;K-WnG`NN%bvZmSUO@kTJ_Y5Z?33A3Y~|bLP*i=9@;$j6mesaub1Vd^tyR6j7vM7JhJMM9^E8Ob>28BcbPGQQ0`$e z*qzC3b;FHv&vtmYI_wFJm)7a~90^(DZme~t^^QuVDI!cldeGAtrA!&c}txIue3{_;B`RR4GYje&1}%-pOT_-0lg(ynWhEWgUMvqrnEIlEo4p- zg5n!7)x8pn(Tnb&Xg+3sY(V2)he<$TkK-a4+c;Kdh~x1j-OJI9$bM>|-lVWfD}klB z--!U)dU>YSoO5k1MWfQHE!JB%2IP4kJ1yI)WtbsP!r8U!AwE1JgZg$x40eLyha z3WAMj#B9Bs0P?LG?`?sHz&%_KRsr`Q*b)CVxkd`2t)O|Z(vKoPV4oKEF>HY?lqwMD zR~Yuskc1&bQ@)2x4aOQ4;!ca3EH1DI;1p8`ls!iXHxLUer>|m~O}>3{ z>pNxWTdOJlv*(x@y@ARx;cSdDw}Ss<#U&@uW(945yLH9 zxhatQ+m-3%egVG5veD#m%$rV+ohB-Qi!LH41EtVA0)k2n^YpGvNRc;ol~R1>^T11a z1{SH}%{ZCrGb=nW0jFD?>85!WIA>@lW9!R(b@Yw-Eqe;0Q)?*k-PIdLhjM9unv_V& z5hd5%a3%30eKWGzaO9Qco@l)vkwElaxTkc`4S=a?X8?$IpV>D>96l=6G2%!FVp_oH zws{j+wat~va^pH38}s8a?yqqiEJGm5y`raIQHtQkE&xG>AqUL97Q&~=^^<|_X`kiy zlU~Jw=_%6*8E9-r4>8@2Mo|SE3vCip9W(3O#O^muU!G1 US6U0LTC3WsUhTFnErQ", self.default_command) + top.bind("", self.close) + top.protocol("WM_DELETE_WINDOW", self.close) + top.wm_title(self.title) + top.wm_iconname(self.icon) + self.top = top + + self.row = 0 + self.top.grid_columnconfigure(0, pad=2, weight=0) + self.top.grid_columnconfigure(1, pad=2, minsize=100, weight=100) + + self.create_entries() # row 0 (and maybe 1), cols 0, 1 + self.create_option_buttons() # next row, cols 0, 1 + self.create_other_buttons() # next row, cols 0, 1 + self.create_command_buttons() # col 2, all rows + + def make_entry(self, label, var): + "Return gridded labeled Entry." + l = Label(self.top, text=label) + l.grid(row=self.row, column=0, sticky="nw") + e = Entry(self.top, textvariable=var, exportselection=0) + e.grid(row=self.row, column=1, sticky="nwe") + self.row = self.row + 1 + return e + + def create_entries(self): + "Create one or more entry lines with make_entry." + self.ent = self.make_entry("Find:", self.engine.patvar) + + def make_frame(self,labeltext=None): + "Return gridded labeled Frame for option or other buttons." + if labeltext: + l = Label(self.top, text=labeltext) + l.grid(row=self.row, column=0, sticky="nw") + f = Frame(self.top) + f.grid(row=self.row, column=1, columnspan=1, sticky="nwe") + self.row = self.row + 1 + return f + + def create_option_buttons(self): + "Fill frame with Checkbuttons bound to SearchEngine booleanvars." + f = self.make_frame("Options") + + btn = Checkbutton(f, anchor="w", + variable=self.engine.revar, + text="Regular expression") + btn.pack(side="left", fill="both") + if self.engine.isre(): + btn.select() + + btn = Checkbutton(f, anchor="w", + variable=self.engine.casevar, + text="Match case") + btn.pack(side="left", fill="both") + if self.engine.iscase(): + btn.select() + + btn = Checkbutton(f, anchor="w", + variable=self.engine.wordvar, + text="Whole word") + btn.pack(side="left", fill="both") + if self.engine.isword(): + btn.select() + + if self.needwrapbutton: + btn = Checkbutton(f, anchor="w", + variable=self.engine.wrapvar, + text="Wrap around") + btn.pack(side="left", fill="both") + if self.engine.iswrap(): + btn.select() + + def create_other_buttons(self): + "Fill frame with buttons tied to other options." + f = self.make_frame("Direction") + + btn = Radiobutton(f, anchor="w", + variable=self.engine.backvar, value=1, + text="Up") + btn.pack(side="left", fill="both") + if self.engine.isback(): + btn.select() + + btn = Radiobutton(f, anchor="w", + variable=self.engine.backvar, value=0, + text="Down") + btn.pack(side="left", fill="both") + if not self.engine.isback(): + btn.select() + + def make_button(self, label, command, isdef=0): + "Return command button gridded in command frame." + b = Button(self.buttonframe, + text=label, command=command, + default=isdef and "active" or "normal") + cols,rows=self.buttonframe.grid_size() + b.grid(pady=1,row=rows,column=0,sticky="ew") + self.buttonframe.grid(rowspan=rows+1) + return b + + def create_command_buttons(self): + "Place buttons in vertical command frame gridded on right." + f = self.buttonframe = Frame(self.top) + f.grid(row=0,column=2,padx=2,pady=2,ipadx=2,ipady=2) + + b = self.make_button("close", self.close) + b.lower() + +if __name__ == '__main__': + import unittest + unittest.main( + 'idlelib.idle_test.test_searchdialogbase', verbosity=2) diff --git a/PythonHome/Lib/idlelib/SearchDialogBase.pyc b/PythonHome/Lib/idlelib/SearchDialogBase.pyc deleted file mode 100644 index 1d287af026ad6fb409c6a55c00115386d0afb857..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 7626 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 W&Pwm`^Kt@f)ZVOL{u7<7;r$l{C9Dnr diff --git a/PythonHome/Lib/idlelib/SearchEngine.py b/PythonHome/Lib/idlelib/SearchEngine.py new file mode 100644 index 0000000000..b3b7b4df0a --- /dev/null +++ b/PythonHome/Lib/idlelib/SearchEngine.py @@ -0,0 +1,233 @@ +'''Define SearchEngine for search dialogs.''' +import re +from Tkinter import StringVar, BooleanVar, TclError +import tkMessageBox + +def get(root): + '''Return the singleton SearchEngine instance for the process. + + The single SearchEngine saves settings between dialog instances. + If there is not a SearchEngine already, make one. + ''' + if not hasattr(root, "_searchengine"): + root._searchengine = SearchEngine(root) + # This creates a cycle that persists until root is deleted. + return root._searchengine + +class SearchEngine: + """Handles searching a text widget for Find, Replace, and Grep.""" + + def __init__(self, root): + '''Initialize Variables that save search state. + + The dialogs bind these to the UI elements present in the dialogs. + ''' + self.root = root # need for report_error() + self.patvar = StringVar(root, '') # search pattern + self.revar = BooleanVar(root, False) # regular expression? + self.casevar = BooleanVar(root, False) # match case? + self.wordvar = BooleanVar(root, False) # match whole word? + self.wrapvar = BooleanVar(root, True) # wrap around buffer? + self.backvar = BooleanVar(root, False) # search backwards? + + # Access methods + + def getpat(self): + return self.patvar.get() + + def setpat(self, pat): + self.patvar.set(pat) + + def isre(self): + return self.revar.get() + + def iscase(self): + return self.casevar.get() + + def isword(self): + return self.wordvar.get() + + def iswrap(self): + return self.wrapvar.get() + + def isback(self): + return self.backvar.get() + + # Higher level access methods + + def setcookedpat(self, pat): + "Set pattern after escaping if re." + # called only in SearchDialog.py: 66 + if self.isre(): + pat = re.escape(pat) + self.setpat(pat) + + def getcookedpat(self): + pat = self.getpat() + if not self.isre(): # if True, see setcookedpat + pat = re.escape(pat) + if self.isword(): + pat = r"\b%s\b" % pat + return pat + + def getprog(self): + "Return compiled cooked search pattern." + pat = self.getpat() + if not pat: + self.report_error(pat, "Empty regular expression") + return None + pat = self.getcookedpat() + flags = 0 + if not self.iscase(): + flags = flags | re.IGNORECASE + try: + prog = re.compile(pat, flags) + except re.error as what: + args = what.args + msg = args[0] + col = arg[1] if len(args) >= 2 else -1 + self.report_error(pat, msg, col) + return None + return prog + + def report_error(self, pat, msg, col=-1): + # Derived class could override this with something fancier + msg = "Error: " + str(msg) + if pat: + msg = msg + "\nPattern: " + str(pat) + if col >= 0: + msg = msg + "\nOffset: " + str(col) + tkMessageBox.showerror("Regular expression error", + msg, master=self.root) + + def search_text(self, text, prog=None, ok=0): + '''Return (lineno, matchobj) or None for forward/backward search. + + This function calls the right function with the right arguments. + It directly return the result of that call. + + Text is a text widget. Prog is a precompiled pattern. + The ok parameteris a bit complicated as it has two effects. + + If there is a selection, the search begin at either end, + depending on the direction setting and ok, with ok meaning that + the search starts with the selection. Otherwise, search begins + at the insert mark. + + To aid progress, the search functions do not return an empty + match at the starting position unless ok is True. + ''' + + if not prog: + prog = self.getprog() + if not prog: + return None # Compilation failed -- stop + wrap = self.wrapvar.get() + first, last = get_selection(text) + if self.isback(): + if ok: + start = last + else: + start = first + line, col = get_line_col(start) + res = self.search_backward(text, prog, line, col, wrap, ok) + else: + if ok: + start = first + else: + start = last + line, col = get_line_col(start) + res = self.search_forward(text, prog, line, col, wrap, ok) + return res + + def search_forward(self, text, prog, line, col, wrap, ok=0): + wrapped = 0 + startline = line + chars = text.get("%d.0" % line, "%d.0" % (line+1)) + while chars: + m = prog.search(chars[:-1], col) + if m: + if ok or m.end() > col: + return line, m + line = line + 1 + if wrapped and line > startline: + break + col = 0 + ok = 1 + chars = text.get("%d.0" % line, "%d.0" % (line+1)) + if not chars and wrap: + wrapped = 1 + wrap = 0 + line = 1 + chars = text.get("1.0", "2.0") + return None + + def search_backward(self, text, prog, line, col, wrap, ok=0): + wrapped = 0 + startline = line + chars = text.get("%d.0" % line, "%d.0" % (line+1)) + while 1: + m = search_reverse(prog, chars[:-1], col) + if m: + if ok or m.start() < col: + return line, m + line = line - 1 + if wrapped and line < startline: + break + ok = 1 + if line <= 0: + if not wrap: + break + wrapped = 1 + wrap = 0 + pos = text.index("end-1c") + line, col = map(int, pos.split(".")) + chars = text.get("%d.0" % line, "%d.0" % (line+1)) + col = len(chars) - 1 + return None + +def search_reverse(prog, chars, col): + '''Search backwards and return an re match object or None. + + This is done by searching forwards until there is no match. + Prog: compiled re object with a search method returning a match. + Chars: line of text, without \n. + Col: stop index for the search; the limit for match.end(). + ''' + m = prog.search(chars) + if not m: + return None + found = None + i, j = m.span() # m.start(), m.end() == match slice indexes + while i < col and j <= col: + found = m + if i == j: + j = j+1 + m = prog.search(chars, j) + if not m: + break + i, j = m.span() + return found + +def get_selection(text): + '''Return tuple of 'line.col' indexes from selection or insert mark. + ''' + try: + first = text.index("sel.first") + last = text.index("sel.last") + except TclError: + first = last = None + if not first: + first = text.index("insert") + if not last: + last = first + return first, last + +def get_line_col(index): + '''Return (line, col) tuple of ints from 'line.col' string.''' + line, col = map(int, index.split(".")) # Fails on invalid index + return line, col + +if __name__ == "__main__": + import unittest + unittest.main('idlelib.idle_test.test_searchengine', verbosity=2, exit=False) diff --git a/PythonHome/Lib/idlelib/SearchEngine.pyc b/PythonHome/Lib/idlelib/SearchEngine.pyc deleted file mode 100644 index 005f454196563db1929cf0309b788d65bdeb73a9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 7992 zcmb_hPi!1l8Gp08UVGPeoI1r$NJ%FxX*b|3X(|8GsL;4+8dTh99B45?tMSfTd%UwV z+j-A*jBE)hmADll^~eQ54;If>cmD8`)xIkJn)v<(9`j2Sky2|YJr&hd;;A)M@Tse$rbczOR#&5jT5G7$ zgj$&Ku`hUmMeHw|)HGu2vphX2SQh!BMTnw#HxAc1P>9IJ94Gie0$L%>gOM zwI3Tl&8#0D-78FT9Y(uL{wN%3KTEY+WoL1Kp5vw#_Btj`qI)wmp|!c4LH)1*0`jXv z#@PmnJj*N@r=&2SL9Kh|&3OGz93?uz_u;kO@vi0a4Q&Zc!$LLZy!l!%fm)wU{&CJV zJmwcDG@u8dqO1`{fF7_4oUqa$fLQ@B9Y}%J3F!e^1*Z?jC;-ak0OGV%07n7k`%n;I zbe`x0*aF|z z<1||G13gZ{zFzXN!oQL0ako!U@!|QG@t9o{dk%fzH!7mEz$Rb_Jc60%fgFmSiTiq* z_w`JcJyYeXR@qbS10^QLNrw3$ikoR{p=Z0E=%jjevFFh8@ zr?7vo7lUuT-jk@C6DZU~%bTzMD+5I0McULx+82C0+SgT4vlXEwpkWJm9O(?6U=7bh z>mB(90D@u9qGkv)3@M_=V6`KT)JPAuKQ>j^1G7SXJ_`)O8F!%qV0qXeTBh$d( z;qm!EGw`KDG?bRP(i1Yt=?N4yKS$$?xWFmQzE?&HVxL8YyfS7ukAE zUtFJoc@o1^9$3`x1}0R8#pzfV3uQh>`nJkr9vmF51XM56VS^_N#X!k~6?xm8^$X_C zdWXh3p#PNP22ZiZFd{gE;&G1&i&q`c4^^|$8 zI5N(H6T#bh2rgDRtImVscyO5e;+D7M=;pTCgMXe-TTOKh1Be`V7oD*u!6_8ZFEYpAW3+MiH+h-+%<%s$+Bn+-q-0nczk<-buD0dzy1Nf8W9 zsC{fJLgD63wKu8m)g6)V?9~B1nn#=hTy^1UKO2qXL`S~kPU*r6P zV>=0f(7W`~CeG3rV=5*!j4_2pMruRCAu=n@ZpusF;&jJTHsQ9>Q-(b1vM#0`o9$cjM{Vj@)sA@+t;b`Yfm z7tkZ?MrK34`&n`HUt$~LUgU^)UXC#5fQX&cZ^@K~n*!*$#hBvE4}ice zAb*FYV$G=14aU_@40oWaP%+0=C?PD{ zhZIWwJ?a`%FU64PAYxLgo~O8EO6|8~&r;?0rqmvKuq{M~g>98ymwkR-EayJ5;m7ZT zT3j7gvEZ)WRT7k%W;R7A-_kVx-@@b+|dtQ0ojNC1y) zaAkmCsn=-d$OHa zKV$BST!Jq+{B~wdARs)PKXv_E&_UM?dsLaR(r{HN1GDOE2rrw5BMqF&M(Z)&0t=JG zeWWUp9~vJ$$aHv7(2P>B3v@XL#UXE)CALMJWfu0<>T}4Ht z$7s{9gMnn7V*}XIv$Q%ui33)L8I>5+EhxRA9#DXzWPz956O9AVPi;6-3!C6cY zKf`Xqya$VJxx#U&SAyD}IOr>YFLY)C)Cy|xgal*ds)6;>|S=k zHJ7++D7mT;8A4eFd2HRB4}+x9 zai9?}^Y}3y2Pj~n>79dTTfp~e#H?+gp;7eC%6HQ{<1oP}tir@uy!jZI_=nsu0Wk+? z0OuVVQb9v_6bc8Vi7$hX4&@9N^*73w@Db*V!jQ z%^{CXnP#G=DhR3-6?NHt~cfOyw^+NPkTLy-Fv-J z7HubNk}bVnl=XYPU>X|W!a5+1x}cP!P5Cus$O;r-5vo87TD}UsE-B>O zek3|^|9jqjNxcnATwKmx@OYWPn`XcCcnFwq)q3Ec@tc5i$_M}vzLX(g;rMTF!V%*W zF)Cc&E#e0H?7~|b_-q>|^ylTT3vNH>xfzXJk(f%dNlYnTBk@UC#vus7HnWl{iFyui zvP?61#i!YnU=aG_;-PHY`fc~30g$3BZ)@{=lBDWoVW|^ z?Ob%r#TmGth=Q*}z5+CH;$|GC;y#>_7ZnpDFM38>I>@%uNNhkX<<O6Ai$i$ zXMbIJ$oLwnfoV(~J@pPCY~Cr?AnlMXh&m)baPDrNARRsQ>2e=qNOh4$*zIv5a(SKt z>LSp3-pK&J0SxkN1Q{1$8L@RFwqy(~X(gs~2Mndm6gFl{!YP_qx1bQs4ZfCfnDfHq zhI7DQV~zJz$KpM25&we6Jc&Zp>xigMf#WB@adN$Nz;gx-qWs+7;^X)%zc_(s(91he zeBl;&RoazA{P7&kAy?2cFrrz_b80hUe7#>q2d?1F28$L8{1`ZLW yAszA_QX8}}bZ~a5eX`!kURRxedIeTe89F0s+*966tu=k>*R93YiPi*f0{;tDBxuC| diff --git a/PythonHome/Lib/idlelib/StackViewer.py b/PythonHome/Lib/idlelib/StackViewer.py new file mode 100644 index 0000000000..74c9136700 --- /dev/null +++ b/PythonHome/Lib/idlelib/StackViewer.py @@ -0,0 +1,152 @@ +import os +import sys +import linecache +import re +import Tkinter as tk + +from idlelib.TreeWidget import TreeNode, TreeItem, ScrolledCanvas +from idlelib.ObjectBrowser import ObjectTreeItem, make_objecttreeitem +from idlelib.PyShell import PyShellFileList + +def StackBrowser(root, flist=None, tb=None, top=None): + if top is None: + from Tkinter import Toplevel + top = Toplevel(root) + sc = ScrolledCanvas(top, bg="white", highlightthickness=0) + sc.frame.pack(expand=1, fill="both") + item = StackTreeItem(flist, tb) + node = TreeNode(sc.canvas, None, item) + node.expand() + +class StackTreeItem(TreeItem): + + def __init__(self, flist=None, tb=None): + self.flist = flist + self.stack = self.get_stack(tb) + self.text = self.get_exception() + + def get_stack(self, tb): + if tb is None: + tb = sys.last_traceback + stack = [] + if tb and tb.tb_frame is None: + tb = tb.tb_next + while tb is not None: + stack.append((tb.tb_frame, tb.tb_lineno)) + tb = tb.tb_next + return stack + + def get_exception(self): + type = sys.last_type + value = sys.last_value + if hasattr(type, "__name__"): + type = type.__name__ + s = str(type) + if value is not None: + s = s + ": " + str(value) + return s + + def GetText(self): + return self.text + + def GetSubList(self): + sublist = [] + for info in self.stack: + item = FrameTreeItem(info, self.flist) + sublist.append(item) + return sublist + +class FrameTreeItem(TreeItem): + + def __init__(self, info, flist): + self.info = info + self.flist = flist + + def GetText(self): + frame, lineno = self.info + try: + modname = frame.f_globals["__name__"] + except: + modname = "?" + code = frame.f_code + filename = code.co_filename + funcname = code.co_name + sourceline = linecache.getline(filename, lineno) + sourceline = sourceline.strip() + if funcname in ("?", "", None): + item = "%s, line %d: %s" % (modname, lineno, sourceline) + else: + item = "%s.%s(...), line %d: %s" % (modname, funcname, + lineno, sourceline) + return item + + def GetSubList(self): + frame, lineno = self.info + sublist = [] + if frame.f_globals is not frame.f_locals: + item = VariablesTreeItem("", frame.f_locals, self.flist) + sublist.append(item) + item = VariablesTreeItem("", frame.f_globals, self.flist) + sublist.append(item) + return sublist + + def OnDoubleClick(self): + if self.flist: + frame, lineno = self.info + filename = frame.f_code.co_filename + if os.path.isfile(filename): + self.flist.gotofileline(filename, lineno) + +class VariablesTreeItem(ObjectTreeItem): + + def GetText(self): + return self.labeltext + + def GetLabelText(self): + return None + + def IsExpandable(self): + return len(self.object) > 0 + + def keys(self): + return self.object.keys() + + def GetSubList(self): + sublist = [] + for key in self.keys(): + try: + value = self.object[key] + except KeyError: + continue + def setfunction(value, key=key, object=self.object): + object[key] = value + item = make_objecttreeitem(key + " =", value, setfunction) + sublist.append(item) + return sublist + +def _stack_viewer(parent): + root = tk.Tk() + root.title("Test StackViewer") + width, height, x, y = list(map(int, re.split('[x+]', parent.geometry()))) + root.geometry("+%d+%d"%(x, y + 150)) + flist = PyShellFileList(root) + try: # to obtain a traceback object + a + except: + exc_type, exc_value, exc_tb = sys.exc_info() + + # inject stack trace to sys + sys.last_type = exc_type + sys.last_value = exc_value + sys.last_traceback = exc_tb + + StackBrowser(root, flist=flist, top=root, tb=exc_tb) + + # restore sys to original state + del sys.last_type + del sys.last_value + del sys.last_traceback + +if __name__ == '__main__': + from idlelib.idle_test.htest import run + run(_stack_viewer) diff --git a/PythonHome/Lib/idlelib/StackViewer.pyc b/PythonHome/Lib/idlelib/StackViewer.pyc deleted file mode 100644 index b93582d2d1055b236536e832841afac8cf274a60..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6076 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 diff --git a/PythonHome/Lib/idlelib/ToolTip.py b/PythonHome/Lib/idlelib/ToolTip.py new file mode 100644 index 0000000000..11136c4429 --- /dev/null +++ b/PythonHome/Lib/idlelib/ToolTip.py @@ -0,0 +1,97 @@ +# general purpose 'tooltip' routines - currently unused in idlefork +# (although the 'calltips' extension is partly based on this code) +# may be useful for some purposes in (or almost in ;) the current project scope +# Ideas gleaned from PySol + +from Tkinter import * + +class ToolTipBase: + + def __init__(self, button): + self.button = button + self.tipwindow = None + self.id = None + self.x = self.y = 0 + self._id1 = self.button.bind("", self.enter) + self._id2 = self.button.bind("", self.leave) + self._id3 = self.button.bind("", self.leave) + + def enter(self, event=None): + self.schedule() + + def leave(self, event=None): + self.unschedule() + self.hidetip() + + def schedule(self): + self.unschedule() + self.id = self.button.after(1500, self.showtip) + + def unschedule(self): + id = self.id + self.id = None + if id: + self.button.after_cancel(id) + + def showtip(self): + if self.tipwindow: + return + # The tip window must be completely outside the button; + # otherwise when the mouse enters the tip window we get + # a leave event and it disappears, and then we get an enter + # event and it reappears, and so on forever :-( + x = self.button.winfo_rootx() + 20 + y = self.button.winfo_rooty() + self.button.winfo_height() + 1 + self.tipwindow = tw = Toplevel(self.button) + tw.wm_overrideredirect(1) + tw.wm_geometry("+%d+%d" % (x, y)) + self.showcontents() + + def showcontents(self, text="Your text here"): + # Override this in derived class + label = Label(self.tipwindow, text=text, justify=LEFT, + background="#ffffe0", relief=SOLID, borderwidth=1) + label.pack() + + def hidetip(self): + tw = self.tipwindow + self.tipwindow = None + if tw: + tw.destroy() + +class ToolTip(ToolTipBase): + def __init__(self, button, text): + ToolTipBase.__init__(self, button) + self.text = text + def showcontents(self): + ToolTipBase.showcontents(self, self.text) + +class ListboxToolTip(ToolTipBase): + def __init__(self, button, items): + ToolTipBase.__init__(self, button) + self.items = items + def showcontents(self): + listbox = Listbox(self.tipwindow, background="#ffffe0") + listbox.pack() + for item in self.items: + listbox.insert(END, item) + +def _tooltip(parent): + root = Tk() + root.title("Test tooltip") + width, height, x, y = list(map(int, re.split('[x+]', parent.geometry()))) + root.geometry("+%d+%d"%(x, y + 150)) + label = Label(root, text="Place your mouse over buttons") + label.pack() + button1 = Button(root, text="Button 1") + button2 = Button(root, text="Button 2") + button1.pack() + button2.pack() + ToolTip(button1, "This is tooltip text for button1.") + ListboxToolTip(button2, ["This is","multiple line", + "tooltip text","for button2"]) + root.mainloop() + +if __name__ == '__main__': + from idlelib.idle_test.htest import run + run(_tooltip) diff --git a/PythonHome/Lib/idlelib/ToolTip.pyc b/PythonHome/Lib/idlelib/ToolTip.pyc deleted file mode 100644 index 88c95e8842eaef8959e24521b81e8faad174ca16..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4414 zcmd5<-EJF26rQymJ9d*2TAEb+x}p_s1A(RzLZS+&O^c8sx7t`j4Xsv=cN}lJ_L`k> zlZaFxxe`19&%gt5$s=&b1Hkv4*^Qm3ihRKZNoI0(e!ug7rug?_?e{-^+3u+9r-=Vw zqnV%3h4}MStW+y3sBl4rMfFOlu~JWVJQbFd_EZ%8;~iv7O1LZs=76ki7o?}Hnrt1@0tz>d#6q!7GQJ&eA zt<)_6gA!hpdI^S$SzsaC{6J6>F&r0Ex1g3~7?;iSC}(~|)r{UkA5lJr;b8Sfh`$Ey z+81$&b<&s+5xPl`CW$?iU_ALgvJ|5G?&)Z+XT@b($uQP0bZqG$2mK&`oW$~`r4-M6k1OwK~x!7(+~i3OrOwvT9-s5doZgxUBQ;?Xohx0wUp*Adv$Nw zTl7{ui6c*vQChe9(AIlECUK;QrR3;7n)wo)%@sk{fXzV%a1+FLxW=5aAS7#yy*a1{ z@^<=iLZ&@5CGPPO@sRzIu~GNP(&u;Eo#%ULG8%*uus`hLM}H=fIYk`QU6Imml0t3= zh{Qcnm3W}|-Bx>7$D%2@W9z}gmW*#d+WK}=hK9JIL6*c1{SU|wEj#AUS>^a1HmswG zji|y^?}{_-Q;s=_Cube=2F2!#T(bPcB?Xx1nUshp)W)XC(Uc?7v1Ua|WBYuFR0qBoBt%B;XwDw2LV-;n`v<6JF0}lk)otEeqUBugNznn4Ta5L_|G+ z3(r^s*>|!QO!CPfFe?%YK*UELl;@(zEs*{yJ5e;(OwJSPeD*%Zh7B}fuk2NemXNk0 zV|SCo|APX>rz5NT=ByUiPVss^n-tE&oK59rTBNDaN5#Ir0WlpA5e>(l$Gmmo;)mBH zLlxELvt`AQC@BmGVTaWC4>#3!qIDkJ^sk|xj(!bBd-04+zAh7egi)W&NOX(_1_cLV zuTl@1n-iX8U+nZE@sBc@sQP^NX%^q2Wx?YL%BH3N$bdc}P##S|(ttWNY{nXLE0X;S z1SC5~K6lbYs&Qou(hWETJCNb2=L1%YNRi#2mMCge0xv;8)R4I=0q|>QFl)nBg%7+o%-$Rk99*!YxN>i$6t1v%l+LX-+p^dOfg#}FQ@*9uwq@0 zqk$H<(|Zk5#bp0_gIr0O(t0jVX(JoE2NBIuEVkbs%KvC!Wo4>mr5VPNtDW+i$iGg$ zY58LGjw_$R$frR`M(ekuL7XH*DcWS&u$`iQ66Oy+ho_3Gnt5 zy*{JoxYU}7ReMi$VrWK8fu;2vf4<#aS?x;y9bB}iJ& zAts%=Ty?^_zlnLDVcjyXWY5Mm{tqmyX|2cJXE2-aAk?`bKw#Z5Q;Nh|;qvFp MmE~G>X#oM@U)vJ;NdN!< diff --git a/PythonHome/Lib/idlelib/TreeWidget.py b/PythonHome/Lib/idlelib/TreeWidget.py new file mode 100644 index 0000000000..ebb1f02a15 --- /dev/null +++ b/PythonHome/Lib/idlelib/TreeWidget.py @@ -0,0 +1,466 @@ +# XXX TO DO: +# - popup menu +# - support partial or total redisplay +# - key bindings (instead of quick-n-dirty bindings on Canvas): +# - up/down arrow keys to move focus around +# - ditto for page up/down, home/end +# - left/right arrows to expand/collapse & move out/in +# - more doc strings +# - add icons for "file", "module", "class", "method"; better "python" icon +# - callback for selection??? +# - multiple-item selection +# - tooltips +# - redo geometry without magic numbers +# - keep track of object ids to allow more careful cleaning +# - optimize tree redraw after expand of subnode + +import os +from Tkinter import * +import imp + +from idlelib import ZoomHeight +from idlelib.configHandler import idleConf + +ICONDIR = "Icons" + +# Look for Icons subdirectory in the same directory as this module +try: + _icondir = os.path.join(os.path.dirname(__file__), ICONDIR) +except NameError: + _icondir = ICONDIR +if os.path.isdir(_icondir): + ICONDIR = _icondir +elif not os.path.isdir(ICONDIR): + raise RuntimeError, "can't find icon directory (%r)" % (ICONDIR,) + +def listicons(icondir=ICONDIR): + """Utility to display the available icons.""" + root = Tk() + import glob + list = glob.glob(os.path.join(icondir, "*.gif")) + list.sort() + images = [] + row = column = 0 + for file in list: + name = os.path.splitext(os.path.basename(file))[0] + image = PhotoImage(file=file, master=root) + images.append(image) + label = Label(root, image=image, bd=1, relief="raised") + label.grid(row=row, column=column) + label = Label(root, text=name) + label.grid(row=row+1, column=column) + column = column + 1 + if column >= 10: + row = row+2 + column = 0 + root.images = images + + +class TreeNode: + + def __init__(self, canvas, parent, item): + self.canvas = canvas + self.parent = parent + self.item = item + self.state = 'collapsed' + self.selected = False + self.children = [] + self.x = self.y = None + self.iconimages = {} # cache of PhotoImage instances for icons + + def destroy(self): + for c in self.children[:]: + self.children.remove(c) + c.destroy() + self.parent = None + + def geticonimage(self, name): + try: + return self.iconimages[name] + except KeyError: + pass + file, ext = os.path.splitext(name) + ext = ext or ".gif" + fullname = os.path.join(ICONDIR, file + ext) + image = PhotoImage(master=self.canvas, file=fullname) + self.iconimages[name] = image + return image + + def select(self, event=None): + if self.selected: + return + self.deselectall() + self.selected = True + self.canvas.delete(self.image_id) + self.drawicon() + self.drawtext() + + def deselect(self, event=None): + if not self.selected: + return + self.selected = False + self.canvas.delete(self.image_id) + self.drawicon() + self.drawtext() + + def deselectall(self): + if self.parent: + self.parent.deselectall() + else: + self.deselecttree() + + def deselecttree(self): + if self.selected: + self.deselect() + for child in self.children: + child.deselecttree() + + def flip(self, event=None): + if self.state == 'expanded': + self.collapse() + else: + self.expand() + self.item.OnDoubleClick() + return "break" + + def expand(self, event=None): + if not self.item._IsExpandable(): + return + if self.state != 'expanded': + self.state = 'expanded' + self.update() + self.view() + + def collapse(self, event=None): + if self.state != 'collapsed': + self.state = 'collapsed' + self.update() + + def view(self): + top = self.y - 2 + bottom = self.lastvisiblechild().y + 17 + height = bottom - top + visible_top = self.canvas.canvasy(0) + visible_height = self.canvas.winfo_height() + visible_bottom = self.canvas.canvasy(visible_height) + if visible_top <= top and bottom <= visible_bottom: + return + x0, y0, x1, y1 = self.canvas._getints(self.canvas['scrollregion']) + if top >= visible_top and height <= visible_height: + fraction = top + height - visible_height + else: + fraction = top + fraction = float(fraction) / y1 + self.canvas.yview_moveto(fraction) + + def lastvisiblechild(self): + if self.children and self.state == 'expanded': + return self.children[-1].lastvisiblechild() + else: + return self + + def update(self): + if self.parent: + self.parent.update() + else: + oldcursor = self.canvas['cursor'] + self.canvas['cursor'] = "watch" + self.canvas.update() + self.canvas.delete(ALL) # XXX could be more subtle + self.draw(7, 2) + x0, y0, x1, y1 = self.canvas.bbox(ALL) + self.canvas.configure(scrollregion=(0, 0, x1, y1)) + self.canvas['cursor'] = oldcursor + + def draw(self, x, y): + # XXX This hard-codes too many geometry constants! + self.x, self.y = x, y + self.drawicon() + self.drawtext() + if self.state != 'expanded': + return y+17 + # draw children + if not self.children: + sublist = self.item._GetSubList() + if not sublist: + # _IsExpandable() was mistaken; that's allowed + return y+17 + for item in sublist: + child = self.__class__(self.canvas, self, item) + self.children.append(child) + cx = x+20 + cy = y+17 + cylast = 0 + for child in self.children: + cylast = cy + self.canvas.create_line(x+9, cy+7, cx, cy+7, fill="gray50") + cy = child.draw(cx, cy) + if child.item._IsExpandable(): + if child.state == 'expanded': + iconname = "minusnode" + callback = child.collapse + else: + iconname = "plusnode" + callback = child.expand + image = self.geticonimage(iconname) + id = self.canvas.create_image(x+9, cylast+7, image=image) + # XXX This leaks bindings until canvas is deleted: + self.canvas.tag_bind(id, "<1>", callback) + self.canvas.tag_bind(id, "", lambda x: None) + id = self.canvas.create_line(x+9, y+10, x+9, cylast+7, + ##stipple="gray50", # XXX Seems broken in Tk 8.0.x + fill="gray50") + self.canvas.tag_lower(id) # XXX .lower(id) before Python 1.5.2 + return cy + + def drawicon(self): + if self.selected: + imagename = (self.item.GetSelectedIconName() or + self.item.GetIconName() or + "openfolder") + else: + imagename = self.item.GetIconName() or "folder" + image = self.geticonimage(imagename) + id = self.canvas.create_image(self.x, self.y, anchor="nw", image=image) + self.image_id = id + self.canvas.tag_bind(id, "<1>", self.select) + self.canvas.tag_bind(id, "", self.flip) + + def drawtext(self): + textx = self.x+20-1 + texty = self.y-1 + labeltext = self.item.GetLabelText() + if labeltext: + id = self.canvas.create_text(textx, texty, anchor="nw", + text=labeltext) + self.canvas.tag_bind(id, "<1>", self.select) + self.canvas.tag_bind(id, "", self.flip) + x0, y0, x1, y1 = self.canvas.bbox(id) + textx = max(x1, 200) + 10 + text = self.item.GetText() or "" + try: + self.entry + except AttributeError: + pass + else: + self.edit_finish() + try: + label = self.label + except AttributeError: + # padding carefully selected (on Windows) to match Entry widget: + self.label = Label(self.canvas, text=text, bd=0, padx=2, pady=2) + theme = idleConf.GetOption('main','Theme','name') + if self.selected: + self.label.configure(idleConf.GetHighlight(theme, 'hilite')) + else: + self.label.configure(idleConf.GetHighlight(theme, 'normal')) + id = self.canvas.create_window(textx, texty, + anchor="nw", window=self.label) + self.label.bind("<1>", self.select_or_edit) + self.label.bind("", self.flip) + self.text_id = id + + def select_or_edit(self, event=None): + if self.selected and self.item.IsEditable(): + self.edit(event) + else: + self.select(event) + + def edit(self, event=None): + self.entry = Entry(self.label, bd=0, highlightthickness=1, width=0) + self.entry.insert(0, self.label['text']) + self.entry.selection_range(0, END) + self.entry.pack(ipadx=5) + self.entry.focus_set() + self.entry.bind("", self.edit_finish) + self.entry.bind("", self.edit_cancel) + + def edit_finish(self, event=None): + try: + entry = self.entry + del self.entry + except AttributeError: + return + text = entry.get() + entry.destroy() + if text and text != self.item.GetText(): + self.item.SetText(text) + text = self.item.GetText() + self.label['text'] = text + self.drawtext() + self.canvas.focus_set() + + def edit_cancel(self, event=None): + try: + entry = self.entry + del self.entry + except AttributeError: + return + entry.destroy() + self.drawtext() + self.canvas.focus_set() + + +class TreeItem: + + """Abstract class representing tree items. + + Methods should typically be overridden, otherwise a default action + is used. + + """ + + def __init__(self): + """Constructor. Do whatever you need to do.""" + + def GetText(self): + """Return text string to display.""" + + def GetLabelText(self): + """Return label text string to display in front of text (if any).""" + + expandable = None + + def _IsExpandable(self): + """Do not override! Called by TreeNode.""" + if self.expandable is None: + self.expandable = self.IsExpandable() + return self.expandable + + def IsExpandable(self): + """Return whether there are subitems.""" + return 1 + + def _GetSubList(self): + """Do not override! Called by TreeNode.""" + if not self.IsExpandable(): + return [] + sublist = self.GetSubList() + if not sublist: + self.expandable = 0 + return sublist + + def IsEditable(self): + """Return whether the item's text may be edited.""" + + def SetText(self, text): + """Change the item's text (if it is editable).""" + + def GetIconName(self): + """Return name of icon to be displayed normally.""" + + def GetSelectedIconName(self): + """Return name of icon to be displayed when selected.""" + + def GetSubList(self): + """Return list of items forming sublist.""" + + def OnDoubleClick(self): + """Called on a double-click on the item.""" + + +# Example application + +class FileTreeItem(TreeItem): + + """Example TreeItem subclass -- browse the file system.""" + + def __init__(self, path): + self.path = path + + def GetText(self): + return os.path.basename(self.path) or self.path + + def IsEditable(self): + return os.path.basename(self.path) != "" + + def SetText(self, text): + newpath = os.path.dirname(self.path) + newpath = os.path.join(newpath, text) + if os.path.dirname(newpath) != os.path.dirname(self.path): + return + try: + os.rename(self.path, newpath) + self.path = newpath + except os.error: + pass + + def GetIconName(self): + if not self.IsExpandable(): + return "python" # XXX wish there was a "file" icon + + def IsExpandable(self): + return os.path.isdir(self.path) + + def GetSubList(self): + try: + names = os.listdir(self.path) + except os.error: + return [] + names.sort(key = os.path.normcase) + sublist = [] + for name in names: + item = FileTreeItem(os.path.join(self.path, name)) + sublist.append(item) + return sublist + + +# A canvas widget with scroll bars and some useful bindings + +class ScrolledCanvas: + def __init__(self, master, **opts): + if 'yscrollincrement' not in opts: + opts['yscrollincrement'] = 17 + self.master = master + self.frame = Frame(master) + self.frame.rowconfigure(0, weight=1) + self.frame.columnconfigure(0, weight=1) + self.canvas = Canvas(self.frame, **opts) + self.canvas.grid(row=0, column=0, sticky="nsew") + self.vbar = Scrollbar(self.frame, name="vbar") + self.vbar.grid(row=0, column=1, sticky="nse") + self.hbar = Scrollbar(self.frame, name="hbar", orient="horizontal") + self.hbar.grid(row=1, column=0, sticky="ews") + self.canvas['yscrollcommand'] = self.vbar.set + self.vbar['command'] = self.canvas.yview + self.canvas['xscrollcommand'] = self.hbar.set + self.hbar['command'] = self.canvas.xview + self.canvas.bind("", self.page_up) + self.canvas.bind("", self.page_down) + self.canvas.bind("", self.unit_up) + self.canvas.bind("", self.unit_down) + #if isinstance(master, Toplevel) or isinstance(master, Tk): + self.canvas.bind("", self.zoom_height) + self.canvas.focus_set() + def page_up(self, event): + self.canvas.yview_scroll(-1, "page") + return "break" + def page_down(self, event): + self.canvas.yview_scroll(1, "page") + return "break" + def unit_up(self, event): + self.canvas.yview_scroll(-1, "unit") + return "break" + def unit_down(self, event): + self.canvas.yview_scroll(1, "unit") + return "break" + def zoom_height(self, event): + ZoomHeight.zoom_height(self.master) + return "break" + + +def _tree_widget(parent): + root = Tk() + root.title("Test TreeWidget") + width, height, x, y = list(map(int, re.split('[x+]', parent.geometry()))) + root.geometry("+%d+%d"%(x, y + 150)) + sc = ScrolledCanvas(root, bg="white", highlightthickness=0, takefocus=1) + sc.frame.pack(expand=1, fill="both", side=LEFT) + item = FileTreeItem(os.getcwd()) + node = TreeNode(sc.canvas, None, item) + node.expand() + root.mainloop() + +if __name__ == '__main__': + from idlelib.idle_test.htest import run + run(_tree_widget) diff --git a/PythonHome/Lib/idlelib/TreeWidget.pyc b/PythonHome/Lib/idlelib/TreeWidget.pyc deleted file mode 100644 index 993dfce69922be29c697ade936e46e867ba1d329..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 16916 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 O%)<2JIH|;D=l=mBj^R)M diff --git a/PythonHome/Lib/idlelib/UndoDelegator.py b/PythonHome/Lib/idlelib/UndoDelegator.py new file mode 100644 index 0000000000..cdeacea32f --- /dev/null +++ b/PythonHome/Lib/idlelib/UndoDelegator.py @@ -0,0 +1,365 @@ +import string +from Tkinter import * + +from idlelib.Delegator import Delegator + +#$ event <> +#$ win +#$ unix + +#$ event <> +#$ win +#$ unix + +#$ event <> +#$ win +#$ unix + + +class UndoDelegator(Delegator): + + max_undo = 1000 + + def __init__(self): + Delegator.__init__(self) + self.reset_undo() + + def setdelegate(self, delegate): + if self.delegate is not None: + self.unbind("<>") + self.unbind("<>") + self.unbind("<>") + Delegator.setdelegate(self, delegate) + if delegate is not None: + self.bind("<>", self.undo_event) + self.bind("<>", self.redo_event) + self.bind("<>", self.dump_event) + + def dump_event(self, event): + from pprint import pprint + pprint(self.undolist[:self.pointer]) + print "pointer:", self.pointer, + print "saved:", self.saved, + print "can_merge:", self.can_merge, + print "get_saved():", self.get_saved() + pprint(self.undolist[self.pointer:]) + return "break" + + def reset_undo(self): + self.was_saved = -1 + self.pointer = 0 + self.undolist = [] + self.undoblock = 0 # or a CommandSequence instance + self.set_saved(1) + + def set_saved(self, flag): + if flag: + self.saved = self.pointer + else: + self.saved = -1 + self.can_merge = False + self.check_saved() + + def get_saved(self): + return self.saved == self.pointer + + saved_change_hook = None + + def set_saved_change_hook(self, hook): + self.saved_change_hook = hook + + was_saved = -1 + + def check_saved(self): + is_saved = self.get_saved() + if is_saved != self.was_saved: + self.was_saved = is_saved + if self.saved_change_hook: + self.saved_change_hook() + + def insert(self, index, chars, tags=None): + self.addcmd(InsertCommand(index, chars, tags)) + + def delete(self, index1, index2=None): + self.addcmd(DeleteCommand(index1, index2)) + + # Clients should call undo_block_start() and undo_block_stop() + # around a sequence of editing cmds to be treated as a unit by + # undo & redo. Nested matching calls are OK, and the inner calls + # then act like nops. OK too if no editing cmds, or only one + # editing cmd, is issued in between: if no cmds, the whole + # sequence has no effect; and if only one cmd, that cmd is entered + # directly into the undo list, as if undo_block_xxx hadn't been + # called. The intent of all that is to make this scheme easy + # to use: all the client has to worry about is making sure each + # _start() call is matched by a _stop() call. + + def undo_block_start(self): + if self.undoblock == 0: + self.undoblock = CommandSequence() + self.undoblock.bump_depth() + + def undo_block_stop(self): + if self.undoblock.bump_depth(-1) == 0: + cmd = self.undoblock + self.undoblock = 0 + if len(cmd) > 0: + if len(cmd) == 1: + # no need to wrap a single cmd + cmd = cmd.getcmd(0) + # this blk of cmds, or single cmd, has already + # been done, so don't execute it again + self.addcmd(cmd, 0) + + def addcmd(self, cmd, execute=True): + if execute: + cmd.do(self.delegate) + if self.undoblock != 0: + self.undoblock.append(cmd) + return + if self.can_merge and self.pointer > 0: + lastcmd = self.undolist[self.pointer-1] + if lastcmd.merge(cmd): + return + self.undolist[self.pointer:] = [cmd] + if self.saved > self.pointer: + self.saved = -1 + self.pointer = self.pointer + 1 + if len(self.undolist) > self.max_undo: + ##print "truncating undo list" + del self.undolist[0] + self.pointer = self.pointer - 1 + if self.saved >= 0: + self.saved = self.saved - 1 + self.can_merge = True + self.check_saved() + + def undo_event(self, event): + if self.pointer == 0: + self.bell() + return "break" + cmd = self.undolist[self.pointer - 1] + cmd.undo(self.delegate) + self.pointer = self.pointer - 1 + self.can_merge = False + self.check_saved() + return "break" + + def redo_event(self, event): + if self.pointer >= len(self.undolist): + self.bell() + return "break" + cmd = self.undolist[self.pointer] + cmd.redo(self.delegate) + self.pointer = self.pointer + 1 + self.can_merge = False + self.check_saved() + return "break" + + +class Command: + + # Base class for Undoable commands + + tags = None + + def __init__(self, index1, index2, chars, tags=None): + self.marks_before = {} + self.marks_after = {} + self.index1 = index1 + self.index2 = index2 + self.chars = chars + if tags: + self.tags = tags + + def __repr__(self): + s = self.__class__.__name__ + t = (self.index1, self.index2, self.chars, self.tags) + if self.tags is None: + t = t[:-1] + return s + repr(t) + + def do(self, text): + pass + + def redo(self, text): + pass + + def undo(self, text): + pass + + def merge(self, cmd): + return 0 + + def save_marks(self, text): + marks = {} + for name in text.mark_names(): + if name != "insert" and name != "current": + marks[name] = text.index(name) + return marks + + def set_marks(self, text, marks): + for name, index in marks.items(): + text.mark_set(name, index) + + +class InsertCommand(Command): + + # Undoable insert command + + def __init__(self, index1, chars, tags=None): + Command.__init__(self, index1, None, chars, tags) + + def do(self, text): + self.marks_before = self.save_marks(text) + self.index1 = text.index(self.index1) + if text.compare(self.index1, ">", "end-1c"): + # Insert before the final newline + self.index1 = text.index("end-1c") + text.insert(self.index1, self.chars, self.tags) + self.index2 = text.index("%s+%dc" % (self.index1, len(self.chars))) + self.marks_after = self.save_marks(text) + ##sys.__stderr__.write("do: %s\n" % self) + + def redo(self, text): + text.mark_set('insert', self.index1) + text.insert(self.index1, self.chars, self.tags) + self.set_marks(text, self.marks_after) + text.see('insert') + ##sys.__stderr__.write("redo: %s\n" % self) + + def undo(self, text): + text.mark_set('insert', self.index1) + text.delete(self.index1, self.index2) + self.set_marks(text, self.marks_before) + text.see('insert') + ##sys.__stderr__.write("undo: %s\n" % self) + + def merge(self, cmd): + if self.__class__ is not cmd.__class__: + return False + if self.index2 != cmd.index1: + return False + if self.tags != cmd.tags: + return False + if len(cmd.chars) != 1: + return False + if self.chars and \ + self.classify(self.chars[-1]) != self.classify(cmd.chars): + return False + self.index2 = cmd.index2 + self.chars = self.chars + cmd.chars + return True + + alphanumeric = string.ascii_letters + string.digits + "_" + + def classify(self, c): + if c in self.alphanumeric: + return "alphanumeric" + if c == "\n": + return "newline" + return "punctuation" + + +class DeleteCommand(Command): + + # Undoable delete command + + def __init__(self, index1, index2=None): + Command.__init__(self, index1, index2, None, None) + + def do(self, text): + self.marks_before = self.save_marks(text) + self.index1 = text.index(self.index1) + if self.index2: + self.index2 = text.index(self.index2) + else: + self.index2 = text.index(self.index1 + " +1c") + if text.compare(self.index2, ">", "end-1c"): + # Don't delete the final newline + self.index2 = text.index("end-1c") + self.chars = text.get(self.index1, self.index2) + text.delete(self.index1, self.index2) + self.marks_after = self.save_marks(text) + ##sys.__stderr__.write("do: %s\n" % self) + + def redo(self, text): + text.mark_set('insert', self.index1) + text.delete(self.index1, self.index2) + self.set_marks(text, self.marks_after) + text.see('insert') + ##sys.__stderr__.write("redo: %s\n" % self) + + def undo(self, text): + text.mark_set('insert', self.index1) + text.insert(self.index1, self.chars) + self.set_marks(text, self.marks_before) + text.see('insert') + ##sys.__stderr__.write("undo: %s\n" % self) + +class CommandSequence(Command): + + # Wrapper for a sequence of undoable cmds to be undone/redone + # as a unit + + def __init__(self): + self.cmds = [] + self.depth = 0 + + def __repr__(self): + s = self.__class__.__name__ + strs = [] + for cmd in self.cmds: + strs.append(" %r" % (cmd,)) + return s + "(\n" + ",\n".join(strs) + "\n)" + + def __len__(self): + return len(self.cmds) + + def append(self, cmd): + self.cmds.append(cmd) + + def getcmd(self, i): + return self.cmds[i] + + def redo(self, text): + for cmd in self.cmds: + cmd.redo(text) + + def undo(self, text): + cmds = self.cmds[:] + cmds.reverse() + for cmd in cmds: + cmd.undo(text) + + def bump_depth(self, incr=1): + self.depth = self.depth + incr + return self.depth + +def _undo_delegator(parent): + from idlelib.Percolator import Percolator + root = Tk() + root.title("Test UndoDelegator") + width, height, x, y = list(map(int, re.split('[x+]', parent.geometry()))) + root.geometry("+%d+%d"%(x, y + 150)) + + text = Text(root) + text.config(height=10) + text.pack() + text.focus_set() + p = Percolator(text) + d = UndoDelegator() + p.insertfilter(d) + + undo = Button(root, text="Undo", command=lambda:d.undo_event(None)) + undo.pack(side='left') + redo = Button(root, text="Redo", command=lambda:d.redo_event(None)) + redo.pack(side='left') + dump = Button(root, text="Dump", command=lambda:d.dump_event(None)) + dump.pack(side='left') + + root.mainloop() + +if __name__ == "__main__": + from idlelib.idle_test.htest import run + run(_undo_delegator) diff --git a/PythonHome/Lib/idlelib/UndoDelegator.pyc b/PythonHome/Lib/idlelib/UndoDelegator.pyc deleted file mode 100644 index d392d2606d257cf15c75eee80d38af806d324c02..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 12790 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 BN*DkD diff --git a/PythonHome/Lib/idlelib/WidgetRedirector.py b/PythonHome/Lib/idlelib/WidgetRedirector.py new file mode 100644 index 0000000000..b1534a71b2 --- /dev/null +++ b/PythonHome/Lib/idlelib/WidgetRedirector.py @@ -0,0 +1,125 @@ +from Tkinter import * + +class WidgetRedirector: + + """Support for redirecting arbitrary widget subcommands. + + Some Tk operations don't normally pass through Tkinter. For example, if a + character is inserted into a Text widget by pressing a key, a default Tk + binding to the widget's 'insert' operation is activated, and the Tk library + processes the insert without calling back into Tkinter. + + Although a binding to could be made via Tkinter, what we really want + to do is to hook the Tk 'insert' operation itself. + + When a widget is instantiated, a Tcl command is created whose name is the + same as the pathname widget._w. This command is used to invoke the various + widget operations, e.g. insert (for a Text widget). We are going to hook + this command and provide a facility ('register') to intercept the widget + operation. + + In IDLE, the function being registered provides access to the top of a + Percolator chain. At the bottom of the chain is a call to the original + Tk widget operation. + + """ + def __init__(self, widget): + self._operations = {} + self.widget = widget # widget instance + self.tk = tk = widget.tk # widget's root + w = widget._w # widget's (full) Tk pathname + self.orig = w + "_orig" + # Rename the Tcl command within Tcl: + tk.call("rename", w, self.orig) + # Create a new Tcl command whose name is the widget's pathname, and + # whose action is to dispatch on the operation passed to the widget: + tk.createcommand(w, self.dispatch) + + def __repr__(self): + return "WidgetRedirector(%s<%s>)" % (self.widget.__class__.__name__, + self.widget._w) + + def close(self): + for operation in list(self._operations): + self.unregister(operation) + widget = self.widget; del self.widget + orig = self.orig; del self.orig + tk = widget.tk + w = widget._w + tk.deletecommand(w) + # restore the original widget Tcl command: + tk.call("rename", orig, w) + + def register(self, operation, function): + self._operations[operation] = function + setattr(self.widget, operation, function) + return OriginalCommand(self, operation) + + def unregister(self, operation): + if operation in self._operations: + function = self._operations[operation] + del self._operations[operation] + if hasattr(self.widget, operation): + delattr(self.widget, operation) + return function + else: + return None + + def dispatch(self, operation, *args): + '''Callback from Tcl which runs when the widget is referenced. + + If an operation has been registered in self._operations, apply the + associated function to the args passed into Tcl. Otherwise, pass the + operation through to Tk via the original Tcl function. + + Note that if a registered function is called, the operation is not + passed through to Tk. Apply the function returned by self.register() + to *args to accomplish that. For an example, see ColorDelegator.py. + + ''' + m = self._operations.get(operation) + try: + if m: + return m(*args) + else: + return self.tk.call((self.orig, operation) + args) + except TclError: + return "" + + +class OriginalCommand: + + def __init__(self, redir, operation): + self.redir = redir + self.operation = operation + self.tk = redir.tk + self.orig = redir.orig + self.tk_call = self.tk.call + self.orig_and_operation = (self.orig, self.operation) + + def __repr__(self): + return "OriginalCommand(%r, %r)" % (self.redir, self.operation) + + def __call__(self, *args): + return self.tk_call(self.orig_and_operation + args) + + +def _widget_redirector(parent): + root = Tk() + root.title("Test WidgetRedirector") + width, height, x, y = list(map(int, re.split('[x+]', parent.geometry()))) + root.geometry("+%d+%d"%(x, y + 150)) + text = Text(root) + text.pack() + text.focus_set() + redir = WidgetRedirector(text) + global previous_tcl_fcn + def my_insert(*args): + print "insert", args + previous_tcl_fcn(*args) + previous_tcl_fcn = redir.register("insert", my_insert) + root.mainloop() + +if __name__ == "__main__": + from idlelib.idle_test.htest import run + run(_widget_redirector) diff --git a/PythonHome/Lib/idlelib/WidgetRedirector.pyc b/PythonHome/Lib/idlelib/WidgetRedirector.pyc deleted file mode 100644 index 4fb60b164d61ed1cc92083885bf8115f22261216..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5341 zcmbVQ-EP~+6&^~mY$^8UuT8ow3QVx|T25R6MbVog4R+Vrrok?pf->ON^@63zkwl9k zRdQsJ zRehTH{|r|-L=)rZsZ^=MxS`^%iks?NrQRv^`(sbVEfwEU@!H}MrnGr;+*Af*>uS``D~UK zRuA(+7uC*5Hqv2nn%E*NF7<_QrOWwgluxH&7MJ~QSK~9tr$!%6bUrghXp=lEb)08A zR%dxJ4b${e&%(0Qc3kB1(HJw6%$lOF^{=s)c^gh=soB%XP=`V;8iz#~VTMjhon)mc ztclUFxeoQAd24GXZWhrdxiMiavgxCzjd1|qX5Iaq>nB!P%$EI4jQ|cW@cxTBp zcf+>Hd5G;mDT`$VGLvc*S9jMxIKDRo8u-xo4j3$oZT2=?t=PBm_ zf>5vU_53Sy`9eqeJdO3K(bF(C`aFTC4yQeRF%BWKfm#I2i!igo3uKCOvW?C-&nGp% z-zA$ZO**Xfbu=~^Sg7>rK(-*7RFdn%C`LCq|e)4~rz9mqM>%YiUe-+Vn^L8tWbn^ndJN zx37=DL1FYLuT)Jm97L;oQ>D<~c>;h#Jq)8HP3)!a?G$E|lrXrRUB?%?k(pUx&9NiI z7A#dbzRvXPmtTLmC-a8$491gZP$8M9NkY_WOIjCAr#3~K&vahf{BN;io`&#s4f9Vj z!1lS@|1`HYpK>M*P6owN#n@_Ed6A5gEKG$>SnN#oi$X8PaEpGA@@yn-BediMw-VQXsN4)IzxEDFb0%5YpHil8<1PuMz1h5mfi-s_Ku7!B8ZGTF)X>Z6Zs1+Ecq7-?9k)v7CU02m6cgi zjFS@P7>#?JC#&cJJ~{BYxy0Lx9(qce@(FtVldqH0lO#?Joc`qKMjYYrH zzFof96*+``+rhLTh*Ct=AgDMZl0o1zo=ZCMnO#0my28wgAovsnN`j}nyPn8I*!VzX z`ZGFjf1<2d4`f1Sd-=^nb?w9yqhYf9(>--WSz$kTrqmy6W1%_Wwzi{d*J-QkHFece zXY1-}jWj*pYzTT-fJd;gmjW0?OMW3Qmeh-cE9(nh@j%vG0EGVK-ycSsh6gO}z zXEX55=P+L02+9~BC|2;qAY5)BCUD?PM(~h4Z)|97;cVzGNWQ7U#=Z;A;-ezE|9y;# zVbx*ny+tM1HT=Ioza*~8+wvZI5{7CS_c?Zi#zi0a$E2-_H%nPRc6NgS%=p!+;1IO< zN;$b56pS{gu7JpZHo~hyLfn3V#5gRMNDvy>0UwAF9pst00fqlD=DaTi{zEMKC9Wz& z+=cL6?*Ra4H3R~(L%v>d&IuZ)U-%NW=rQ14{*0lt*p`6WP=AF$PVew1cHlG~BM2mZ zj1_~U?15?_%1*kfI8vVHA?gf%hZyYwaM^;_>?3AMg)%IVSeWZC#z{2R#ThRb1B)hR2{*>iAvN}vl$A)x_BTdM6o=Q z+C$gYR_C>_7?n~y3N_RW;I^;dV0Ceklqedj!qQbDB(~TJTexzQt0q!VQLH*sirn>f zD{>v=mL&-aF4m)~($tfsA_9ag5`|)&vpA6Dt~4VnU<(5C}S2mt0^7DZmTXu`DO!UNZlBT1yw_x27Z{Fk_#cWgfJnqJ%M zHlDysB%u2|30cPRAeiRyJVko5^wl7U^9ZSqiPyi+<`EkvV{tj3l$Y#C?{>-Euama$ z)P97ZyxD1W?sV2VU7xu*!X+P0`~p|`2^v!$#J>GMXEB_!i0>k^{gOXN!XiBSZ7TZ$q{^9MjZv=v8+cAF0-!MDEB{e;j%W|cp zDMIj9knz=T00{n(o>yv9Il{Qt3}P7aY6mYY&Uw@gY?KDWD3cNYgA9XOnO@>3!Z##y zveZID_wsk~-(!U*ho-}cgaMn_)cACBXbDThnf&9$ip)Y1qDhs=D^`qdWbj_c7MD^K z@x6<5W_Y(DmGLl-AV!ItA)Y4T_bG{Q2=OFK^L*w?bK1@f2XyR27KPChUrVAzMVZ=${Ju3B(|V_riL`eU~K jXBb1nB_dEACaSHt}l<=-A diff --git a/PythonHome/Lib/idlelib/WindowList.py b/PythonHome/Lib/idlelib/WindowList.py new file mode 100644 index 0000000000..658502b20b --- /dev/null +++ b/PythonHome/Lib/idlelib/WindowList.py @@ -0,0 +1,90 @@ +from Tkinter import * + +class WindowList: + + def __init__(self): + self.dict = {} + self.callbacks = [] + + def add(self, window): + window.after_idle(self.call_callbacks) + self.dict[str(window)] = window + + def delete(self, window): + try: + del self.dict[str(window)] + except KeyError: + # Sometimes, destroy() is called twice + pass + self.call_callbacks() + + def add_windows_to_menu(self, menu): + list = [] + for key in self.dict.keys(): + window = self.dict[key] + try: + title = window.get_title() + except TclError: + continue + list.append((title, window)) + list.sort() + for title, window in list: + menu.add_command(label=title, command=window.wakeup) + + def register_callback(self, callback): + self.callbacks.append(callback) + + def unregister_callback(self, callback): + try: + self.callbacks.remove(callback) + except ValueError: + pass + + def call_callbacks(self): + for callback in self.callbacks: + try: + callback() + except: + print "warning: callback failed in WindowList", \ + sys.exc_type, ":", sys.exc_value + +registry = WindowList() + +add_windows_to_menu = registry.add_windows_to_menu +register_callback = registry.register_callback +unregister_callback = registry.unregister_callback + + +class ListedToplevel(Toplevel): + + def __init__(self, master, **kw): + Toplevel.__init__(self, master, kw) + registry.add(self) + self.focused_widget = self + + def destroy(self): + registry.delete(self) + Toplevel.destroy(self) + # If this is Idle's last window then quit the mainloop + # (Needed for clean exit on Windows 98) + if not registry.dict: + self.quit() + + def update_windowlist_registry(self, window): + registry.call_callbacks() + + def get_title(self): + # Subclass can override + return self.wm_title() + + def wakeup(self): + try: + if self.wm_state() == "iconic": + self.wm_withdraw() + self.wm_deiconify() + self.tkraise() + self.focused_widget.focus_set() + except TclError: + # This can happen when the window menu was torn off. + # Simply ignore it. + pass diff --git a/PythonHome/Lib/idlelib/WindowList.pyc b/PythonHome/Lib/idlelib/WindowList.pyc deleted file mode 100644 index 7570f208dde14a3b2670a0f5d5418a3019b0ac36..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3411 zcmbVO>uwuG6h5tttK z$5QgEybABYd+`A9eP``BElA*|o$=YZoa=Yanefln${(Fyw!1R@3-S8}hWiOqivLD( zk)1Satsx6m&y+M$-D(O|WUmc6%B8 zv%m1yHlRGG5B&<}PFAGD@x#pdGo`qB55sL@vJeV}LWYnI1xbVg6-m^lT2|7z(wIu$ zRmoggmT0@Z1YTWo<_IwEW4J4rGLaLJSY*E&};I zWTY1xSQ%?X7O;nGk~F1rrlzdUO`(Bm%4Z-ZYpS{epi=#Ar?@CJA4q>i%4=ebDU3X# zeIfB?Ua(B{j_5%3;sZPRsw{_P#OTh=h^Wc}2GHu%!cn#b$`O`gLbGOCL9MccCpgrS z-$4K?r-2;*Jhg|R5!rbBt(+n#&>jH`<&D#tOjhNj#%N*xv@V@u4d#Yw?sqiz=!&St z$f}y0)Oomv!-z9>Iwx4Jt0RtY2tGC*UzNRpjKG?}0NMcuq+Xz6mT)#ON5|4p$A!>z z%QFOd^2FwzZt4yPgQQ3`BP$p%@_jpT3h#aEW1o3AgI?b0=IUTiToxP8yNY4u(&ymV_UYd}KAAb88}2 zs|Bo}^GC%$?6`_$N5o7M$7rpkVFZA>djrJr-Kobn9)B#SMkW{3@wnAFT46c>&70^B z$d^q(TFFp0zsBYxjB}`V?}ObqDT}Pwzr8+l=Xx*6a+|Ja#rnMFYPY$ql~LoV2z0791*f`dh#PML5j&giP zjC;i56Y*~JCa1SKy~9aM9Eb&i6|p4{2#y_~5j1P~x7=(s!)8O90^6=lcZP?#eQNVA z4(T7S-NSI7VzTI<3pQZ1TiT-SjN%D_2N>=KCXec<9Sj+ViuNoNgYu7Zk5tt5rb!v2 zvCo?txmEROs;c@*S1Kfy6Lp*#)f;w4&ZhA=OHs_)RAAoR1_{#-0#Sp;{~z`$?+z|G zRyIL7X;lb+?ltiVw$99>EzcRootn5?ngLZ&FZ9thYu#EjsZ$mIYvjhLrxs0mIGGpg zqfzFy-K$*-SiyqwCB`&UTc#DBdv(y3``jg3Dm$LR)^l;7+alFa(Wsvc?xGEs&>kJ8 ziMNOn-+ycj@hp_zV0Ts%sncwzZp@FWXhXM|=XgTVFdkIR>!rN23N8;ZD%pWnFmfjP zRQ4W-$;Mnfid8?5^180*3&2n{?ezw+Mjv2P3!COd?5vO2g4uGVI#WAi7tzXw&*4&UWv$Hj#Z`p>!}>E$lu1$HyH|8 z9px)**0w4>%h*wSclud@wAOl8;q!&!$y`!q3o4+#zf)D{&xr*s>np+KTg{+}7ke}O E8v!<0-~a#s diff --git a/PythonHome/Lib/idlelib/ZoomHeight.py b/PythonHome/Lib/idlelib/ZoomHeight.py new file mode 100644 index 0000000000..a5d679e499 --- /dev/null +++ b/PythonHome/Lib/idlelib/ZoomHeight.py @@ -0,0 +1,51 @@ +# Sample extension: zoom a window to maximum height + +import re +import sys + +from idlelib import macosxSupport + +class ZoomHeight: + + menudefs = [ + ('windows', [ + ('_Zoom Height', '<>'), + ]) + ] + + def __init__(self, editwin): + self.editwin = editwin + + def zoom_height_event(self, event): + top = self.editwin.top + zoom_height(top) + +def zoom_height(top): + geom = top.wm_geometry() + m = re.match(r"(\d+)x(\d+)\+(-?\d+)\+(-?\d+)", geom) + if not m: + top.bell() + return + width, height, x, y = map(int, m.groups()) + newheight = top.winfo_screenheight() + if sys.platform == 'win32': + newy = 0 + newheight = newheight - 72 + + elif macosxSupport.isAquaTk(): + # The '88' below is a magic number that avoids placing the bottom + # of the window below the panel on my machine. I don't know how + # to calculate the correct value for this with tkinter. + newy = 22 + newheight = newheight - newy - 88 + + else: + #newy = 24 + newy = 0 + #newheight = newheight - 96 + newheight = newheight - 88 + if height >= newheight: + newgeom = "" + else: + newgeom = "%dx%d+%d+%d" % (width, newheight, x, newy) + top.wm_geometry(newgeom) diff --git a/PythonHome/Lib/idlelib/ZoomHeight.pyc b/PythonHome/Lib/idlelib/ZoomHeight.pyc deleted file mode 100644 index 75b3692f572c184d9667a698dda82dd7fda8b5e5..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1571 zcmb7E&2G~`5T3Q2q-j(2Pbw7%2@XX@r9HIQs{CDgKs`7}KorS@?51_hnAjNEbn-Bc6NTg{nq}k#rf}V-Z#56dwhJKVc0_mjaN}h)VkCa zwUpRBNvRiy-W&}E z#n8EVSXxDq9h&6$#9b@r1(xg+2m_Zgd4-M@^*oj>kC2{op$Mq}*`sDy#RkWD&yrjh zXVx~L$DHCpnZqu@u)qHqmhBVCdT`M7VEa2>LbqJ$M9~C$1%swEFl&Ru8=W|$2zi$a zc#BDU5yKc_l)~PFw$px+H7UMVz3vRgZVu~loaBj%<7McUqmhzwI22E%oV!p^ zOCPVIsYlMEiANU-XF$N2!95Cjhg9HLbH%_d;LDB1Wuv7B7wakz=99@?#DM)r$t%}G z#u8)=M$2(YHIzVdE7(J>Vg^Fq$xIvzAL2MG^eE*i1C*J3q)pF8>>br1uF4hdCYU3J zha*`QRo_=jLEZ1NmFdS}1>~PlN{}yzriz@RK3E18D7x?%c3^II#m8sD3-~yEpox`! zm2Gfr2Q>9*3R$6PRorX5G_7&7{W@unPCXiaVFpjdz1PVbr{bhdml1v z>#fJ*uTa2RBnZJYXhQ*X%|^34+po@Mc|DKg`R zV-Odu83~tlT=zuo&IgmGLfWh|kZ+PZ$HY7y7Ndc6t5A`=SH!kEG$t?UES`33g(ZWu z<9fv~i{M&vDzVQ$jykVTLq24ox#Z$XaI)altS9YGB-bn`FP)3S*fBV{Ih(C8!7&@l z?*$4+5(0|2k%j!%xPxIILGVRcRaG^w0`(C367)r{5mePmQ1#|vse9|HjLtwr{CkLa myJVmJPNZ3(cf`@Jin&!qg4=$1*A9H_m;2FB4R6_7Tlxd;jw+r2 diff --git a/PythonHome/Lib/idlelib/__init__.py b/PythonHome/Lib/idlelib/__init__.py new file mode 100644 index 0000000000..7a83ddea76 --- /dev/null +++ b/PythonHome/Lib/idlelib/__init__.py @@ -0,0 +1 @@ +# Dummy file to make this a package. diff --git a/PythonHome/Lib/idlelib/__init__.pyc b/PythonHome/Lib/idlelib/__init__.pyc deleted file mode 100644 index e56d5ddf451eff22316099eee1af91af8e13a155..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 112 zcmZSn%*(YSJRvxl0SXv_v;z',self.Ok) #dismiss dialog + self.bind('',self.Ok) #dismiss dialog + self.wait_window() + + def CreateWidgets(self): + frameMain = Frame(self, borderwidth=2, relief=SUNKEN) + frameButtons = Frame(self) + frameButtons.pack(side=BOTTOM, fill=X) + frameMain.pack(side=TOP, expand=TRUE, fill=BOTH) + self.buttonOk = Button(frameButtons, text='Close', + command=self.Ok) + self.buttonOk.pack(padx=5, pady=5) + #self.picture = Image('photo', data=self.pictureData) + frameBg = Frame(frameMain, bg=self.bg) + frameBg.pack(expand=TRUE, fill=BOTH) + labelTitle = Label(frameBg, text='IDLE', fg=self.fg, bg=self.bg, + font=('courier', 24, 'bold')) + labelTitle.grid(row=0, column=0, sticky=W, padx=10, pady=10) + #labelPicture = Label(frameBg, text='[picture]') + #image=self.picture, bg=self.bg) + #labelPicture.grid(row=1, column=1, sticky=W, rowspan=2, + # padx=0, pady=3) + byline = "Python's Integrated DeveLopment Environment" + 5*'\n' + labelDesc = Label(frameBg, text=byline, justify=LEFT, + fg=self.fg, bg=self.bg) + labelDesc.grid(row=2, column=0, sticky=W, columnspan=3, padx=10, pady=5) + labelEmail = Label(frameBg, text='email: idle-dev@python.org', + justify=LEFT, fg=self.fg, bg=self.bg) + labelEmail.grid(row=6, column=0, columnspan=2, + sticky=W, padx=10, pady=0) + labelWWW = Label(frameBg, text='www: http://www.python.org/idle/', + justify=LEFT, fg=self.fg, bg=self.bg) + labelWWW.grid(row=7, column=0, columnspan=2, sticky=W, padx=10, pady=0) + Frame(frameBg, borderwidth=1, relief=SUNKEN, + height=2, bg=self.bg).grid(row=8, column=0, sticky=EW, + columnspan=3, padx=5, pady=5) + labelPythonVer = Label(frameBg, text='Python version: ' + \ + sys.version.split()[0], fg=self.fg, bg=self.bg) + labelPythonVer.grid(row=9, column=0, sticky=W, padx=10, pady=0) + tkVer = self.tk.call('info', 'patchlevel') + labelTkVer = Label(frameBg, text='Tk version: '+ + tkVer, fg=self.fg, bg=self.bg) + labelTkVer.grid(row=9, column=1, sticky=W, padx=2, pady=0) + py_button_f = Frame(frameBg, bg=self.bg) + py_button_f.grid(row=10, column=0, columnspan=2, sticky=NSEW) + buttonLicense = Button(py_button_f, text='License', width=8, + highlightbackground=self.bg, + command=self.ShowLicense) + buttonLicense.pack(side=LEFT, padx=10, pady=10) + buttonCopyright = Button(py_button_f, text='Copyright', width=8, + highlightbackground=self.bg, + command=self.ShowCopyright) + buttonCopyright.pack(side=LEFT, padx=10, pady=10) + buttonCredits = Button(py_button_f, text='Credits', width=8, + highlightbackground=self.bg, + command=self.ShowPythonCredits) + buttonCredits.pack(side=LEFT, padx=10, pady=10) + Frame(frameBg, borderwidth=1, relief=SUNKEN, + height=2, bg=self.bg).grid(row=11, column=0, sticky=EW, + columnspan=3, padx=5, pady=5) + idle_v = Label(frameBg, text='IDLE version: ' + idlever.IDLE_VERSION, + fg=self.fg, bg=self.bg) + idle_v.grid(row=12, column=0, sticky=W, padx=10, pady=0) + idle_button_f = Frame(frameBg, bg=self.bg) + idle_button_f.grid(row=13, column=0, columnspan=3, sticky=NSEW) + idle_about_b = Button(idle_button_f, text='README', width=8, + highlightbackground=self.bg, + command=self.ShowIDLEAbout) + idle_about_b.pack(side=LEFT, padx=10, pady=10) + idle_news_b = Button(idle_button_f, text='NEWS', width=8, + highlightbackground=self.bg, + command=self.ShowIDLENEWS) + idle_news_b.pack(side=LEFT, padx=10, pady=10) + idle_credits_b = Button(idle_button_f, text='Credits', width=8, + highlightbackground=self.bg, + command=self.ShowIDLECredits) + idle_credits_b.pack(side=LEFT, padx=10, pady=10) + + def ShowLicense(self): + self.display_printer_text('About - License', license) + + def ShowCopyright(self): + self.display_printer_text('About - Copyright', copyright) + + def ShowPythonCredits(self): + self.display_printer_text('About - Python Credits', credits) + + def ShowIDLECredits(self): + self.display_file_text('About - Credits', 'CREDITS.txt', 'iso-8859-1') + + def ShowIDLEAbout(self): + self.display_file_text('About - Readme', 'README.txt') + + def ShowIDLENEWS(self): + self.display_file_text('About - NEWS', 'NEWS.txt') + + def display_printer_text(self, title, printer): + printer._Printer__setup() + text = '\n'.join(printer._Printer__lines) + textView.view_text(self, title, text) + + def display_file_text(self, title, filename, encoding=None): + fn = os.path.join(os.path.abspath(os.path.dirname(__file__)), filename) + textView.view_file(self, title, fn, encoding) + + def Ok(self, event=None): + self.destroy() + +if __name__ == '__main__': + from idlelib.idle_test.htest import run + run(AboutDialog) diff --git a/PythonHome/Lib/idlelib/aboutDialog.pyc b/PythonHome/Lib/idlelib/aboutDialog.pyc deleted file mode 100644 index 5074eaaa162bfe3db802adf55fb82891db763b3f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6448 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 Ur1ayNf;FAtL*U}eX=~2',self.Cancel) #dismiss dialog, no save + #self.bind('',self.Apply) #apply changes, save + #self.bind('',self.Help) #context help + self.LoadConfigs() + self.AttachVarCallbacks() #avoid callbacks during LoadConfigs + + self.wm_deiconify() + self.wait_window() + + def CreateWidgets(self): + self.tabPages = TabbedPageSet(self, + page_names=['Fonts/Tabs','Highlighting','Keys','General']) + frameActionButtons = Frame(self,pady=2) + #action buttons + if macosxSupport.isAquaTk(): + # Changing the default padding on OSX results in unreadable + # text in the buttons + paddingArgs={} + else: + paddingArgs={'padx':6, 'pady':3} + +# Comment out button creation and packing until implement self.Help +## self.buttonHelp = Button(frameActionButtons,text='Help', +## command=self.Help,takefocus=FALSE, +## **paddingArgs) + self.buttonOk = Button(frameActionButtons,text='Ok', + command=self.Ok,takefocus=FALSE, + **paddingArgs) + self.buttonApply = Button(frameActionButtons,text='Apply', + command=self.Apply,takefocus=FALSE, + **paddingArgs) + self.buttonCancel = Button(frameActionButtons,text='Cancel', + command=self.Cancel,takefocus=FALSE, + **paddingArgs) + self.CreatePageFontTab() + self.CreatePageHighlight() + self.CreatePageKeys() + self.CreatePageGeneral() +## self.buttonHelp.pack(side=RIGHT,padx=5) + self.buttonOk.pack(side=LEFT,padx=5) + self.buttonApply.pack(side=LEFT,padx=5) + self.buttonCancel.pack(side=LEFT,padx=5) + frameActionButtons.pack(side=BOTTOM) + Frame(self, height=2, borderwidth=0).pack(side=BOTTOM) + self.tabPages.pack(side=TOP,expand=TRUE,fill=BOTH) + + def CreatePageFontTab(self): + #tkVars + self.fontSize=StringVar(self) + self.fontBold=BooleanVar(self) + self.fontName=StringVar(self) + self.spaceNum=IntVar(self) + self.editFont=tkFont.Font(self,('courier',10,'normal')) + ##widget creation + #body frame + frame=self.tabPages.pages['Fonts/Tabs'].frame + #body section frames + frameFont=LabelFrame(frame,borderwidth=2,relief=GROOVE, + text=' Base Editor Font ') + frameIndent=LabelFrame(frame,borderwidth=2,relief=GROOVE, + text=' Indentation Width ') + #frameFont + frameFontName=Frame(frameFont) + frameFontParam=Frame(frameFont) + labelFontNameTitle=Label(frameFontName,justify=LEFT, + text='Font Face :') + self.listFontName=Listbox(frameFontName,height=5,takefocus=FALSE, + exportselection=FALSE) + self.listFontName.bind('',self.OnListFontButtonRelease) + scrollFont=Scrollbar(frameFontName) + scrollFont.config(command=self.listFontName.yview) + self.listFontName.config(yscrollcommand=scrollFont.set) + labelFontSizeTitle=Label(frameFontParam,text='Size :') + self.optMenuFontSize=DynOptionMenu(frameFontParam,self.fontSize,None, + command=self.SetFontSample) + checkFontBold=Checkbutton(frameFontParam,variable=self.fontBold, + onvalue=1,offvalue=0,text='Bold',command=self.SetFontSample) + frameFontSample=Frame(frameFont,relief=SOLID,borderwidth=1) + self.labelFontSample=Label(frameFontSample, + text='AaBbCcDdEe\nFfGgHhIiJjK\n1234567890\n#:+=(){}[]', + justify=LEFT,font=self.editFont) + #frameIndent + frameIndentSize=Frame(frameIndent) + labelSpaceNumTitle=Label(frameIndentSize, justify=LEFT, + text='Python Standard: 4 Spaces!') + self.scaleSpaceNum=Scale(frameIndentSize, variable=self.spaceNum, + orient='horizontal', + tickinterval=2, from_=2, to=16) + #widget packing + #body + frameFont.pack(side=LEFT,padx=5,pady=5,expand=TRUE,fill=BOTH) + frameIndent.pack(side=LEFT,padx=5,pady=5,fill=Y) + #frameFont + frameFontName.pack(side=TOP,padx=5,pady=5,fill=X) + frameFontParam.pack(side=TOP,padx=5,pady=5,fill=X) + labelFontNameTitle.pack(side=TOP,anchor=W) + self.listFontName.pack(side=LEFT,expand=TRUE,fill=X) + scrollFont.pack(side=LEFT,fill=Y) + labelFontSizeTitle.pack(side=LEFT,anchor=W) + self.optMenuFontSize.pack(side=LEFT,anchor=W) + checkFontBold.pack(side=LEFT,anchor=W,padx=20) + frameFontSample.pack(side=TOP,padx=5,pady=5,expand=TRUE,fill=BOTH) + self.labelFontSample.pack(expand=TRUE,fill=BOTH) + #frameIndent + frameIndentSize.pack(side=TOP,fill=X) + labelSpaceNumTitle.pack(side=TOP,anchor=W,padx=5) + self.scaleSpaceNum.pack(side=TOP,padx=5,fill=X) + return frame + + def CreatePageHighlight(self): + self.builtinTheme=StringVar(self) + self.customTheme=StringVar(self) + self.fgHilite=BooleanVar(self) + self.colour=StringVar(self) + self.fontName=StringVar(self) + self.themeIsBuiltin=BooleanVar(self) + self.highlightTarget=StringVar(self) + ##widget creation + #body frame + frame=self.tabPages.pages['Highlighting'].frame + #body section frames + frameCustom=LabelFrame(frame,borderwidth=2,relief=GROOVE, + text=' Custom Highlighting ') + frameTheme=LabelFrame(frame,borderwidth=2,relief=GROOVE, + text=' Highlighting Theme ') + #frameCustom + self.textHighlightSample=Text(frameCustom,relief=SOLID,borderwidth=1, + font=('courier',12,''),cursor='hand2',width=21,height=11, + takefocus=FALSE,highlightthickness=0,wrap=NONE) + text=self.textHighlightSample + text.bind('',lambda e: 'break') + text.bind('',lambda e: 'break') + textAndTags=(('#you can click here','comment'),('\n','normal'), + ('#to choose items','comment'),('\n','normal'),('def','keyword'), + (' ','normal'),('func','definition'),('(param):','normal'), + ('\n ','normal'),('"""string"""','string'),('\n var0 = ','normal'), + ("'string'",'string'),('\n var1 = ','normal'),("'selected'",'hilite'), + ('\n var2 = ','normal'),("'found'",'hit'), + ('\n var3 = ','normal'),('list', 'builtin'), ('(','normal'), + ('None', 'builtin'),(')\n\n','normal'), + (' error ','error'),(' ','normal'),('cursor |','cursor'), + ('\n ','normal'),('shell','console'),(' ','normal'),('stdout','stdout'), + (' ','normal'),('stderr','stderr'),('\n','normal')) + for txTa in textAndTags: + text.insert(END,txTa[0],txTa[1]) + for element in self.themeElements.keys(): + text.tag_bind(self.themeElements[element][0],'', + lambda event,elem=element: event.widget.winfo_toplevel() + .highlightTarget.set(elem)) + text.config(state=DISABLED) + self.frameColourSet=Frame(frameCustom,relief=SOLID,borderwidth=1) + frameFgBg=Frame(frameCustom) + buttonSetColour=Button(self.frameColourSet,text='Choose Colour for :', + command=self.GetColour,highlightthickness=0) + self.optMenuHighlightTarget=DynOptionMenu(self.frameColourSet, + self.highlightTarget,None,highlightthickness=0)#,command=self.SetHighlightTargetBinding + self.radioFg=Radiobutton(frameFgBg,variable=self.fgHilite, + value=1,text='Foreground',command=self.SetColourSampleBinding) + self.radioBg=Radiobutton(frameFgBg,variable=self.fgHilite, + value=0,text='Background',command=self.SetColourSampleBinding) + self.fgHilite.set(1) + buttonSaveCustomTheme=Button(frameCustom, + text='Save as New Custom Theme',command=self.SaveAsNewTheme) + #frameTheme + labelTypeTitle=Label(frameTheme,text='Select : ') + self.radioThemeBuiltin=Radiobutton(frameTheme,variable=self.themeIsBuiltin, + value=1,command=self.SetThemeType,text='a Built-in Theme') + self.radioThemeCustom=Radiobutton(frameTheme,variable=self.themeIsBuiltin, + value=0,command=self.SetThemeType,text='a Custom Theme') + self.optMenuThemeBuiltin=DynOptionMenu(frameTheme, + self.builtinTheme,None,command=None) + self.optMenuThemeCustom=DynOptionMenu(frameTheme, + self.customTheme,None,command=None) + self.buttonDeleteCustomTheme=Button(frameTheme,text='Delete Custom Theme', + command=self.DeleteCustomTheme) + ##widget packing + #body + frameCustom.pack(side=LEFT,padx=5,pady=5,expand=TRUE,fill=BOTH) + frameTheme.pack(side=LEFT,padx=5,pady=5,fill=Y) + #frameCustom + self.frameColourSet.pack(side=TOP,padx=5,pady=5,expand=TRUE,fill=X) + frameFgBg.pack(side=TOP,padx=5,pady=0) + self.textHighlightSample.pack(side=TOP,padx=5,pady=5,expand=TRUE, + fill=BOTH) + buttonSetColour.pack(side=TOP,expand=TRUE,fill=X,padx=8,pady=4) + self.optMenuHighlightTarget.pack(side=TOP,expand=TRUE,fill=X,padx=8,pady=3) + self.radioFg.pack(side=LEFT,anchor=E) + self.radioBg.pack(side=RIGHT,anchor=W) + buttonSaveCustomTheme.pack(side=BOTTOM,fill=X,padx=5,pady=5) + #frameTheme + labelTypeTitle.pack(side=TOP,anchor=W,padx=5,pady=5) + self.radioThemeBuiltin.pack(side=TOP,anchor=W,padx=5) + self.radioThemeCustom.pack(side=TOP,anchor=W,padx=5,pady=2) + self.optMenuThemeBuiltin.pack(side=TOP,fill=X,padx=5,pady=5) + self.optMenuThemeCustom.pack(side=TOP,fill=X,anchor=W,padx=5,pady=5) + self.buttonDeleteCustomTheme.pack(side=TOP,fill=X,padx=5,pady=5) + return frame + + def CreatePageKeys(self): + #tkVars + self.bindingTarget=StringVar(self) + self.builtinKeys=StringVar(self) + self.customKeys=StringVar(self) + self.keysAreBuiltin=BooleanVar(self) + self.keyBinding=StringVar(self) + ##widget creation + #body frame + frame=self.tabPages.pages['Keys'].frame + #body section frames + frameCustom=LabelFrame(frame,borderwidth=2,relief=GROOVE, + text=' Custom Key Bindings ') + frameKeySets=LabelFrame(frame,borderwidth=2,relief=GROOVE, + text=' Key Set ') + #frameCustom + frameTarget=Frame(frameCustom) + labelTargetTitle=Label(frameTarget,text='Action - Key(s)') + scrollTargetY=Scrollbar(frameTarget) + scrollTargetX=Scrollbar(frameTarget,orient=HORIZONTAL) + self.listBindings=Listbox(frameTarget,takefocus=FALSE, + exportselection=FALSE) + self.listBindings.bind('',self.KeyBindingSelected) + scrollTargetY.config(command=self.listBindings.yview) + scrollTargetX.config(command=self.listBindings.xview) + self.listBindings.config(yscrollcommand=scrollTargetY.set) + self.listBindings.config(xscrollcommand=scrollTargetX.set) + self.buttonNewKeys=Button(frameCustom,text='Get New Keys for Selection', + command=self.GetNewKeys,state=DISABLED) + #frameKeySets + frames = [Frame(frameKeySets, padx=2, pady=2, borderwidth=0) + for i in range(2)] + self.radioKeysBuiltin=Radiobutton(frames[0],variable=self.keysAreBuiltin, + value=1,command=self.SetKeysType,text='Use a Built-in Key Set') + self.radioKeysCustom=Radiobutton(frames[0],variable=self.keysAreBuiltin, + value=0,command=self.SetKeysType,text='Use a Custom Key Set') + self.optMenuKeysBuiltin=DynOptionMenu(frames[0], + self.builtinKeys,None,command=None) + self.optMenuKeysCustom=DynOptionMenu(frames[0], + self.customKeys,None,command=None) + self.buttonDeleteCustomKeys=Button(frames[1],text='Delete Custom Key Set', + command=self.DeleteCustomKeys) + buttonSaveCustomKeys=Button(frames[1], + text='Save as New Custom Key Set',command=self.SaveAsNewKeySet) + ##widget packing + #body + frameCustom.pack(side=BOTTOM,padx=5,pady=5,expand=TRUE,fill=BOTH) + frameKeySets.pack(side=BOTTOM,padx=5,pady=5,fill=BOTH) + #frameCustom + self.buttonNewKeys.pack(side=BOTTOM,fill=X,padx=5,pady=5) + frameTarget.pack(side=LEFT,padx=5,pady=5,expand=TRUE,fill=BOTH) + #frame target + frameTarget.columnconfigure(0,weight=1) + frameTarget.rowconfigure(1,weight=1) + labelTargetTitle.grid(row=0,column=0,columnspan=2,sticky=W) + self.listBindings.grid(row=1,column=0,sticky=NSEW) + scrollTargetY.grid(row=1,column=1,sticky=NS) + scrollTargetX.grid(row=2,column=0,sticky=EW) + #frameKeySets + self.radioKeysBuiltin.grid(row=0, column=0, sticky=W+NS) + self.radioKeysCustom.grid(row=1, column=0, sticky=W+NS) + self.optMenuKeysBuiltin.grid(row=0, column=1, sticky=NSEW) + self.optMenuKeysCustom.grid(row=1, column=1, sticky=NSEW) + self.buttonDeleteCustomKeys.pack(side=LEFT,fill=X,expand=True,padx=2) + buttonSaveCustomKeys.pack(side=LEFT,fill=X,expand=True,padx=2) + frames[0].pack(side=TOP, fill=BOTH, expand=True) + frames[1].pack(side=TOP, fill=X, expand=True, pady=2) + return frame + + def CreatePageGeneral(self): + #tkVars + self.winWidth=StringVar(self) + self.winHeight=StringVar(self) + self.paraWidth=StringVar(self) + self.startupEdit=IntVar(self) + self.autoSave=IntVar(self) + self.encoding=StringVar(self) + self.userHelpBrowser=BooleanVar(self) + self.helpBrowser=StringVar(self) + #widget creation + #body + frame=self.tabPages.pages['General'].frame + #body section frames + frameRun=LabelFrame(frame,borderwidth=2,relief=GROOVE, + text=' Startup Preferences ') + frameSave=LabelFrame(frame,borderwidth=2,relief=GROOVE, + text=' Autosave Preferences ') + frameWinSize=Frame(frame,borderwidth=2,relief=GROOVE) + frameParaSize=Frame(frame,borderwidth=2,relief=GROOVE) + frameEncoding=Frame(frame,borderwidth=2,relief=GROOVE) + frameHelp=LabelFrame(frame,borderwidth=2,relief=GROOVE, + text=' Additional Help Sources ') + #frameRun + labelRunChoiceTitle=Label(frameRun,text='At Startup') + radioStartupEdit=Radiobutton(frameRun,variable=self.startupEdit, + value=1,command=self.SetKeysType,text="Open Edit Window") + radioStartupShell=Radiobutton(frameRun,variable=self.startupEdit, + value=0,command=self.SetKeysType,text='Open Shell Window') + #frameSave + labelRunSaveTitle=Label(frameSave,text='At Start of Run (F5) ') + radioSaveAsk=Radiobutton(frameSave,variable=self.autoSave, + value=0,command=self.SetKeysType,text="Prompt to Save") + radioSaveAuto=Radiobutton(frameSave,variable=self.autoSave, + value=1,command=self.SetKeysType,text='No Prompt') + #frameWinSize + labelWinSizeTitle=Label(frameWinSize,text='Initial Window Size'+ + ' (in characters)') + labelWinWidthTitle=Label(frameWinSize,text='Width') + entryWinWidth=Entry(frameWinSize,textvariable=self.winWidth, + width=3) + labelWinHeightTitle=Label(frameWinSize,text='Height') + entryWinHeight=Entry(frameWinSize,textvariable=self.winHeight, + width=3) + #paragraphFormatWidth + labelParaWidthTitle=Label(frameParaSize,text='Paragraph reformat'+ + ' width (in characters)') + entryParaWidth=Entry(frameParaSize,textvariable=self.paraWidth, + width=3) + #frameEncoding + labelEncodingTitle=Label(frameEncoding,text="Default Source Encoding") + radioEncLocale=Radiobutton(frameEncoding,variable=self.encoding, + value="locale",text="Locale-defined") + radioEncUTF8=Radiobutton(frameEncoding,variable=self.encoding, + value="utf-8",text="UTF-8") + radioEncNone=Radiobutton(frameEncoding,variable=self.encoding, + value="none",text="None") + #frameHelp + frameHelpList=Frame(frameHelp) + frameHelpListButtons=Frame(frameHelpList) + scrollHelpList=Scrollbar(frameHelpList) + self.listHelp=Listbox(frameHelpList,height=5,takefocus=FALSE, + exportselection=FALSE) + scrollHelpList.config(command=self.listHelp.yview) + self.listHelp.config(yscrollcommand=scrollHelpList.set) + self.listHelp.bind('',self.HelpSourceSelected) + self.buttonHelpListEdit=Button(frameHelpListButtons,text='Edit', + state=DISABLED,width=8,command=self.HelpListItemEdit) + self.buttonHelpListAdd=Button(frameHelpListButtons,text='Add', + width=8,command=self.HelpListItemAdd) + self.buttonHelpListRemove=Button(frameHelpListButtons,text='Remove', + state=DISABLED,width=8,command=self.HelpListItemRemove) + #widget packing + #body + frameRun.pack(side=TOP,padx=5,pady=5,fill=X) + frameSave.pack(side=TOP,padx=5,pady=5,fill=X) + frameWinSize.pack(side=TOP,padx=5,pady=5,fill=X) + frameParaSize.pack(side=TOP,padx=5,pady=5,fill=X) + frameEncoding.pack(side=TOP,padx=5,pady=5,fill=X) + frameHelp.pack(side=TOP,padx=5,pady=5,expand=TRUE,fill=BOTH) + #frameRun + labelRunChoiceTitle.pack(side=LEFT,anchor=W,padx=5,pady=5) + radioStartupShell.pack(side=RIGHT,anchor=W,padx=5,pady=5) + radioStartupEdit.pack(side=RIGHT,anchor=W,padx=5,pady=5) + #frameSave + labelRunSaveTitle.pack(side=LEFT,anchor=W,padx=5,pady=5) + radioSaveAuto.pack(side=RIGHT,anchor=W,padx=5,pady=5) + radioSaveAsk.pack(side=RIGHT,anchor=W,padx=5,pady=5) + #frameWinSize + labelWinSizeTitle.pack(side=LEFT,anchor=W,padx=5,pady=5) + entryWinHeight.pack(side=RIGHT,anchor=E,padx=10,pady=5) + labelWinHeightTitle.pack(side=RIGHT,anchor=E,pady=5) + entryWinWidth.pack(side=RIGHT,anchor=E,padx=10,pady=5) + labelWinWidthTitle.pack(side=RIGHT,anchor=E,pady=5) + #paragraphFormatWidth + labelParaWidthTitle.pack(side=LEFT,anchor=W,padx=5,pady=5) + entryParaWidth.pack(side=RIGHT,anchor=E,padx=10,pady=5) + #frameEncoding + labelEncodingTitle.pack(side=LEFT,anchor=W,padx=5,pady=5) + radioEncNone.pack(side=RIGHT,anchor=E,pady=5) + radioEncUTF8.pack(side=RIGHT,anchor=E,pady=5) + radioEncLocale.pack(side=RIGHT,anchor=E,pady=5) + #frameHelp + frameHelpListButtons.pack(side=RIGHT,padx=5,pady=5,fill=Y) + frameHelpList.pack(side=TOP,padx=5,pady=5,expand=TRUE,fill=BOTH) + scrollHelpList.pack(side=RIGHT,anchor=W,fill=Y) + self.listHelp.pack(side=LEFT,anchor=E,expand=TRUE,fill=BOTH) + self.buttonHelpListEdit.pack(side=TOP,anchor=W,pady=5) + self.buttonHelpListAdd.pack(side=TOP,anchor=W) + self.buttonHelpListRemove.pack(side=TOP,anchor=W,pady=5) + return frame + + def AttachVarCallbacks(self): + self.fontSize.trace_variable('w',self.VarChanged_fontSize) + self.fontName.trace_variable('w',self.VarChanged_fontName) + self.fontBold.trace_variable('w',self.VarChanged_fontBold) + self.spaceNum.trace_variable('w',self.VarChanged_spaceNum) + self.colour.trace_variable('w',self.VarChanged_colour) + self.builtinTheme.trace_variable('w',self.VarChanged_builtinTheme) + self.customTheme.trace_variable('w',self.VarChanged_customTheme) + self.themeIsBuiltin.trace_variable('w',self.VarChanged_themeIsBuiltin) + self.highlightTarget.trace_variable('w',self.VarChanged_highlightTarget) + self.keyBinding.trace_variable('w',self.VarChanged_keyBinding) + self.builtinKeys.trace_variable('w',self.VarChanged_builtinKeys) + self.customKeys.trace_variable('w',self.VarChanged_customKeys) + self.keysAreBuiltin.trace_variable('w',self.VarChanged_keysAreBuiltin) + self.winWidth.trace_variable('w',self.VarChanged_winWidth) + self.winHeight.trace_variable('w',self.VarChanged_winHeight) + self.paraWidth.trace_variable('w',self.VarChanged_paraWidth) + self.startupEdit.trace_variable('w',self.VarChanged_startupEdit) + self.autoSave.trace_variable('w',self.VarChanged_autoSave) + self.encoding.trace_variable('w',self.VarChanged_encoding) + + def VarChanged_fontSize(self,*params): + value=self.fontSize.get() + self.AddChangedItem('main','EditorWindow','font-size',value) + + def VarChanged_fontName(self,*params): + value=self.fontName.get() + self.AddChangedItem('main','EditorWindow','font',value) + + def VarChanged_fontBold(self,*params): + value=self.fontBold.get() + self.AddChangedItem('main','EditorWindow','font-bold',value) + + def VarChanged_spaceNum(self,*params): + value=self.spaceNum.get() + self.AddChangedItem('main','Indent','num-spaces',value) + + def VarChanged_colour(self,*params): + self.OnNewColourSet() + + def VarChanged_builtinTheme(self,*params): + value=self.builtinTheme.get() + self.AddChangedItem('main','Theme','name',value) + self.PaintThemeSample() + + def VarChanged_customTheme(self,*params): + value=self.customTheme.get() + if value != '- no custom themes -': + self.AddChangedItem('main','Theme','name',value) + self.PaintThemeSample() + + def VarChanged_themeIsBuiltin(self,*params): + value=self.themeIsBuiltin.get() + self.AddChangedItem('main','Theme','default',value) + if value: + self.VarChanged_builtinTheme() + else: + self.VarChanged_customTheme() + + def VarChanged_highlightTarget(self,*params): + self.SetHighlightTarget() + + def VarChanged_keyBinding(self,*params): + value=self.keyBinding.get() + keySet=self.customKeys.get() + event=self.listBindings.get(ANCHOR).split()[0] + if idleConf.IsCoreBinding(event): + #this is a core keybinding + self.AddChangedItem('keys',keySet,event,value) + else: #this is an extension key binding + extName=idleConf.GetExtnNameForEvent(event) + extKeybindSection=extName+'_cfgBindings' + self.AddChangedItem('extensions',extKeybindSection,event,value) + + def VarChanged_builtinKeys(self,*params): + value=self.builtinKeys.get() + self.AddChangedItem('main','Keys','name',value) + self.LoadKeysList(value) + + def VarChanged_customKeys(self,*params): + value=self.customKeys.get() + if value != '- no custom keys -': + self.AddChangedItem('main','Keys','name',value) + self.LoadKeysList(value) + + def VarChanged_keysAreBuiltin(self,*params): + value=self.keysAreBuiltin.get() + self.AddChangedItem('main','Keys','default',value) + if value: + self.VarChanged_builtinKeys() + else: + self.VarChanged_customKeys() + + def VarChanged_winWidth(self,*params): + value=self.winWidth.get() + self.AddChangedItem('main','EditorWindow','width',value) + + def VarChanged_winHeight(self,*params): + value=self.winHeight.get() + self.AddChangedItem('main','EditorWindow','height',value) + + def VarChanged_paraWidth(self,*params): + value=self.paraWidth.get() + self.AddChangedItem('main','FormatParagraph','paragraph',value) + + def VarChanged_startupEdit(self,*params): + value=self.startupEdit.get() + self.AddChangedItem('main','General','editor-on-startup',value) + + def VarChanged_autoSave(self,*params): + value=self.autoSave.get() + self.AddChangedItem('main','General','autosave',value) + + def VarChanged_encoding(self,*params): + value=self.encoding.get() + self.AddChangedItem('main','EditorWindow','encoding',value) + + def ResetChangedItems(self): + #When any config item is changed in this dialog, an entry + #should be made in the relevant section (config type) of this + #dictionary. The key should be the config file section name and the + #value a dictionary, whose key:value pairs are item=value pairs for + #that config file section. + self.changedItems={'main':{},'highlight':{},'keys':{},'extensions':{}} + + def AddChangedItem(self,type,section,item,value): + value=str(value) #make sure we use a string + if section not in self.changedItems[type]: + self.changedItems[type][section]={} + self.changedItems[type][section][item]=value + + def GetDefaultItems(self): + dItems={'main':{},'highlight':{},'keys':{},'extensions':{}} + for configType in dItems.keys(): + sections=idleConf.GetSectionList('default',configType) + for section in sections: + dItems[configType][section]={} + options=idleConf.defaultCfg[configType].GetOptionList(section) + for option in options: + dItems[configType][section][option]=( + idleConf.defaultCfg[configType].Get(section,option)) + return dItems + + def SetThemeType(self): + if self.themeIsBuiltin.get(): + self.optMenuThemeBuiltin.config(state=NORMAL) + self.optMenuThemeCustom.config(state=DISABLED) + self.buttonDeleteCustomTheme.config(state=DISABLED) + else: + self.optMenuThemeBuiltin.config(state=DISABLED) + self.radioThemeCustom.config(state=NORMAL) + self.optMenuThemeCustom.config(state=NORMAL) + self.buttonDeleteCustomTheme.config(state=NORMAL) + + def SetKeysType(self): + if self.keysAreBuiltin.get(): + self.optMenuKeysBuiltin.config(state=NORMAL) + self.optMenuKeysCustom.config(state=DISABLED) + self.buttonDeleteCustomKeys.config(state=DISABLED) + else: + self.optMenuKeysBuiltin.config(state=DISABLED) + self.radioKeysCustom.config(state=NORMAL) + self.optMenuKeysCustom.config(state=NORMAL) + self.buttonDeleteCustomKeys.config(state=NORMAL) + + def GetNewKeys(self): + listIndex=self.listBindings.index(ANCHOR) + binding=self.listBindings.get(listIndex) + bindName=binding.split()[0] #first part, up to first space + if self.keysAreBuiltin.get(): + currentKeySetName=self.builtinKeys.get() + else: + currentKeySetName=self.customKeys.get() + currentBindings=idleConf.GetCurrentKeySet() + if currentKeySetName in self.changedItems['keys'].keys(): #unsaved changes + keySetChanges=self.changedItems['keys'][currentKeySetName] + for event in keySetChanges.keys(): + currentBindings[event]=keySetChanges[event].split() + currentKeySequences=currentBindings.values() + newKeys=GetKeysDialog(self,'Get New Keys',bindName, + currentKeySequences).result + if newKeys: #new keys were specified + if self.keysAreBuiltin.get(): #current key set is a built-in + message=('Your changes will be saved as a new Custom Key Set. '+ + 'Enter a name for your new Custom Key Set below.') + newKeySet=self.GetNewKeysName(message) + if not newKeySet: #user cancelled custom key set creation + self.listBindings.select_set(listIndex) + self.listBindings.select_anchor(listIndex) + return + else: #create new custom key set based on previously active key set + self.CreateNewKeySet(newKeySet) + self.listBindings.delete(listIndex) + self.listBindings.insert(listIndex,bindName+' - '+newKeys) + self.listBindings.select_set(listIndex) + self.listBindings.select_anchor(listIndex) + self.keyBinding.set(newKeys) + else: + self.listBindings.select_set(listIndex) + self.listBindings.select_anchor(listIndex) + + def GetNewKeysName(self,message): + usedNames=(idleConf.GetSectionList('user','keys')+ + idleConf.GetSectionList('default','keys')) + newKeySet=GetCfgSectionNameDialog(self,'New Custom Key Set', + message,usedNames).result + return newKeySet + + def SaveAsNewKeySet(self): + newKeysName=self.GetNewKeysName('New Key Set Name:') + if newKeysName: + self.CreateNewKeySet(newKeysName) + + def KeyBindingSelected(self,event): + self.buttonNewKeys.config(state=NORMAL) + + def CreateNewKeySet(self,newKeySetName): + #creates new custom key set based on the previously active key set, + #and makes the new key set active + if self.keysAreBuiltin.get(): + prevKeySetName=self.builtinKeys.get() + else: + prevKeySetName=self.customKeys.get() + prevKeys=idleConf.GetCoreKeys(prevKeySetName) + newKeys={} + for event in prevKeys.keys(): #add key set to changed items + eventName=event[2:-2] #trim off the angle brackets + binding=string.join(prevKeys[event]) + newKeys[eventName]=binding + #handle any unsaved changes to prev key set + if prevKeySetName in self.changedItems['keys'].keys(): + keySetChanges=self.changedItems['keys'][prevKeySetName] + for event in keySetChanges.keys(): + newKeys[event]=keySetChanges[event] + #save the new theme + self.SaveNewKeySet(newKeySetName,newKeys) + #change gui over to the new key set + customKeyList=idleConf.GetSectionList('user','keys') + customKeyList.sort() + self.optMenuKeysCustom.SetMenu(customKeyList,newKeySetName) + self.keysAreBuiltin.set(0) + self.SetKeysType() + + def LoadKeysList(self,keySetName): + reselect=0 + newKeySet=0 + if self.listBindings.curselection(): + reselect=1 + listIndex=self.listBindings.index(ANCHOR) + keySet=idleConf.GetKeySet(keySetName) + bindNames=keySet.keys() + bindNames.sort() + self.listBindings.delete(0,END) + for bindName in bindNames: + key=string.join(keySet[bindName]) #make key(s) into a string + bindName=bindName[2:-2] #trim off the angle brackets + if keySetName in self.changedItems['keys'].keys(): + #handle any unsaved changes to this key set + if bindName in self.changedItems['keys'][keySetName].keys(): + key=self.changedItems['keys'][keySetName][bindName] + self.listBindings.insert(END, bindName+' - '+key) + if reselect: + self.listBindings.see(listIndex) + self.listBindings.select_set(listIndex) + self.listBindings.select_anchor(listIndex) + + def DeleteCustomKeys(self): + keySetName=self.customKeys.get() + if not tkMessageBox.askyesno('Delete Key Set','Are you sure you wish '+ + 'to delete the key set %r ?' % (keySetName), + parent=self): + return + #remove key set from config + idleConf.userCfg['keys'].remove_section(keySetName) + if keySetName in self.changedItems['keys']: + del(self.changedItems['keys'][keySetName]) + #write changes + idleConf.userCfg['keys'].Save() + #reload user key set list + itemList=idleConf.GetSectionList('user','keys') + itemList.sort() + if not itemList: + self.radioKeysCustom.config(state=DISABLED) + self.optMenuKeysCustom.SetMenu(itemList,'- no custom keys -') + else: + self.optMenuKeysCustom.SetMenu(itemList,itemList[0]) + #revert to default key set + self.keysAreBuiltin.set(idleConf.defaultCfg['main'].Get('Keys','default')) + self.builtinKeys.set(idleConf.defaultCfg['main'].Get('Keys','name')) + #user can't back out of these changes, they must be applied now + self.Apply() + self.SetKeysType() + + def DeleteCustomTheme(self): + themeName=self.customTheme.get() + if not tkMessageBox.askyesno('Delete Theme','Are you sure you wish '+ + 'to delete the theme %r ?' % (themeName,), + parent=self): + return + #remove theme from config + idleConf.userCfg['highlight'].remove_section(themeName) + if themeName in self.changedItems['highlight']: + del(self.changedItems['highlight'][themeName]) + #write changes + idleConf.userCfg['highlight'].Save() + #reload user theme list + itemList=idleConf.GetSectionList('user','highlight') + itemList.sort() + if not itemList: + self.radioThemeCustom.config(state=DISABLED) + self.optMenuThemeCustom.SetMenu(itemList,'- no custom themes -') + else: + self.optMenuThemeCustom.SetMenu(itemList,itemList[0]) + #revert to default theme + self.themeIsBuiltin.set(idleConf.defaultCfg['main'].Get('Theme','default')) + self.builtinTheme.set(idleConf.defaultCfg['main'].Get('Theme','name')) + #user can't back out of these changes, they must be applied now + self.Apply() + self.SetThemeType() + + def GetColour(self): + target=self.highlightTarget.get() + prevColour=self.frameColourSet.cget('bg') + rgbTuplet, colourString = tkColorChooser.askcolor(parent=self, + title='Pick new colour for : '+target,initialcolor=prevColour) + if colourString and (colourString!=prevColour): + #user didn't cancel, and they chose a new colour + if self.themeIsBuiltin.get(): #current theme is a built-in + message=('Your changes will be saved as a new Custom Theme. '+ + 'Enter a name for your new Custom Theme below.') + newTheme=self.GetNewThemeName(message) + if not newTheme: #user cancelled custom theme creation + return + else: #create new custom theme based on previously active theme + self.CreateNewTheme(newTheme) + self.colour.set(colourString) + else: #current theme is user defined + self.colour.set(colourString) + + def OnNewColourSet(self): + newColour=self.colour.get() + self.frameColourSet.config(bg=newColour)#set sample + if self.fgHilite.get(): plane='foreground' + else: plane='background' + sampleElement=self.themeElements[self.highlightTarget.get()][0] + self.textHighlightSample.tag_config(sampleElement, **{plane:newColour}) + theme=self.customTheme.get() + themeElement=sampleElement+'-'+plane + self.AddChangedItem('highlight',theme,themeElement,newColour) + + def GetNewThemeName(self,message): + usedNames=(idleConf.GetSectionList('user','highlight')+ + idleConf.GetSectionList('default','highlight')) + newTheme=GetCfgSectionNameDialog(self,'New Custom Theme', + message,usedNames).result + return newTheme + + def SaveAsNewTheme(self): + newThemeName=self.GetNewThemeName('New Theme Name:') + if newThemeName: + self.CreateNewTheme(newThemeName) + + def CreateNewTheme(self,newThemeName): + #creates new custom theme based on the previously active theme, + #and makes the new theme active + if self.themeIsBuiltin.get(): + themeType='default' + themeName=self.builtinTheme.get() + else: + themeType='user' + themeName=self.customTheme.get() + newTheme=idleConf.GetThemeDict(themeType,themeName) + #apply any of the old theme's unsaved changes to the new theme + if themeName in self.changedItems['highlight'].keys(): + themeChanges=self.changedItems['highlight'][themeName] + for element in themeChanges.keys(): + newTheme[element]=themeChanges[element] + #save the new theme + self.SaveNewTheme(newThemeName,newTheme) + #change gui over to the new theme + customThemeList=idleConf.GetSectionList('user','highlight') + customThemeList.sort() + self.optMenuThemeCustom.SetMenu(customThemeList,newThemeName) + self.themeIsBuiltin.set(0) + self.SetThemeType() + + def OnListFontButtonRelease(self,event): + font = self.listFontName.get(ANCHOR) + self.fontName.set(font.lower()) + self.SetFontSample() + + def SetFontSample(self,event=None): + fontName=self.fontName.get() + if self.fontBold.get(): + fontWeight=tkFont.BOLD + else: + fontWeight=tkFont.NORMAL + newFont = (fontName, self.fontSize.get(), fontWeight) + self.labelFontSample.config(font=newFont) + self.textHighlightSample.configure(font=newFont) + + def SetHighlightTarget(self): + if self.highlightTarget.get()=='Cursor': #bg not possible + self.radioFg.config(state=DISABLED) + self.radioBg.config(state=DISABLED) + self.fgHilite.set(1) + else: #both fg and bg can be set + self.radioFg.config(state=NORMAL) + self.radioBg.config(state=NORMAL) + self.fgHilite.set(1) + self.SetColourSample() + + def SetColourSampleBinding(self,*args): + self.SetColourSample() + + def SetColourSample(self): + #set the colour smaple area + tag=self.themeElements[self.highlightTarget.get()][0] + if self.fgHilite.get(): plane='foreground' + else: plane='background' + colour=self.textHighlightSample.tag_cget(tag,plane) + self.frameColourSet.config(bg=colour) + + def PaintThemeSample(self): + if self.themeIsBuiltin.get(): #a default theme + theme=self.builtinTheme.get() + else: #a user theme + theme=self.customTheme.get() + for elementTitle in self.themeElements.keys(): + element=self.themeElements[elementTitle][0] + colours=idleConf.GetHighlight(theme,element) + if element=='cursor': #cursor sample needs special painting + colours['background']=idleConf.GetHighlight(theme, + 'normal', fgBg='bg') + #handle any unsaved changes to this theme + if theme in self.changedItems['highlight'].keys(): + themeDict=self.changedItems['highlight'][theme] + if element+'-foreground' in themeDict: + colours['foreground']=themeDict[element+'-foreground'] + if element+'-background' in themeDict: + colours['background']=themeDict[element+'-background'] + self.textHighlightSample.tag_config(element, **colours) + self.SetColourSample() + + def HelpSourceSelected(self,event): + self.SetHelpListButtonStates() + + def SetHelpListButtonStates(self): + if self.listHelp.size()<1: #no entries in list + self.buttonHelpListEdit.config(state=DISABLED) + self.buttonHelpListRemove.config(state=DISABLED) + else: #there are some entries + if self.listHelp.curselection(): #there currently is a selection + self.buttonHelpListEdit.config(state=NORMAL) + self.buttonHelpListRemove.config(state=NORMAL) + else: #there currently is not a selection + self.buttonHelpListEdit.config(state=DISABLED) + self.buttonHelpListRemove.config(state=DISABLED) + + def HelpListItemAdd(self): + helpSource=GetHelpSourceDialog(self,'New Help Source').result + if helpSource: + self.userHelpList.append( (helpSource[0],helpSource[1]) ) + self.listHelp.insert(END,helpSource[0]) + self.UpdateUserHelpChangedItems() + self.SetHelpListButtonStates() + + def HelpListItemEdit(self): + itemIndex=self.listHelp.index(ANCHOR) + helpSource=self.userHelpList[itemIndex] + newHelpSource=GetHelpSourceDialog(self,'Edit Help Source', + menuItem=helpSource[0],filePath=helpSource[1]).result + if (not newHelpSource) or (newHelpSource==helpSource): + return #no changes + self.userHelpList[itemIndex]=newHelpSource + self.listHelp.delete(itemIndex) + self.listHelp.insert(itemIndex,newHelpSource[0]) + self.UpdateUserHelpChangedItems() + self.SetHelpListButtonStates() + + def HelpListItemRemove(self): + itemIndex=self.listHelp.index(ANCHOR) + del(self.userHelpList[itemIndex]) + self.listHelp.delete(itemIndex) + self.UpdateUserHelpChangedItems() + self.SetHelpListButtonStates() + + def UpdateUserHelpChangedItems(self): + "Clear and rebuild the HelpFiles section in self.changedItems" + self.changedItems['main']['HelpFiles'] = {} + for num in range(1,len(self.userHelpList)+1): + self.AddChangedItem('main','HelpFiles',str(num), + string.join(self.userHelpList[num-1][:2],';')) + + def LoadFontCfg(self): + ##base editor font selection list + fonts=list(tkFont.families(self)) + fonts.sort() + for font in fonts: + self.listFontName.insert(END,font) + configuredFont=idleConf.GetOption('main','EditorWindow','font', + default='courier') + lc_configuredFont = configuredFont.lower() + self.fontName.set(lc_configuredFont) + lc_fonts = [s.lower() for s in fonts] + if lc_configuredFont in lc_fonts: + currentFontIndex = lc_fonts.index(lc_configuredFont) + self.listFontName.see(currentFontIndex) + self.listFontName.select_set(currentFontIndex) + self.listFontName.select_anchor(currentFontIndex) + ##font size dropdown + fontSize=idleConf.GetOption('main','EditorWindow','font-size', + type='int', default='10') + self.optMenuFontSize.SetMenu(('7','8','9','10','11','12','13','14', + '16','18','20','22'),fontSize ) + ##fontWeight + self.fontBold.set(idleConf.GetOption('main','EditorWindow', + 'font-bold',default=0,type='bool')) + ##font sample + self.SetFontSample() + + def LoadTabCfg(self): + ##indent sizes + spaceNum=idleConf.GetOption('main','Indent','num-spaces', + default=4,type='int') + self.spaceNum.set(spaceNum) + + def LoadThemeCfg(self): + ##current theme type radiobutton + self.themeIsBuiltin.set(idleConf.GetOption('main','Theme','default', + type='bool',default=1)) + ##currently set theme + currentOption=idleConf.CurrentTheme() + ##load available theme option menus + if self.themeIsBuiltin.get(): #default theme selected + itemList=idleConf.GetSectionList('default','highlight') + itemList.sort() + self.optMenuThemeBuiltin.SetMenu(itemList,currentOption) + itemList=idleConf.GetSectionList('user','highlight') + itemList.sort() + if not itemList: + self.radioThemeCustom.config(state=DISABLED) + self.customTheme.set('- no custom themes -') + else: + self.optMenuThemeCustom.SetMenu(itemList,itemList[0]) + else: #user theme selected + itemList=idleConf.GetSectionList('user','highlight') + itemList.sort() + self.optMenuThemeCustom.SetMenu(itemList,currentOption) + itemList=idleConf.GetSectionList('default','highlight') + itemList.sort() + self.optMenuThemeBuiltin.SetMenu(itemList,itemList[0]) + self.SetThemeType() + ##load theme element option menu + themeNames=self.themeElements.keys() + themeNames.sort(key=lambda x: self.themeElements[x][1]) + self.optMenuHighlightTarget.SetMenu(themeNames,themeNames[0]) + self.PaintThemeSample() + self.SetHighlightTarget() + + def LoadKeyCfg(self): + ##current keys type radiobutton + self.keysAreBuiltin.set(idleConf.GetOption('main','Keys','default', + type='bool',default=1)) + ##currently set keys + currentOption=idleConf.CurrentKeys() + ##load available keyset option menus + if self.keysAreBuiltin.get(): #default theme selected + itemList=idleConf.GetSectionList('default','keys') + itemList.sort() + self.optMenuKeysBuiltin.SetMenu(itemList,currentOption) + itemList=idleConf.GetSectionList('user','keys') + itemList.sort() + if not itemList: + self.radioKeysCustom.config(state=DISABLED) + self.customKeys.set('- no custom keys -') + else: + self.optMenuKeysCustom.SetMenu(itemList,itemList[0]) + else: #user key set selected + itemList=idleConf.GetSectionList('user','keys') + itemList.sort() + self.optMenuKeysCustom.SetMenu(itemList,currentOption) + itemList=idleConf.GetSectionList('default','keys') + itemList.sort() + self.optMenuKeysBuiltin.SetMenu(itemList,itemList[0]) + self.SetKeysType() + ##load keyset element list + keySetName=idleConf.CurrentKeys() + self.LoadKeysList(keySetName) + + def LoadGeneralCfg(self): + #startup state + self.startupEdit.set(idleConf.GetOption('main','General', + 'editor-on-startup',default=1,type='bool')) + #autosave state + self.autoSave.set(idleConf.GetOption('main', 'General', 'autosave', + default=0, type='bool')) + #initial window size + self.winWidth.set(idleConf.GetOption('main','EditorWindow','width', + type='int')) + self.winHeight.set(idleConf.GetOption('main','EditorWindow','height', + type='int')) + #initial paragraph reformat size + self.paraWidth.set(idleConf.GetOption('main','FormatParagraph','paragraph', + type='int')) + # default source encoding + self.encoding.set(idleConf.GetOption('main', 'EditorWindow', + 'encoding', default='none')) + # additional help sources + self.userHelpList = idleConf.GetAllExtraHelpSourcesList() + for helpItem in self.userHelpList: + self.listHelp.insert(END,helpItem[0]) + self.SetHelpListButtonStates() + + def LoadConfigs(self): + """ + load configuration from default and user config files and populate + the widgets on the config dialog pages. + """ + ### fonts / tabs page + self.LoadFontCfg() + self.LoadTabCfg() + ### highlighting page + self.LoadThemeCfg() + ### keys page + self.LoadKeyCfg() + ### general page + self.LoadGeneralCfg() + + def SaveNewKeySet(self,keySetName,keySet): + """ + save a newly created core key set. + keySetName - string, the name of the new key set + keySet - dictionary containing the new key set + """ + if not idleConf.userCfg['keys'].has_section(keySetName): + idleConf.userCfg['keys'].add_section(keySetName) + for event in keySet.keys(): + value=keySet[event] + idleConf.userCfg['keys'].SetOption(keySetName,event,value) + + def SaveNewTheme(self,themeName,theme): + """ + save a newly created theme. + themeName - string, the name of the new theme + theme - dictionary containing the new theme + """ + if not idleConf.userCfg['highlight'].has_section(themeName): + idleConf.userCfg['highlight'].add_section(themeName) + for element in theme.keys(): + value=theme[element] + idleConf.userCfg['highlight'].SetOption(themeName,element,value) + + def SetUserValue(self,configType,section,item,value): + if idleConf.defaultCfg[configType].has_option(section,item): + if idleConf.defaultCfg[configType].Get(section,item)==value: + #the setting equals a default setting, remove it from user cfg + return idleConf.userCfg[configType].RemoveOption(section,item) + #if we got here set the option + return idleConf.userCfg[configType].SetOption(section,item,value) + + def SaveAllChangedConfigs(self): + "Save configuration changes to the user config file." + idleConf.userCfg['main'].Save() + for configType in self.changedItems.keys(): + cfgTypeHasChanges = False + for section in self.changedItems[configType].keys(): + if section == 'HelpFiles': + #this section gets completely replaced + idleConf.userCfg['main'].remove_section('HelpFiles') + cfgTypeHasChanges = True + for item in self.changedItems[configType][section].keys(): + value = self.changedItems[configType][section][item] + if self.SetUserValue(configType,section,item,value): + cfgTypeHasChanges = True + if cfgTypeHasChanges: + idleConf.userCfg[configType].Save() + for configType in ['keys', 'highlight']: + # save these even if unchanged! + idleConf.userCfg[configType].Save() + self.ResetChangedItems() #clear the changed items dict + + def DeactivateCurrentConfig(self): + #Before a config is saved, some cleanup of current + #config must be done - remove the previous keybindings + winInstances=self.parent.instance_dict.keys() + for instance in winInstances: + instance.RemoveKeybindings() + + def ActivateConfigChanges(self): + "Dynamically apply configuration changes" + winInstances=self.parent.instance_dict.keys() + for instance in winInstances: + instance.ResetColorizer() + instance.ResetFont() + instance.set_notabs_indentwidth() + instance.ApplyKeybindings() + instance.reset_help_menu_entries() + + def Cancel(self): + self.destroy() + + def Ok(self): + self.Apply() + self.destroy() + + def Apply(self): + self.DeactivateCurrentConfig() + self.SaveAllChangedConfigs() + self.ActivateConfigChanges() + + def Help(self): + pass + +if __name__ == '__main__': + from idlelib.idle_test.htest import run + run(ConfigDialog) diff --git a/PythonHome/Lib/idlelib/configDialog.pyc b/PythonHome/Lib/idlelib/configDialog.pyc deleted file mode 100644 index 4d8a8c1ad02b50663b7c9f1e2e4b171525419e14..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 43516 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�s>O6;%xa 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 diff --git a/PythonHome/Lib/idlelib/configHandler.py b/PythonHome/Lib/idlelib/configHandler.py new file mode 100644 index 0000000000..67ab1f653d --- /dev/null +++ b/PythonHome/Lib/idlelib/configHandler.py @@ -0,0 +1,721 @@ +"""Provides access to stored IDLE configuration information. + +Refer to the comments at the beginning of config-main.def for a description of +the available configuration files and the design implemented to update user +configuration information. In particular, user configuration choices which +duplicate the defaults will be removed from the user's configuration files, +and if a file becomes empty, it will be deleted. + +The contents of the user files may be altered using the Options/Configure IDLE +menu to access the configuration GUI (configDialog.py), or manually. + +Throughout this module there is an emphasis on returning useable defaults +when a problem occurs in returning a requested configuration value back to +idle. This is to allow IDLE to continue to function in spite of errors in +the retrieval of config information. When a default is returned instead of +a requested config value, a message is printed to stderr to aid in +configuration problem notification and resolution. + +""" +import os +import sys +import string +from ConfigParser import ConfigParser, NoOptionError, NoSectionError + +class InvalidConfigType(Exception): pass +class InvalidConfigSet(Exception): pass +class InvalidFgBg(Exception): pass +class InvalidTheme(Exception): pass + +class IdleConfParser(ConfigParser): + """ + A ConfigParser specialised for idle configuration file handling + """ + def __init__(self, cfgFile, cfgDefaults=None): + """ + cfgFile - string, fully specified configuration file name + """ + self.file=cfgFile + ConfigParser.__init__(self,defaults=cfgDefaults) + + def Get(self, section, option, type=None, default=None, raw=False): + """ + Get an option value for given section/option or return default. + If type is specified, return as type. + """ + if not self.has_option(section, option): + return default + if type=='bool': + return self.getboolean(section, option) + elif type=='int': + return self.getint(section, option) + else: + return self.get(section, option, raw=raw) + + def GetOptionList(self,section): + """ + Get an option list for given section + """ + if self.has_section(section): + return self.options(section) + else: #return a default value + return [] + + def Load(self): + """ + Load the configuration file from disk + """ + self.read(self.file) + +class IdleUserConfParser(IdleConfParser): + """ + IdleConfigParser specialised for user configuration handling. + """ + + def AddSection(self,section): + """ + if section doesn't exist, add it + """ + if not self.has_section(section): + self.add_section(section) + + def RemoveEmptySections(self): + """ + remove any sections that have no options + """ + for section in self.sections(): + if not self.GetOptionList(section): + self.remove_section(section) + + def IsEmpty(self): + """ + Remove empty sections and then return 1 if parser has no sections + left, else return 0. + """ + self.RemoveEmptySections() + if self.sections(): + return 0 + else: + return 1 + + def RemoveOption(self,section,option): + """ + If section/option exists, remove it. + Returns 1 if option was removed, 0 otherwise. + """ + if self.has_section(section): + return self.remove_option(section,option) + + def SetOption(self,section,option,value): + """ + Sets option to value, adding section if required. + Returns 1 if option was added or changed, otherwise 0. + """ + if self.has_option(section,option): + if self.get(section,option)==value: + return 0 + else: + self.set(section,option,value) + return 1 + else: + if not self.has_section(section): + self.add_section(section) + self.set(section,option,value) + return 1 + + def RemoveFile(self): + """ + Removes the user config file from disk if it exists. + """ + if os.path.exists(self.file): + os.remove(self.file) + + def Save(self): + """Update user configuration file. + + Remove empty sections. If resulting config isn't empty, write the file + to disk. If config is empty, remove the file from disk if it exists. + + """ + if not self.IsEmpty(): + fname = self.file + try: + cfgFile = open(fname, 'w') + except IOError: + os.unlink(fname) + cfgFile = open(fname, 'w') + self.write(cfgFile) + else: + self.RemoveFile() + +class IdleConf: + """ + holds config parsers for all idle config files: + default config files + (idle install dir)/config-main.def + (idle install dir)/config-extensions.def + (idle install dir)/config-highlight.def + (idle install dir)/config-keys.def + user config files + (user home dir)/.idlerc/config-main.cfg + (user home dir)/.idlerc/config-extensions.cfg + (user home dir)/.idlerc/config-highlight.cfg + (user home dir)/.idlerc/config-keys.cfg + """ + def __init__(self): + self.defaultCfg={} + self.userCfg={} + self.cfg={} + self.CreateConfigHandlers() + self.LoadCfgFiles() + #self.LoadCfg() + + def CreateConfigHandlers(self): + """ + set up a dictionary of config parsers for default and user + configurations respectively + """ + #build idle install path + if __name__ != '__main__': # we were imported + idleDir=os.path.dirname(__file__) + else: # we were exec'ed (for testing only) + idleDir=os.path.abspath(sys.path[0]) + userDir=self.GetUserCfgDir() + configTypes=('main','extensions','highlight','keys') + defCfgFiles={} + usrCfgFiles={} + for cfgType in configTypes: #build config file names + defCfgFiles[cfgType]=os.path.join(idleDir,'config-'+cfgType+'.def') + usrCfgFiles[cfgType]=os.path.join(userDir,'config-'+cfgType+'.cfg') + for cfgType in configTypes: #create config parsers + self.defaultCfg[cfgType]=IdleConfParser(defCfgFiles[cfgType]) + self.userCfg[cfgType]=IdleUserConfParser(usrCfgFiles[cfgType]) + + def GetUserCfgDir(self): + """ + Creates (if required) and returns a filesystem directory for storing + user config files. + + """ + cfgDir = '.idlerc' + userDir = os.path.expanduser('~') + if userDir != '~': # expanduser() found user home dir + if not os.path.exists(userDir): + warn = ('\n Warning: os.path.expanduser("~") points to\n '+ + userDir+',\n but the path does not exist.\n') + try: + sys.stderr.write(warn) + except IOError: + pass + userDir = '~' + if userDir == "~": # still no path to home! + # traditionally IDLE has defaulted to os.getcwd(), is this adequate? + userDir = os.getcwd() + userDir = os.path.join(userDir, cfgDir) + if not os.path.exists(userDir): + try: + os.mkdir(userDir) + except (OSError, IOError): + warn = ('\n Warning: unable to create user config directory\n'+ + userDir+'\n Check path and permissions.\n Exiting!\n\n') + sys.stderr.write(warn) + raise SystemExit + return userDir + + def GetOption(self, configType, section, option, default=None, type=None, + warn_on_default=True, raw=False): + """ + Get an option value for given config type and given general + configuration section/option or return a default. If type is specified, + return as type. Firstly the user configuration is checked, with a + fallback to the default configuration, and a final 'catch all' + fallback to a useable passed-in default if the option isn't present in + either the user or the default configuration. + configType must be one of ('main','extensions','highlight','keys') + If a default is returned, and warn_on_default is True, a warning is + printed to stderr. + + """ + try: + if self.userCfg[configType].has_option(section,option): + return self.userCfg[configType].Get(section, option, + type=type, raw=raw) + except ValueError: + warning = ('\n Warning: configHandler.py - IdleConf.GetOption -\n' + ' invalid %r value for configuration option %r\n' + ' from section %r: %r\n' % + (type, option, section, + self.userCfg[configType].Get(section, option, + raw=raw))) + try: + sys.stderr.write(warning) + except IOError: + pass + try: + if self.defaultCfg[configType].has_option(section,option): + return self.defaultCfg[configType].Get(section, option, + type=type, raw=raw) + except ValueError: + pass + #returning default, print warning + if warn_on_default: + warning = ('\n Warning: configHandler.py - IdleConf.GetOption -\n' + ' problem retrieving configuration option %r\n' + ' from section %r.\n' + ' returning default value: %r\n' % + (option, section, default)) + try: + sys.stderr.write(warning) + except IOError: + pass + return default + + def SetOption(self, configType, section, option, value): + """In user's config file, set section's option to value. + + """ + self.userCfg[configType].SetOption(section, option, value) + + def GetSectionList(self, configSet, configType): + """ + Get a list of sections from either the user or default config for + the given config type. + configSet must be either 'user' or 'default' + configType must be one of ('main','extensions','highlight','keys') + """ + if not (configType in ('main','extensions','highlight','keys')): + raise InvalidConfigType, 'Invalid configType specified' + if configSet == 'user': + cfgParser=self.userCfg[configType] + elif configSet == 'default': + cfgParser=self.defaultCfg[configType] + else: + raise InvalidConfigSet, 'Invalid configSet specified' + return cfgParser.sections() + + def GetHighlight(self, theme, element, fgBg=None): + """ + return individual highlighting theme elements. + fgBg - string ('fg'or'bg') or None, if None return a dictionary + containing fg and bg colours (appropriate for passing to Tkinter in, + e.g., a tag_config call), otherwise fg or bg colour only as specified. + """ + if self.defaultCfg['highlight'].has_section(theme): + themeDict=self.GetThemeDict('default',theme) + else: + themeDict=self.GetThemeDict('user',theme) + fore=themeDict[element+'-foreground'] + if element=='cursor': #there is no config value for cursor bg + back=themeDict['normal-background'] + else: + back=themeDict[element+'-background'] + highlight={"foreground": fore,"background": back} + if not fgBg: #return dict of both colours + return highlight + else: #return specified colour only + if fgBg == 'fg': + return highlight["foreground"] + if fgBg == 'bg': + return highlight["background"] + else: + raise InvalidFgBg, 'Invalid fgBg specified' + + def GetThemeDict(self,type,themeName): + """ + type - string, 'default' or 'user' theme type + themeName - string, theme name + Returns a dictionary which holds {option:value} for each element + in the specified theme. Values are loaded over a set of ultimate last + fallback defaults to guarantee that all theme elements are present in + a newly created theme. + """ + if type == 'user': + cfgParser=self.userCfg['highlight'] + elif type == 'default': + cfgParser=self.defaultCfg['highlight'] + else: + raise InvalidTheme, 'Invalid theme type specified' + #foreground and background values are provded for each theme element + #(apart from cursor) even though all these values are not yet used + #by idle, to allow for their use in the future. Default values are + #generally black and white. + theme={ 'normal-foreground':'#000000', + 'normal-background':'#ffffff', + 'keyword-foreground':'#000000', + 'keyword-background':'#ffffff', + 'builtin-foreground':'#000000', + 'builtin-background':'#ffffff', + 'comment-foreground':'#000000', + 'comment-background':'#ffffff', + 'string-foreground':'#000000', + 'string-background':'#ffffff', + 'definition-foreground':'#000000', + 'definition-background':'#ffffff', + 'hilite-foreground':'#000000', + 'hilite-background':'gray', + 'break-foreground':'#ffffff', + 'break-background':'#000000', + 'hit-foreground':'#ffffff', + 'hit-background':'#000000', + 'error-foreground':'#ffffff', + 'error-background':'#000000', + #cursor (only foreground can be set) + 'cursor-foreground':'#000000', + #shell window + 'stdout-foreground':'#000000', + 'stdout-background':'#ffffff', + 'stderr-foreground':'#000000', + 'stderr-background':'#ffffff', + 'console-foreground':'#000000', + 'console-background':'#ffffff' } + for element in theme.keys(): + if not cfgParser.has_option(themeName,element): + #we are going to return a default, print warning + warning=('\n Warning: configHandler.py - IdleConf.GetThemeDict' + ' -\n problem retrieving theme element %r' + '\n from theme %r.\n' + ' returning default value: %r\n' % + (element, themeName, theme[element])) + try: + sys.stderr.write(warning) + except IOError: + pass + colour=cfgParser.Get(themeName,element,default=theme[element]) + theme[element]=colour + return theme + + def CurrentTheme(self): + """ + Returns the name of the currently active theme + """ + return self.GetOption('main','Theme','name',default='') + + def CurrentKeys(self): + """ + Returns the name of the currently active key set + """ + return self.GetOption('main','Keys','name',default='') + + def GetExtensions(self, active_only=True, editor_only=False, shell_only=False): + """ + Gets a list of all idle extensions declared in the config files. + active_only - boolean, if true only return active (enabled) extensions + """ + extns=self.RemoveKeyBindNames( + self.GetSectionList('default','extensions')) + userExtns=self.RemoveKeyBindNames( + self.GetSectionList('user','extensions')) + for extn in userExtns: + if extn not in extns: #user has added own extension + extns.append(extn) + if active_only: + activeExtns=[] + for extn in extns: + if self.GetOption('extensions', extn, 'enable', default=True, + type='bool'): + #the extension is enabled + if editor_only or shell_only: + if editor_only: + option = "enable_editor" + else: + option = "enable_shell" + if self.GetOption('extensions', extn,option, + default=True, type='bool', + warn_on_default=False): + activeExtns.append(extn) + else: + activeExtns.append(extn) + return activeExtns + else: + return extns + + def RemoveKeyBindNames(self,extnNameList): + #get rid of keybinding section names + names=extnNameList + kbNameIndicies=[] + for name in names: + if name.endswith(('_bindings', '_cfgBindings')): + kbNameIndicies.append(names.index(name)) + kbNameIndicies.sort() + kbNameIndicies.reverse() + for index in kbNameIndicies: #delete each keybinding section name + del(names[index]) + return names + + def GetExtnNameForEvent(self,virtualEvent): + """ + Returns the name of the extension that virtualEvent is bound in, or + None if not bound in any extension. + virtualEvent - string, name of the virtual event to test for, without + the enclosing '<< >>' + """ + extName=None + vEvent='<<'+virtualEvent+'>>' + for extn in self.GetExtensions(active_only=0): + for event in self.GetExtensionKeys(extn).keys(): + if event == vEvent: + extName=extn + return extName + + def GetExtensionKeys(self,extensionName): + """ + returns a dictionary of the configurable keybindings for a particular + extension,as they exist in the dictionary returned by GetCurrentKeySet; + that is, where previously used bindings are disabled. + """ + keysName=extensionName+'_cfgBindings' + activeKeys=self.GetCurrentKeySet() + extKeys={} + if self.defaultCfg['extensions'].has_section(keysName): + eventNames=self.defaultCfg['extensions'].GetOptionList(keysName) + for eventName in eventNames: + event='<<'+eventName+'>>' + binding=activeKeys[event] + extKeys[event]=binding + return extKeys + + def __GetRawExtensionKeys(self,extensionName): + """ + returns a dictionary of the configurable keybindings for a particular + extension, as defined in the configuration files, or an empty dictionary + if no bindings are found + """ + keysName=extensionName+'_cfgBindings' + extKeys={} + if self.defaultCfg['extensions'].has_section(keysName): + eventNames=self.defaultCfg['extensions'].GetOptionList(keysName) + for eventName in eventNames: + binding=self.GetOption('extensions',keysName, + eventName,default='').split() + event='<<'+eventName+'>>' + extKeys[event]=binding + return extKeys + + def GetExtensionBindings(self,extensionName): + """ + Returns a dictionary of all the event bindings for a particular + extension. The configurable keybindings are returned as they exist in + the dictionary returned by GetCurrentKeySet; that is, where re-used + keybindings are disabled. + """ + bindsName=extensionName+'_bindings' + extBinds=self.GetExtensionKeys(extensionName) + #add the non-configurable bindings + if self.defaultCfg['extensions'].has_section(bindsName): + eventNames=self.defaultCfg['extensions'].GetOptionList(bindsName) + for eventName in eventNames: + binding=self.GetOption('extensions',bindsName, + eventName,default='').split() + event='<<'+eventName+'>>' + extBinds[event]=binding + + return extBinds + + def GetKeyBinding(self, keySetName, eventStr): + """ + returns the keybinding for a specific event. + keySetName - string, name of key binding set + eventStr - string, the virtual event we want the binding for, + represented as a string, eg. '<>' + """ + eventName=eventStr[2:-2] #trim off the angle brackets + binding=self.GetOption('keys',keySetName,eventName,default='').split() + return binding + + def GetCurrentKeySet(self): + result = self.GetKeySet(self.CurrentKeys()) + + if sys.platform == "darwin": + # OS X Tk variants do not support the "Alt" keyboard modifier. + # So replace all keybingings that use "Alt" with ones that + # use the "Option" keyboard modifier. + # TO DO: the "Option" modifier does not work properly for + # Cocoa Tk and XQuartz Tk so we should not use it + # in default OS X KeySets. + for k, v in result.items(): + v2 = [ x.replace('>' + """ + return ('<<'+virtualEvent+'>>') in self.GetCoreKeys().keys() + + def GetCoreKeys(self, keySetName=None): + """ + returns the requested set of core keybindings, with fallbacks if + required. + Keybindings loaded from the config file(s) are loaded _over_ these + defaults, so if there is a problem getting any core binding there will + be an 'ultimate last resort fallback' to the CUA-ish bindings + defined here. + """ + keyBindings={ + '<>': ['', ''], + '<>': ['', ''], + '<>': ['', ''], + '<>': ['', ''], + '<>': [''], + '<>': [''], + '<>': [''], + '<>': [''], + '<>': [''], + '<>': [''], + '<>': [''], + '<>': [''], + '<>': [''], + '<>': [''], + '<>': [''], + '<>': [''], + '<>': [''], + '<>': [''], + '<>': [''], + '<>': [''], + '<>': [''], + '<>': [''], + '<>': [''], + '<>': [''], + '<>': [''], + '<>': [''], + '<>': [''], + '<>': [''], + '<>': [''], + '<>': [''], + '<>': ['', ''], + '<>': [''], + '<>': [''], + '<>': [''], + '<>': [''], + '<>': [''], + '<>': [''], + '<>': ['', ''], + '<>': [''], + '<>': [''], + '<>': [''], + '<>': [''], + '<>': [''], + '<>': [''], + '<>': [''], + '<>': [''], + '<>': [''], + '<>': [''], + '<>': [''] + } + if keySetName: + for event in keyBindings.keys(): + binding=self.GetKeyBinding(keySetName,event) + if binding: + keyBindings[event]=binding + else: #we are going to return a default, print warning + warning=('\n Warning: configHandler.py - IdleConf.GetCoreKeys' + ' -\n problem retrieving key binding for event %r' + '\n from key set %r.\n' + ' returning default value: %r\n' % + (event, keySetName, keyBindings[event])) + try: + sys.stderr.write(warning) + except IOError: + pass + return keyBindings + + def GetExtraHelpSourceList(self,configSet): + """Fetch list of extra help sources from a given configSet. + + Valid configSets are 'user' or 'default'. Return a list of tuples of + the form (menu_item , path_to_help_file , option), or return the empty + list. 'option' is the sequence number of the help resource. 'option' + values determine the position of the menu items on the Help menu, + therefore the returned list must be sorted by 'option'. + + """ + helpSources=[] + if configSet=='user': + cfgParser=self.userCfg['main'] + elif configSet=='default': + cfgParser=self.defaultCfg['main'] + else: + raise InvalidConfigSet, 'Invalid configSet specified' + options=cfgParser.GetOptionList('HelpFiles') + for option in options: + value=cfgParser.Get('HelpFiles',option,default=';') + if value.find(';')==-1: #malformed config entry with no ';' + menuItem='' #make these empty + helpPath='' #so value won't be added to list + else: #config entry contains ';' as expected + value=string.split(value,';') + menuItem=value[0].strip() + helpPath=value[1].strip() + if menuItem and helpPath: #neither are empty strings + helpSources.append( (menuItem,helpPath,option) ) + helpSources.sort(key=lambda x: int(x[2])) + return helpSources + + def GetAllExtraHelpSourcesList(self): + """ + Returns a list of tuples containing the details of all additional help + sources configured, or an empty list if there are none. Tuples are of + the format returned by GetExtraHelpSourceList. + """ + allHelpSources=( self.GetExtraHelpSourceList('default')+ + self.GetExtraHelpSourceList('user') ) + return allHelpSources + + def LoadCfgFiles(self): + """ + load all configuration files. + """ + for key in self.defaultCfg.keys(): + self.defaultCfg[key].Load() + self.userCfg[key].Load() #same keys + + def SaveUserCfgFiles(self): + """ + write all loaded user configuration files back to disk + """ + for key in self.userCfg.keys(): + self.userCfg[key].Save() + +idleConf=IdleConf() + +### module test +if __name__ == '__main__': + def dumpCfg(cfg): + print '\n',cfg,'\n' + for key in cfg.keys(): + sections=cfg[key].sections() + print key + print sections + for section in sections: + options=cfg[key].options(section) + print section + print options + for option in options: + print option, '=', cfg[key].Get(section,option) + dumpCfg(idleConf.defaultCfg) + dumpCfg(idleConf.userCfg) + print idleConf.userCfg['main'].Get('Theme','name') + #print idleConf.userCfg['highlight'].GetDefHighlight('Foo','normal') diff --git a/PythonHome/Lib/idlelib/configHandler.pyc b/PythonHome/Lib/idlelib/configHandler.pyc deleted file mode 100644 index ca3dead51a7091d83c49cc41a2897b7e8821ec93..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 26737 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