| |
| <!DOCTYPE html> |
| |
| |
| <html lang="en" data-content_root="../" > |
| |
| <head> |
| <meta charset="utf-8" /> |
| <meta name="viewport" content="width=device-width, initial-scale=1.0" /> |
| <title>enum — Apache Arrow v24.0.0.dev285</title> |
| |
| |
| |
| <script data-cfasync="false"> |
| document.documentElement.dataset.mode = localStorage.getItem("mode") || ""; |
| document.documentElement.dataset.theme = localStorage.getItem("theme") || ""; |
| </script> |
| <!-- |
| this give us a css class that will be invisible only if js is disabled |
| --> |
| <noscript> |
| <style> |
| .pst-js-only { display: none !important; } |
| |
| </style> |
| </noscript> |
| |
| <!-- Loaded before other Sphinx assets --> |
| <link href="../_static/styles/theme.css?digest=8878045cc6db502f8baf" rel="stylesheet" /> |
| <link href="../_static/styles/pydata-sphinx-theme.css?digest=8878045cc6db502f8baf" rel="stylesheet" /> |
| |
| <link rel="stylesheet" type="text/css" href="../_static/pygments.css?v=03e43079" /> |
| <link rel="stylesheet" type="text/css" href="../_static/copybutton.css?v=76b2166b" /> |
| <link rel="stylesheet" type="text/css" href="../_static/sphinx-design.min.css?v=95c83b7e" /> |
| <link rel="stylesheet" type="text/css" href="../_static/theme_overrides.css?v=8dcd28dc" /> |
| |
| <!-- So that users can add custom icons --> |
| <script src="../_static/scripts/fontawesome.js?digest=8878045cc6db502f8baf"></script> |
| <!-- Pre-loaded scripts that we'll load fully later --> |
| <link rel="preload" as="script" href="../_static/scripts/bootstrap.js?digest=8878045cc6db502f8baf" /> |
| <link rel="preload" as="script" href="../_static/scripts/pydata-sphinx-theme.js?digest=8878045cc6db502f8baf" /> |
| |
| <script src="../_static/documentation_options.js?v=d1837f39"></script> |
| <script src="../_static/doctools.js?v=fd6eb6e6"></script> |
| <script src="../_static/sphinx_highlight.js?v=6ffebe34"></script> |
| <script src="../_static/clipboard.min.js?v=a7894cd8"></script> |
| <script src="../_static/copybutton.js?v=3bb21c8c"></script> |
| <script src="../_static/design-tabs.js?v=f930bc37"></script> |
| <script type="module">import mermaid from "https://cdn.jsdelivr.net/npm/mermaid@11.12.1/dist/mermaid.esm.min.mjs"; |
| |
| |
| |
| |
| |
| const initStyles = () => { |
| const defaultStyle = document.createElement('style'); |
| defaultStyle.textContent = `pre.mermaid { |
| /* Same as .mermaid-container > pre */ |
| display: block; |
| width: 100%; |
| } |
| |
| pre.mermaid > svg { |
| /* Same as .mermaid-container > pre > svg */ |
| height: 500px; |
| width: 100%; |
| max-width: 100% !important; |
| }`; |
| document.head.appendChild(defaultStyle); |
| |
| const fullscreenStyle = document.createElement('style'); |
| fullscreenStyle.textContent = `.mermaid-container { |
| display: flex; |
| flex-direction: row; |
| width: 100%; |
| } |
| |
| .mermaid-container > pre { |
| display: block; |
| width: 100%; |
| } |
| |
| .mermaid-container > pre > svg { |
| height: 500px; |
| width: 100%; |
| max-width: 100% !important; |
| } |
| |
| .mermaid-fullscreen-btn { |
| width: 28px; |
| height: 28px; |
| background: rgba(255, 255, 255, 0.95); |
| border: 1px solid rgba(0, 0, 0, 0.3); |
| border-radius: 4px; |
| cursor: pointer; |
| display: flex; |
| align-items: center; |
| justify-content: center; |
| transition: all 0.2s; |
| box-shadow: 0 2px 6px rgba(0, 0, 0, 0.2); |
| font-size: 14px; |
| line-height: 1; |
| padding: 0; |
| color: #333; |
| } |
| |
| .mermaid-fullscreen-btn:hover { |
| opacity: 100% !important; |
| background: rgba(255, 255, 255, 1); |
| box-shadow: 0 3px 10px rgba(0, 0, 0, 0.3); |
| transform: scale(1.1); |
| } |
| |
| .mermaid-fullscreen-btn.dark-theme { |
| background: rgba(50, 50, 50, 0.95); |
| border: 1px solid rgba(255, 255, 255, 0.3); |
| color: #e0e0e0; |
| } |
| |
| .mermaid-fullscreen-btn.dark-theme:hover { |
| background: rgba(60, 60, 60, 1); |
| box-shadow: 0 3px 10px rgba(255, 255, 255, 0.2); |
| } |
| |
| .mermaid-fullscreen-modal { |
| display: none; |
| position: fixed !important; |
| top: 0 !important; |
| left: 0 !important; |
| width: 95vw; |
| height: 100vh; |
| background: rgba(255, 255, 255, 0.98); |
| z-index: 9999; |
| padding: 20px; |
| overflow: auto; |
| } |
| |
| .mermaid-fullscreen-modal.dark-theme { |
| background: rgba(0, 0, 0, 0.98); |
| } |
| |
| .mermaid-fullscreen-modal.active { |
| display: flex; |
| align-items: center; |
| justify-content: center; |
| } |
| |
| .mermaid-container-fullscreen { |
| position: relative; |
| width: 95vw; |
| height: 90vh; |
| max-width: 95vw; |
| max-height: 90vh; |
| background: white; |
| border-radius: 8px; |
| padding: 20px; |
| box-shadow: 0 10px 40px rgba(0, 0, 0, 0.3); |
| overflow: auto; |
| display: flex; |
| align-items: center; |
| justify-content: center; |
| } |
| |
| .mermaid-container-fullscreen.dark-theme { |
| background: #1a1a1a; |
| box-shadow: 0 10px 40px rgba(0, 0, 0, 0.8); |
| } |
| |
| .mermaid-container-fullscreen pre.mermaid { |
| width: 100%; |
| height: 100%; |
| display: flex; |
| align-items: center; |
| justify-content: center; |
| } |
| |
| .mermaid-container-fullscreen .mermaid svg { |
| height: 100% !important; |
| width: 100% !important; |
| cursor: grab; |
| } |
| |
| .mermaid-fullscreen-close { |
| position: fixed !important; |
| top: 20px !important; |
| right: 20px !important; |
| width: 40px; |
| height: 40px; |
| background: rgba(255, 255, 255, 0.95); |
| border: 1px solid rgba(0, 0, 0, 0.2); |
| border-radius: 50%; |
| cursor: pointer; |
| z-index: 10000; |
| display: flex; |
| align-items: center; |
| justify-content: center; |
| box-shadow: 0 4px 12px rgba(0, 0, 0, 0.3); |
| transition: all 0.2s; |
| font-size: 24px; |
| line-height: 1; |
| color: #333; |
| } |
| |
| .mermaid-fullscreen-close:hover { |
| background: white; |
| box-shadow: 0 6px 16px rgba(0, 0, 0, 0.4); |
| transform: scale(1.1); |
| } |
| |
| .mermaid-fullscreen-close.dark-theme { |
| background: rgba(50, 50, 50, 0.95); |
| border: 1px solid rgba(255, 255, 255, 0.2); |
| color: #e0e0e0; |
| } |
| |
| .mermaid-fullscreen-close.dark-theme:hover { |
| background: rgba(60, 60, 60, 1); |
| box-shadow: 0 6px 16px rgba(255, 255, 255, 0.2); |
| } |
| |
| .mermaid-fullscreen-modal .mermaid-fullscreen-btn { |
| display: none !important; |
| }`; |
| document.head.appendChild(fullscreenStyle); |
| } |
| |
| // Detect if page has dark background |
| const isDarkTheme = () => { |
| // We use a set of heuristics: |
| // 1. Check for common dark mode classes or attributes |
| // 2. Check computed background color brightness |
| if (document.documentElement.classList.contains('dark') || |
| document.documentElement.getAttribute('data-theme') === 'dark' || |
| document.body.classList.contains('dark') || |
| document.body.getAttribute('data-theme') === 'dark') { |
| // console.log("Dark theme detected via class/attribute"); |
| return true; |
| } |
| if (document.documentElement.classList.contains('light') || |
| document.documentElement.getAttribute('data-theme') === 'light' || |
| document.body.classList.contains('light') || |
| document.body.getAttribute('data-theme') === 'light') { |
| // console.log("Light theme detected via class/attribute"); |
| return false; |
| } |
| if (window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches) { |
| // console.log("Dark theme detected via prefers-color-scheme"); |
| return true; |
| } |
| const bgColor = window.getComputedStyle(document.body).backgroundColor; |
| const match = bgColor.match(/rgb\((\d+),\s*(\d+),\s*(\d+)/); |
| if (match) { |
| const r = parseInt(match[1]); |
| const g = parseInt(match[2]); |
| const b = parseInt(match[3]); |
| const brightness = (r * 299 + g * 587 + b * 114) / 1000; |
| // console.log("Background color brightness:", brightness); |
| return brightness < 128; |
| } |
| // console.log("No dark or light theme detected, defaulting to light theme"); |
| return false; |
| }; |
| |
| let darkTheme = isDarkTheme(); |
| let modal = null; |
| let modalContent = null; |
| let previousScrollOffset = [window.scrollX, window.scrollY]; |
| |
| const runMermaid = async (rerun) => { |
| console.log("Running mermaid diagrams, rerun =", rerun); |
| // clear all existing mermaid charts |
| let all_mermaids = document.querySelectorAll(".mermaid"); |
| |
| if (rerun) { |
| all_mermaids.forEach((el) => { |
| if(!el.hasAttribute("data-original-code")) { |
| // store original code |
| // console.log(`Storing original code for first run: `, el.innerHTML); |
| el.setAttribute('data-original-code', el.innerHTML); |
| } |
| if(el.getAttribute("data-processed") === "true") { |
| // remove and restore original |
| el.removeAttribute("data-processed"); |
| // console.log(`Restoring original code for re-run: `, el.getAttribute('data-original-code')); |
| el.innerHTML = el.getAttribute('data-original-code'); |
| } else { |
| // store original code |
| // console.log(`Storing original code for re-run: `, el.innerHTML); |
| el.setAttribute('data-original-code', el.innerHTML); |
| } |
| }); |
| await mermaid.run(); |
| } |
| |
| all_mermaids = document.querySelectorAll(".mermaid"); |
| const mermaids_processed = document.querySelectorAll(".mermaid[data-processed='true']"); |
| |
| if ("False" === "True") { |
| const mermaids_to_add_zoom = -1 === -1 ? all_mermaids.length : -1; |
| if(mermaids_to_add_zoom > 0) { |
| var svgs = d3.selectAll(""); |
| if(all_mermaids.length !== mermaids_processed.length) { |
| setTimeout(() => runMermaid(false), 200); |
| return; |
| } else if(svgs.size() !== mermaids_to_add_zoom) { |
| setTimeout(() => runMermaid(false), 200); |
| return; |
| } else { |
| svgs.each(function() { |
| var svg = d3.select(this); |
| svg.html("<g class='wrapper'>" + svg.html() + "</g>"); |
| var inner = svg.select("g"); |
| var zoom = d3.zoom().on("zoom", function(event) { |
| inner.attr("transform", event.transform); |
| }); |
| svg.call(zoom); |
| }); |
| } |
| } |
| } else if(all_mermaids.length !== mermaids_processed.length) { |
| // Wait for mermaid to process all diagrams |
| setTimeout(() => runMermaid(false), 200); |
| return; |
| } |
| |
| // Stop here if not adding fullscreen capability |
| if ("True" !== "True") return; |
| |
| if (modal !== null ) { |
| // Destroy existing modal |
| modal.remove(); |
| modal = null; |
| modalContent = null; |
| } |
| |
| modal = document.createElement('div'); |
| modal.className = 'mermaid-fullscreen-modal' + (darkTheme ? ' dark-theme' : ''); |
| modal.setAttribute('role', 'dialog'); |
| modal.setAttribute('aria-modal', 'true'); |
| modal.setAttribute('aria-label', 'Fullscreen diagram viewer'); |
| modal.innerHTML = ` |
| <button class="mermaid-fullscreen-close${darkTheme ? ' dark-theme' : ''}" aria-label="Close fullscreen">✕</button> |
| <div class="mermaid-container-fullscreen${darkTheme ? ' dark-theme' : ''}"></div> |
| `; |
| document.body.appendChild(modal); |
| |
| modalContent = modal.querySelector('.mermaid-container-fullscreen'); |
| const closeBtn = modal.querySelector('.mermaid-fullscreen-close'); |
| |
| const closeModal = () => { |
| modal.classList.remove('active'); |
| modalContent.innerHTML = ''; |
| document.body.style.overflow = '' |
| window.scrollTo({left: previousScrollOffset[0], top: previousScrollOffset[1], behavior: 'instant'}); |
| }; |
| |
| closeBtn.addEventListener('click', closeModal); |
| modal.addEventListener('click', (e) => { |
| if (e.target === modal) closeModal(); |
| }); |
| document.addEventListener('keydown', (e) => { |
| if (e.key === 'Escape' && modal.classList.contains('active')) { |
| closeModal(); |
| } |
| }); |
| |
| document.querySelectorAll('.mermaid').forEach((mermaidDiv) => { |
| if (mermaidDiv.parentNode.classList.contains('mermaid-container') || |
| mermaidDiv.closest('.mermaid-fullscreen-modal')) { |
| // Already processed, adjust button class if needed |
| const existingBtn = mermaidDiv.parentNode.querySelector('.mermaid-fullscreen-btn'); |
| if (existingBtn) { |
| existingBtn.className = 'mermaid-fullscreen-btn' + (darkTheme ? ' dark-theme' : ''); |
| } |
| return; |
| } |
| |
| const container = document.createElement('div'); |
| container.className = 'mermaid-container'; |
| mermaidDiv.parentNode.insertBefore(container, mermaidDiv); |
| container.appendChild(mermaidDiv); |
| |
| const fullscreenBtn = document.createElement('button'); |
| fullscreenBtn.className = 'mermaid-fullscreen-btn' + (darkTheme ? ' dark-theme' : ''); |
| fullscreenBtn.setAttribute('aria-label', 'View diagram in fullscreen'); |
| fullscreenBtn.textContent = '⛶'; |
| fullscreenBtn.style.opacity = '50%'; |
| |
| // Calculate dynamic position based on diagram's margin and padding |
| const diagramStyle = window.getComputedStyle(mermaidDiv); |
| const marginTop = parseFloat(diagramStyle.marginTop) || 0; |
| const marginRight = parseFloat(diagramStyle.marginRight) || 0; |
| const paddingTop = parseFloat(diagramStyle.paddingTop) || 0; |
| const paddingRight = parseFloat(diagramStyle.paddingRight) || 0; |
| fullscreenBtn.style.top = `${marginTop + paddingTop + 4}px`; |
| fullscreenBtn.style.right = `${marginRight + paddingRight + 4}px`; |
| |
| fullscreenBtn.addEventListener('click', () => { |
| previousScrollOffset = [window.scroll, window.scrollY]; |
| const clone = mermaidDiv.cloneNode(true); |
| modalContent.innerHTML = ''; |
| modalContent.appendChild(clone); |
| |
| const svg = clone.querySelector('svg'); |
| if (svg) { |
| svg.removeAttribute('width'); |
| svg.removeAttribute('height'); |
| svg.style.width = '100%'; |
| svg.style.height = 'auto'; |
| svg.style.maxWidth = '100%'; |
| svg.style.sdisplay = 'block'; |
| |
| if ("False" === "True") { |
| setTimeout(() => { |
| const g = svg.querySelector('g'); |
| if (g) { |
| var svgD3 = d3.select(svg); |
| svgD3.html("<g class='wrapper'>" + svgD3.html() + "</g>"); |
| var inner = svgD3.select("g"); |
| var zoom = d3.zoom().on("zoom", function(event) { |
| inner.attr("transform", event.transform); |
| }); |
| svgD3.call(zoom); |
| } |
| }, 100); |
| } |
| } |
| |
| modal.classList.add('active'); |
| document.body.style.overflow = 'hidden'; |
| }); |
| container.appendChild(fullscreenBtn); |
| }); |
| }; |
| |
| const load = async () => { |
| initStyles(); |
| |
| await runMermaid(true); |
| |
| const reRunIfThemeChanges = async () => { |
| const newDarkTheme = isDarkTheme(); |
| if (newDarkTheme !== darkTheme) { |
| darkTheme = newDarkTheme; |
| console.log("Theme change detected, re-running mermaid with", darkTheme ? "dark" : "default", "theme"); |
| await mermaid.initialize( |
| {...JSON.parse( |
| `{"startOnLoad": false}` |
| ), |
| ...{ darkMode: darkTheme, theme: darkTheme ? 'dark' : 'default' }, |
| } |
| ); |
| await runMermaid(true); |
| } |
| }; |
| |
| // Update theme classes when theme changes |
| const themeObserver = new MutationObserver(reRunIfThemeChanges); |
| themeObserver.observe(document.documentElement, { |
| attributes: true, |
| attributeFilter: ['class', 'style', 'data-theme'] |
| }); |
| themeObserver.observe(document.body, { |
| attributes: true, |
| attributeFilter: ['class', 'style', 'data-theme'] |
| }); |
| }; |
| |
| |
| |
| |
| |
| console.log("Initializing mermaid with", darkTheme ? "dark" : "default", "theme"); |
| mermaid.initialize( |
| {...JSON.parse( |
| `{"startOnLoad": false}` |
| ), |
| ...{ darkMode: darkTheme, theme: darkTheme ? 'dark' : 'default' }, |
| } |
| ); |
| |
| window.addEventListener("load", load); |
| window.runMermaid = runMermaid;</script> |
| <script>DOCUMENTATION_OPTIONS.pagename = '_modules/enum';</script> |
| <script> |
| DOCUMENTATION_OPTIONS.theme_version = '0.16.1'; |
| DOCUMENTATION_OPTIONS.theme_switcher_json_url = '/docs/_static/versions.json'; |
| DOCUMENTATION_OPTIONS.theme_switcher_version_match = 'dev/'; |
| DOCUMENTATION_OPTIONS.show_version_warning_banner = |
| true; |
| </script> |
| <link rel="canonical" href="https://arrow.apache.org/docs/_modules/enum.html" /> |
| <link rel="icon" href="../_static/favicon.ico"/> |
| <link rel="index" title="Index" href="../genindex.html" /> |
| <link rel="search" title="Search" href="../search.html" /> |
| |
| <meta name="viewport" content="width=device-width, initial-scale=1"/> |
| <meta name="docsearch:language" content="en"/> |
| <meta name="docsearch:version" content="24.0.0.dev285" /> |
| |
| <!-- Matomo --> |
| <script> |
| var _paq = window._paq = window._paq || []; |
| /* tracker methods like "setCustomDimension" should be called before "trackPageView" */ |
| /* We explicitly disable cookie tracking to avoid privacy issues */ |
| _paq.push(['disableCookies']); |
| _paq.push(['trackPageView']); |
| _paq.push(['enableLinkTracking']); |
| (function() { |
| var u="https://analytics.apache.org/"; |
| _paq.push(['setTrackerUrl', u+'matomo.php']); |
| _paq.push(['setSiteId', '20']); |
| var d=document, g=d.createElement('script'), s=d.getElementsByTagName('script')[0]; |
| g.async=true; g.src=u+'matomo.js'; s.parentNode.insertBefore(g,s); |
| })(); |
| </script> |
| <!-- End Matomo Code --> |
| |
| </head> |
| |
| |
| <body data-bs-spy="scroll" data-bs-target=".bd-toc-nav" data-offset="180" data-bs-root-margin="0px 0px -60%" data-default-mode=""> |
| |
| |
| |
| <div id="pst-skip-link" class="skip-link d-print-none"><a href="#main-content">Skip to main content</a></div> |
| |
| <div id="pst-scroll-pixel-helper"></div> |
| |
| <button type="button" class="btn rounded-pill" id="pst-back-to-top"> |
| <i class="fa-solid fa-arrow-up"></i>Back to top</button> |
| |
| |
| <dialog id="pst-search-dialog"> |
| |
| <form class="bd-search d-flex align-items-center" |
| action="../search.html" |
| method="get"> |
| <i class="fa-solid fa-magnifying-glass"></i> |
| <input type="search" |
| class="form-control" |
| name="q" |
| placeholder="Search the docs ..." |
| aria-label="Search the docs ..." |
| autocomplete="off" |
| autocorrect="off" |
| autocapitalize="off" |
| spellcheck="false"/> |
| <span class="search-button__kbd-shortcut"><kbd class="kbd-shortcut__modifier">Ctrl</kbd>+<kbd>K</kbd></span> |
| </form> |
| </dialog> |
| |
| <div class="pst-async-banner-revealer d-none"> |
| <aside id="bd-header-version-warning" class="d-none d-print-none" aria-label="Version warning"></aside> |
| </div> |
| |
| |
| <header class="bd-header navbar navbar-expand-lg bd-navbar d-print-none"> |
| <div class="bd-header__inner bd-page-width"> |
| <button class="pst-navbar-icon sidebar-toggle primary-toggle" aria-label="Site navigation"> |
| <span class="fa-solid fa-bars"></span> |
| </button> |
| |
| |
| <div class=" navbar-header-items__start"> |
| |
| <div class="navbar-item"> |
| |
| |
| |
| |
| |
| <a class="navbar-brand logo" href="../index.html"> |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| <img src="../_static/arrow.png" class="logo__image only-light" alt="Apache Arrow v24.0.0.dev285 - Home"/> |
| <img src="../_static/arrow-dark.png" class="logo__image only-dark pst-js-only" alt="Apache Arrow v24.0.0.dev285 - Home"/> |
| |
| |
| </a></div> |
| |
| </div> |
| |
| <div class=" navbar-header-items"> |
| |
| <div class="me-auto navbar-header-items__center"> |
| |
| <div class="navbar-item"> |
| <nav> |
| <ul class="bd-navbar-elements navbar-nav"> |
| |
| <li class="nav-item "> |
| <a class="nav-link nav-internal" href="../format/index.html"> |
| Specifications |
| </a> |
| </li> |
| |
| |
| <li class="nav-item "> |
| <a class="nav-link nav-internal" href="../developers/index.html"> |
| Development |
| </a> |
| </li> |
| |
| |
| <li class="nav-item "> |
| <a class="nav-link nav-internal" href="../implementations.html"> |
| Implementations |
| </a> |
| </li> |
| |
| </ul> |
| </nav></div> |
| |
| </div> |
| |
| |
| <div class="navbar-header-items__end"> |
| |
| <div class="navbar-item navbar-persistent--container"> |
| |
| |
| <button class="btn search-button-field search-button__button pst-js-only" title="Search" aria-label="Search" data-bs-placement="bottom" data-bs-toggle="tooltip"> |
| <i class="fa-solid fa-magnifying-glass"></i> |
| <span class="search-button__default-text">Search</span> |
| <span class="search-button__kbd-shortcut"><kbd class="kbd-shortcut__modifier">Ctrl</kbd>+<kbd class="kbd-shortcut__modifier">K</kbd></span> |
| </button> |
| </div> |
| |
| |
| <div class="navbar-item"><div class="kapa-ai-bot"> |
| <script |
| async |
| src="https://widget.kapa.ai/kapa-widget.bundle.js" |
| data-website-id="9db461d5-ac77-4b3f-a5c5-75efa78339d2" |
| data-project-name="Apache Arrow" |
| data-project-color="#000000" |
| data-project-logo="https://arrow.apache.org/img/arrow-logo_chevrons_white-txt_black-bg.png" |
| data-modal-disclaimer="This is a custom LLM with access to all [Arrow documentation](https://arrow.apache.org/docs/). Please include the language you are using in your question, e.g., Python, C++, Java, R, etc." |
| data-consent-required="true" |
| data-user-analytics-cookie-enabled="false" |
| data-consent-screen-disclaimer="By clicking "I agree, let's chat", you consent to the use of the AI assistant in accordance with kapa.ai's [Privacy Policy](https://www.kapa.ai/content/privacy-policy). This service uses reCAPTCHA, which requires your consent to Google's [Privacy Policy](https://policies.google.com/privacy) and [Terms of Service](https://policies.google.com/terms). By proceeding, you explicitly agree to both kapa.ai's and Google's privacy policies." |
| ></script> |
| |
| </div> |
| |
| </div> |
| |
| <div class="navbar-item"> |
| <div class="version-switcher__container dropdown pst-js-only"> |
| <button id="pst-version-switcher-button-2" |
| type="button" |
| class="version-switcher__button btn btn-sm dropdown-toggle" |
| data-bs-toggle="dropdown" |
| aria-haspopup="listbox" |
| aria-controls="pst-version-switcher-list-2" |
| aria-label="Version switcher list" |
| > |
| Choose version <!-- this text may get changed later by javascript --> |
| <span class="caret"></span> |
| </button> |
| <div id="pst-version-switcher-list-2" |
| class="version-switcher__menu dropdown-menu list-group-flush py-0" |
| role="listbox" aria-labelledby="pst-version-switcher-button-2"> |
| <!-- dropdown will be populated by javascript on page load --> |
| </div> |
| </div></div> |
| |
| <div class="navbar-item"> |
| |
| <button class="btn btn-sm nav-link pst-navbar-icon theme-switch-button pst-js-only" aria-label="Color mode" data-bs-title="Color mode" data-bs-placement="bottom" data-bs-toggle="tooltip"> |
| <i class="theme-switch fa-solid fa-sun fa-lg" data-mode="light" title="Light"></i> |
| <i class="theme-switch fa-solid fa-moon fa-lg" data-mode="dark" title="Dark"></i> |
| <i class="theme-switch fa-solid fa-circle-half-stroke fa-lg" data-mode="auto" title="System Settings"></i> |
| </button></div> |
| |
| <div class="navbar-item"><ul class="navbar-icon-links" |
| aria-label="Icon Links"> |
| <li class="nav-item"> |
| |
| |
| |
| |
| |
| |
| |
| |
| <a href="https://github.com/apache/arrow" title="GitHub" class="nav-link pst-navbar-icon" rel="noopener" target="_blank" data-bs-toggle="tooltip" data-bs-placement="bottom"><i class="fa-brands fa-square-github fa-lg" aria-hidden="true"></i> |
| <span class="sr-only">GitHub</span></a> |
| </li> |
| <li class="nav-item"> |
| |
| |
| |
| |
| |
| |
| |
| |
| <a href="https://www.linkedin.com/company/apache-arrow/" title="LinkedIn" class="nav-link pst-navbar-icon" rel="noopener" target="_blank" data-bs-toggle="tooltip" data-bs-placement="bottom"><i class="fa-brands fa-linkedin fa-lg" aria-hidden="true"></i> |
| <span class="sr-only">LinkedIn</span></a> |
| </li> |
| <li class="nav-item"> |
| |
| |
| |
| |
| |
| |
| |
| |
| <a href="https://bsky.app/profile/arrow.apache.org" title="BlueSky" class="nav-link pst-navbar-icon" rel="noopener" target="_blank" data-bs-toggle="tooltip" data-bs-placement="bottom"><i class="fa-brands fa-bluesky fa-lg" aria-hidden="true"></i> |
| <span class="sr-only">BlueSky</span></a> |
| </li> |
| </ul></div> |
| |
| </div> |
| |
| </div> |
| |
| |
| <div class="navbar-persistent--mobile"> |
| |
| <button class="btn search-button-field search-button__button pst-js-only" title="Search" aria-label="Search" data-bs-placement="bottom" data-bs-toggle="tooltip"> |
| <i class="fa-solid fa-magnifying-glass"></i> |
| <span class="search-button__default-text">Search</span> |
| <span class="search-button__kbd-shortcut"><kbd class="kbd-shortcut__modifier">Ctrl</kbd>+<kbd class="kbd-shortcut__modifier">K</kbd></span> |
| </button> |
| </div> |
| |
| |
| |
| </div> |
| |
| </header> |
| |
| |
| <div class="bd-container"> |
| <div class="bd-container__inner bd-page-width"> |
| |
| |
| |
| |
| |
| <dialog id="pst-primary-sidebar-modal"></dialog> |
| <div id="pst-primary-sidebar" class="bd-sidebar-primary bd-sidebar hide-on-wide"> |
| |
| |
| |
| <div class="sidebar-header-items sidebar-primary__section"> |
| |
| |
| <div class="sidebar-header-items__center"> |
| |
| |
| |
| <div class="navbar-item"> |
| <nav> |
| <ul class="bd-navbar-elements navbar-nav"> |
| |
| <li class="nav-item "> |
| <a class="nav-link nav-internal" href="../format/index.html"> |
| Specifications |
| </a> |
| </li> |
| |
| |
| <li class="nav-item "> |
| <a class="nav-link nav-internal" href="../developers/index.html"> |
| Development |
| </a> |
| </li> |
| |
| |
| <li class="nav-item "> |
| <a class="nav-link nav-internal" href="../implementations.html"> |
| Implementations |
| </a> |
| </li> |
| |
| </ul> |
| </nav></div> |
| |
| |
| </div> |
| |
| |
| |
| <div class="sidebar-header-items__end"> |
| |
| <div class="navbar-item"><div class="kapa-ai-bot"> |
| <script |
| async |
| src="https://widget.kapa.ai/kapa-widget.bundle.js" |
| data-website-id="9db461d5-ac77-4b3f-a5c5-75efa78339d2" |
| data-project-name="Apache Arrow" |
| data-project-color="#000000" |
| data-project-logo="https://arrow.apache.org/img/arrow-logo_chevrons_white-txt_black-bg.png" |
| data-modal-disclaimer="This is a custom LLM with access to all [Arrow documentation](https://arrow.apache.org/docs/). Please include the language you are using in your question, e.g., Python, C++, Java, R, etc." |
| data-consent-required="true" |
| data-user-analytics-cookie-enabled="false" |
| data-consent-screen-disclaimer="By clicking "I agree, let's chat", you consent to the use of the AI assistant in accordance with kapa.ai's [Privacy Policy](https://www.kapa.ai/content/privacy-policy). This service uses reCAPTCHA, which requires your consent to Google's [Privacy Policy](https://policies.google.com/privacy) and [Terms of Service](https://policies.google.com/terms). By proceeding, you explicitly agree to both kapa.ai's and Google's privacy policies." |
| ></script> |
| |
| </div> |
| |
| </div> |
| |
| <div class="navbar-item"> |
| <div class="version-switcher__container dropdown pst-js-only"> |
| <button id="pst-version-switcher-button-3" |
| type="button" |
| class="version-switcher__button btn btn-sm dropdown-toggle" |
| data-bs-toggle="dropdown" |
| aria-haspopup="listbox" |
| aria-controls="pst-version-switcher-list-3" |
| aria-label="Version switcher list" |
| > |
| Choose version <!-- this text may get changed later by javascript --> |
| <span class="caret"></span> |
| </button> |
| <div id="pst-version-switcher-list-3" |
| class="version-switcher__menu dropdown-menu list-group-flush py-0" |
| role="listbox" aria-labelledby="pst-version-switcher-button-3"> |
| <!-- dropdown will be populated by javascript on page load --> |
| </div> |
| </div></div> |
| |
| <div class="navbar-item"> |
| |
| <button class="btn btn-sm nav-link pst-navbar-icon theme-switch-button pst-js-only" aria-label="Color mode" data-bs-title="Color mode" data-bs-placement="bottom" data-bs-toggle="tooltip"> |
| <i class="theme-switch fa-solid fa-sun fa-lg" data-mode="light" title="Light"></i> |
| <i class="theme-switch fa-solid fa-moon fa-lg" data-mode="dark" title="Dark"></i> |
| <i class="theme-switch fa-solid fa-circle-half-stroke fa-lg" data-mode="auto" title="System Settings"></i> |
| </button></div> |
| |
| <div class="navbar-item"><ul class="navbar-icon-links" |
| aria-label="Icon Links"> |
| <li class="nav-item"> |
| |
| |
| |
| |
| |
| |
| |
| |
| <a href="https://github.com/apache/arrow" title="GitHub" class="nav-link pst-navbar-icon" rel="noopener" target="_blank" data-bs-toggle="tooltip" data-bs-placement="bottom"><i class="fa-brands fa-square-github fa-lg" aria-hidden="true"></i> |
| <span class="sr-only">GitHub</span></a> |
| </li> |
| <li class="nav-item"> |
| |
| |
| |
| |
| |
| |
| |
| |
| <a href="https://www.linkedin.com/company/apache-arrow/" title="LinkedIn" class="nav-link pst-navbar-icon" rel="noopener" target="_blank" data-bs-toggle="tooltip" data-bs-placement="bottom"><i class="fa-brands fa-linkedin fa-lg" aria-hidden="true"></i> |
| <span class="sr-only">LinkedIn</span></a> |
| </li> |
| <li class="nav-item"> |
| |
| |
| |
| |
| |
| |
| |
| |
| <a href="https://bsky.app/profile/arrow.apache.org" title="BlueSky" class="nav-link pst-navbar-icon" rel="noopener" target="_blank" data-bs-toggle="tooltip" data-bs-placement="bottom"><i class="fa-brands fa-bluesky fa-lg" aria-hidden="true"></i> |
| <span class="sr-only">BlueSky</span></a> |
| </li> |
| </ul></div> |
| |
| </div> |
| |
| </div> |
| |
| |
| <div class="sidebar-primary-items__end sidebar-primary__section"> |
| <div class="sidebar-primary-item"> |
| <div id="ethical-ad-placement" |
| class="flat" |
| data-ea-publisher="readthedocs" |
| data-ea-type="readthedocs-sidebar" |
| data-ea-manual="true"> |
| </div></div> |
| </div> |
| |
| |
| </div> |
| |
| <main id="main-content" class="bd-main" role="main"> |
| |
| |
| <div class="bd-content"> |
| <div class="bd-article-container"> |
| |
| <div class="bd-header-article d-print-none"> |
| <div class="header-article-items header-article__inner"> |
| |
| <div class="header-article-items__start"> |
| |
| <div class="header-article-item"> |
| |
| <nav aria-label="Breadcrumb" class="d-print-none"> |
| <ul class="bd-breadcrumbs"> |
| |
| <li class="breadcrumb-item breadcrumb-home"> |
| <a href="../index.html" class="nav-link" aria-label="Home"> |
| <i class="fa-solid fa-home"></i> |
| </a> |
| </li> |
| |
| <li class="breadcrumb-item"><a href="index.html" class="nav-link">Module code</a></li> |
| |
| <li class="breadcrumb-item active" aria-current="page"><span class="ellipsis">enum</span></li> |
| </ul> |
| </nav> |
| </div> |
| |
| </div> |
| |
| |
| </div> |
| </div> |
| |
| |
| |
| |
| <div id="searchbox"></div> |
| <article class="bd-article"> |
| |
| <h1>Source code for enum</h1><div class="highlight"><pre> |
| <span></span><span class="kn">import</span><span class="w"> </span><span class="nn">sys</span> |
| <span class="kn">import</span><span class="w"> </span><span class="nn">builtins</span><span class="w"> </span><span class="k">as</span><span class="w"> </span><span class="nn">bltns</span> |
| <span class="kn">from</span><span class="w"> </span><span class="nn">functools</span><span class="w"> </span><span class="kn">import</span> <span class="n">partial</span> |
| <span class="kn">from</span><span class="w"> </span><span class="nn">types</span><span class="w"> </span><span class="kn">import</span> <span class="n">MappingProxyType</span><span class="p">,</span> <span class="n">DynamicClassAttribute</span> |
| |
| |
| <span class="n">__all__</span> <span class="o">=</span> <span class="p">[</span> |
| <span class="s1">'EnumType'</span><span class="p">,</span> <span class="s1">'EnumMeta'</span><span class="p">,</span> <span class="s1">'EnumDict'</span><span class="p">,</span> |
| <span class="s1">'Enum'</span><span class="p">,</span> <span class="s1">'IntEnum'</span><span class="p">,</span> <span class="s1">'StrEnum'</span><span class="p">,</span> <span class="s1">'Flag'</span><span class="p">,</span> <span class="s1">'IntFlag'</span><span class="p">,</span> <span class="s1">'ReprEnum'</span><span class="p">,</span> |
| <span class="s1">'auto'</span><span class="p">,</span> <span class="s1">'unique'</span><span class="p">,</span> <span class="s1">'property'</span><span class="p">,</span> <span class="s1">'verify'</span><span class="p">,</span> <span class="s1">'member'</span><span class="p">,</span> <span class="s1">'nonmember'</span><span class="p">,</span> |
| <span class="s1">'FlagBoundary'</span><span class="p">,</span> <span class="s1">'STRICT'</span><span class="p">,</span> <span class="s1">'CONFORM'</span><span class="p">,</span> <span class="s1">'EJECT'</span><span class="p">,</span> <span class="s1">'KEEP'</span><span class="p">,</span> |
| <span class="s1">'global_flag_repr'</span><span class="p">,</span> <span class="s1">'global_enum_repr'</span><span class="p">,</span> <span class="s1">'global_str'</span><span class="p">,</span> <span class="s1">'global_enum'</span><span class="p">,</span> |
| <span class="s1">'EnumCheck'</span><span class="p">,</span> <span class="s1">'CONTINUOUS'</span><span class="p">,</span> <span class="s1">'NAMED_FLAGS'</span><span class="p">,</span> <span class="s1">'UNIQUE'</span><span class="p">,</span> |
| <span class="s1">'pickle_by_global_name'</span><span class="p">,</span> <span class="s1">'pickle_by_enum_name'</span><span class="p">,</span> |
| <span class="p">]</span> |
| |
| |
| <span class="c1"># Dummy value for Enum and Flag as there are explicit checks for them</span> |
| <span class="c1"># before they have been created.</span> |
| <span class="c1"># This is also why there are checks in EnumType like `if Enum is not None`</span> |
| <span class="n">Enum</span> <span class="o">=</span> <span class="n">Flag</span> <span class="o">=</span> <span class="n">EJECT</span> <span class="o">=</span> <span class="n">_stdlib_enums</span> <span class="o">=</span> <span class="n">ReprEnum</span> <span class="o">=</span> <span class="kc">None</span> |
| |
| <span class="k">class</span><span class="w"> </span><span class="nc">nonmember</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span> |
| <span class="w"> </span><span class="sd">"""</span> |
| <span class="sd"> Protects item from becoming an Enum member during class creation.</span> |
| <span class="sd"> """</span> |
| <span class="k">def</span><span class="w"> </span><span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">value</span><span class="p">):</span> |
| <span class="bp">self</span><span class="o">.</span><span class="n">value</span> <span class="o">=</span> <span class="n">value</span> |
| |
| <span class="k">class</span><span class="w"> </span><span class="nc">member</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span> |
| <span class="w"> </span><span class="sd">"""</span> |
| <span class="sd"> Forces item to become an Enum member during class creation.</span> |
| <span class="sd"> """</span> |
| <span class="k">def</span><span class="w"> </span><span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">value</span><span class="p">):</span> |
| <span class="bp">self</span><span class="o">.</span><span class="n">value</span> <span class="o">=</span> <span class="n">value</span> |
| |
| <span class="k">def</span><span class="w"> </span><span class="nf">_is_descriptor</span><span class="p">(</span><span class="n">obj</span><span class="p">):</span> |
| <span class="w"> </span><span class="sd">"""</span> |
| <span class="sd"> Returns True if obj is a descriptor, False otherwise.</span> |
| <span class="sd"> """</span> |
| <span class="k">return</span> <span class="ow">not</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">obj</span><span class="p">,</span> <span class="n">partial</span><span class="p">)</span> <span class="ow">and</span> <span class="p">(</span> |
| <span class="nb">hasattr</span><span class="p">(</span><span class="n">obj</span><span class="p">,</span> <span class="s1">'__get__'</span><span class="p">)</span> <span class="ow">or</span> |
| <span class="nb">hasattr</span><span class="p">(</span><span class="n">obj</span><span class="p">,</span> <span class="s1">'__set__'</span><span class="p">)</span> <span class="ow">or</span> |
| <span class="nb">hasattr</span><span class="p">(</span><span class="n">obj</span><span class="p">,</span> <span class="s1">'__delete__'</span><span class="p">)</span> |
| <span class="p">)</span> |
| |
| <span class="k">def</span><span class="w"> </span><span class="nf">_is_dunder</span><span class="p">(</span><span class="n">name</span><span class="p">):</span> |
| <span class="w"> </span><span class="sd">"""</span> |
| <span class="sd"> Returns True if a __dunder__ name, False otherwise.</span> |
| <span class="sd"> """</span> |
| <span class="k">return</span> <span class="p">(</span> |
| <span class="nb">len</span><span class="p">(</span><span class="n">name</span><span class="p">)</span> <span class="o">></span> <span class="mi">4</span> <span class="ow">and</span> |
| <span class="n">name</span><span class="p">[:</span><span class="mi">2</span><span class="p">]</span> <span class="o">==</span> <span class="n">name</span><span class="p">[</span><span class="o">-</span><span class="mi">2</span><span class="p">:]</span> <span class="o">==</span> <span class="s1">'__'</span> <span class="ow">and</span> |
| <span class="n">name</span><span class="p">[</span><span class="mi">2</span><span class="p">]</span> <span class="o">!=</span> <span class="s1">'_'</span> <span class="ow">and</span> |
| <span class="n">name</span><span class="p">[</span><span class="o">-</span><span class="mi">3</span><span class="p">]</span> <span class="o">!=</span> <span class="s1">'_'</span> |
| <span class="p">)</span> |
| |
| <span class="k">def</span><span class="w"> </span><span class="nf">_is_sunder</span><span class="p">(</span><span class="n">name</span><span class="p">):</span> |
| <span class="w"> </span><span class="sd">"""</span> |
| <span class="sd"> Returns True if a _sunder_ name, False otherwise.</span> |
| <span class="sd"> """</span> |
| <span class="k">return</span> <span class="p">(</span> |
| <span class="nb">len</span><span class="p">(</span><span class="n">name</span><span class="p">)</span> <span class="o">></span> <span class="mi">2</span> <span class="ow">and</span> |
| <span class="n">name</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">==</span> <span class="n">name</span><span class="p">[</span><span class="o">-</span><span class="mi">1</span><span class="p">]</span> <span class="o">==</span> <span class="s1">'_'</span> <span class="ow">and</span> |
| <span class="n">name</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span> <span class="o">!=</span> <span class="s1">'_'</span> <span class="ow">and</span> |
| <span class="n">name</span><span class="p">[</span><span class="o">-</span><span class="mi">2</span><span class="p">]</span> <span class="o">!=</span> <span class="s1">'_'</span> |
| <span class="p">)</span> |
| |
| <span class="k">def</span><span class="w"> </span><span class="nf">_is_internal_class</span><span class="p">(</span><span class="n">cls_name</span><span class="p">,</span> <span class="n">obj</span><span class="p">):</span> |
| <span class="c1"># do not use `re` as `re` imports `enum`</span> |
| <span class="k">if</span> <span class="ow">not</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">obj</span><span class="p">,</span> <span class="nb">type</span><span class="p">):</span> |
| <span class="k">return</span> <span class="kc">False</span> |
| <span class="n">qualname</span> <span class="o">=</span> <span class="nb">getattr</span><span class="p">(</span><span class="n">obj</span><span class="p">,</span> <span class="s1">'__qualname__'</span><span class="p">,</span> <span class="s1">''</span><span class="p">)</span> |
| <span class="n">s_pattern</span> <span class="o">=</span> <span class="n">cls_name</span> <span class="o">+</span> <span class="s1">'.'</span> <span class="o">+</span> <span class="nb">getattr</span><span class="p">(</span><span class="n">obj</span><span class="p">,</span> <span class="s1">'__name__'</span><span class="p">,</span> <span class="s1">''</span><span class="p">)</span> |
| <span class="n">e_pattern</span> <span class="o">=</span> <span class="s1">'.'</span> <span class="o">+</span> <span class="n">s_pattern</span> |
| <span class="k">return</span> <span class="n">qualname</span> <span class="o">==</span> <span class="n">s_pattern</span> <span class="ow">or</span> <span class="n">qualname</span><span class="o">.</span><span class="n">endswith</span><span class="p">(</span><span class="n">e_pattern</span><span class="p">)</span> |
| |
| <span class="k">def</span><span class="w"> </span><span class="nf">_is_private</span><span class="p">(</span><span class="n">cls_name</span><span class="p">,</span> <span class="n">name</span><span class="p">):</span> |
| <span class="c1"># do not use `re` as `re` imports `enum`</span> |
| <span class="n">pattern</span> <span class="o">=</span> <span class="s1">'_</span><span class="si">%s</span><span class="s1">__'</span> <span class="o">%</span> <span class="p">(</span><span class="n">cls_name</span><span class="p">,</span> <span class="p">)</span> |
| <span class="n">pat_len</span> <span class="o">=</span> <span class="nb">len</span><span class="p">(</span><span class="n">pattern</span><span class="p">)</span> |
| <span class="k">if</span> <span class="p">(</span> |
| <span class="nb">len</span><span class="p">(</span><span class="n">name</span><span class="p">)</span> <span class="o">></span> <span class="n">pat_len</span> |
| <span class="ow">and</span> <span class="n">name</span><span class="o">.</span><span class="n">startswith</span><span class="p">(</span><span class="n">pattern</span><span class="p">)</span> |
| <span class="ow">and</span> <span class="p">(</span><span class="n">name</span><span class="p">[</span><span class="o">-</span><span class="mi">1</span><span class="p">]</span> <span class="o">!=</span> <span class="s1">'_'</span> <span class="ow">or</span> <span class="n">name</span><span class="p">[</span><span class="o">-</span><span class="mi">2</span><span class="p">]</span> <span class="o">!=</span> <span class="s1">'_'</span><span class="p">)</span> |
| <span class="p">):</span> |
| <span class="k">return</span> <span class="kc">True</span> |
| <span class="k">else</span><span class="p">:</span> |
| <span class="k">return</span> <span class="kc">False</span> |
| |
| <span class="k">def</span><span class="w"> </span><span class="nf">_is_single_bit</span><span class="p">(</span><span class="n">num</span><span class="p">):</span> |
| <span class="w"> </span><span class="sd">"""</span> |
| <span class="sd"> True if only one bit set in num (should be an int)</span> |
| <span class="sd"> """</span> |
| <span class="k">if</span> <span class="n">num</span> <span class="o">==</span> <span class="mi">0</span><span class="p">:</span> |
| <span class="k">return</span> <span class="kc">False</span> |
| <span class="n">num</span> <span class="o">&=</span> <span class="n">num</span> <span class="o">-</span> <span class="mi">1</span> |
| <span class="k">return</span> <span class="n">num</span> <span class="o">==</span> <span class="mi">0</span> |
| |
| <span class="k">def</span><span class="w"> </span><span class="nf">_make_class_unpicklable</span><span class="p">(</span><span class="n">obj</span><span class="p">):</span> |
| <span class="w"> </span><span class="sd">"""</span> |
| <span class="sd"> Make the given obj un-picklable.</span> |
| |
| <span class="sd"> obj should be either a dictionary, or an Enum</span> |
| <span class="sd"> """</span> |
| <span class="k">def</span><span class="w"> </span><span class="nf">_break_on_call_reduce</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">proto</span><span class="p">):</span> |
| <span class="k">raise</span> <span class="ne">TypeError</span><span class="p">(</span><span class="s1">'</span><span class="si">%r</span><span class="s1"> cannot be pickled'</span> <span class="o">%</span> <span class="bp">self</span><span class="p">)</span> |
| <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">obj</span><span class="p">,</span> <span class="nb">dict</span><span class="p">):</span> |
| <span class="n">obj</span><span class="p">[</span><span class="s1">'__reduce_ex__'</span><span class="p">]</span> <span class="o">=</span> <span class="n">_break_on_call_reduce</span> |
| <span class="n">obj</span><span class="p">[</span><span class="s1">'__module__'</span><span class="p">]</span> <span class="o">=</span> <span class="s1">'<unknown>'</span> |
| <span class="k">else</span><span class="p">:</span> |
| <span class="nb">setattr</span><span class="p">(</span><span class="n">obj</span><span class="p">,</span> <span class="s1">'__reduce_ex__'</span><span class="p">,</span> <span class="n">_break_on_call_reduce</span><span class="p">)</span> |
| <span class="nb">setattr</span><span class="p">(</span><span class="n">obj</span><span class="p">,</span> <span class="s1">'__module__'</span><span class="p">,</span> <span class="s1">'<unknown>'</span><span class="p">)</span> |
| |
| <span class="k">def</span><span class="w"> </span><span class="nf">_iter_bits_lsb</span><span class="p">(</span><span class="n">num</span><span class="p">):</span> |
| <span class="c1"># num must be a positive integer</span> |
| <span class="n">original</span> <span class="o">=</span> <span class="n">num</span> |
| <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">num</span><span class="p">,</span> <span class="n">Enum</span><span class="p">):</span> |
| <span class="n">num</span> <span class="o">=</span> <span class="n">num</span><span class="o">.</span><span class="n">value</span> |
| <span class="k">if</span> <span class="n">num</span> <span class="o"><</span> <span class="mi">0</span><span class="p">:</span> |
| <span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="s1">'</span><span class="si">%r</span><span class="s1"> is not a positive integer'</span> <span class="o">%</span> <span class="n">original</span><span class="p">)</span> |
| <span class="k">while</span> <span class="n">num</span><span class="p">:</span> |
| <span class="n">b</span> <span class="o">=</span> <span class="n">num</span> <span class="o">&</span> <span class="p">(</span><span class="o">~</span><span class="n">num</span> <span class="o">+</span> <span class="mi">1</span><span class="p">)</span> |
| <span class="k">yield</span> <span class="n">b</span> |
| <span class="n">num</span> <span class="o">^=</span> <span class="n">b</span> |
| |
| <span class="k">def</span><span class="w"> </span><span class="nf">show_flag_values</span><span class="p">(</span><span class="n">value</span><span class="p">):</span> |
| <span class="k">return</span> <span class="nb">list</span><span class="p">(</span><span class="n">_iter_bits_lsb</span><span class="p">(</span><span class="n">value</span><span class="p">))</span> |
| |
| <span class="k">def</span><span class="w"> </span><span class="nf">bin</span><span class="p">(</span><span class="n">num</span><span class="p">,</span> <span class="n">max_bits</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span> |
| <span class="w"> </span><span class="sd">"""</span> |
| <span class="sd"> Like built-in bin(), except negative values are represented in</span> |
| <span class="sd"> twos-compliment, and the leading bit always indicates sign</span> |
| <span class="sd"> (0=positive, 1=negative).</span> |
| |
| <span class="sd"> >>> bin(10)</span> |
| <span class="sd"> '0b0 1010'</span> |
| <span class="sd"> >>> bin(~10) # ~10 is -11</span> |
| <span class="sd"> '0b1 0101'</span> |
| <span class="sd"> """</span> |
| |
| <span class="n">ceiling</span> <span class="o">=</span> <span class="mi">2</span> <span class="o">**</span> <span class="p">(</span><span class="n">num</span><span class="p">)</span><span class="o">.</span><span class="n">bit_length</span><span class="p">()</span> |
| <span class="k">if</span> <span class="n">num</span> <span class="o">>=</span> <span class="mi">0</span><span class="p">:</span> |
| <span class="n">s</span> <span class="o">=</span> <span class="n">bltns</span><span class="o">.</span><span class="n">bin</span><span class="p">(</span><span class="n">num</span> <span class="o">+</span> <span class="n">ceiling</span><span class="p">)</span><span class="o">.</span><span class="n">replace</span><span class="p">(</span><span class="s1">'1'</span><span class="p">,</span> <span class="s1">'0'</span><span class="p">,</span> <span class="mi">1</span><span class="p">)</span> |
| <span class="k">else</span><span class="p">:</span> |
| <span class="n">s</span> <span class="o">=</span> <span class="n">bltns</span><span class="o">.</span><span class="n">bin</span><span class="p">(</span><span class="o">~</span><span class="n">num</span> <span class="o">^</span> <span class="p">(</span><span class="n">ceiling</span> <span class="o">-</span> <span class="mi">1</span><span class="p">)</span> <span class="o">+</span> <span class="n">ceiling</span><span class="p">)</span> |
| <span class="n">sign</span> <span class="o">=</span> <span class="n">s</span><span class="p">[:</span><span class="mi">3</span><span class="p">]</span> |
| <span class="n">digits</span> <span class="o">=</span> <span class="n">s</span><span class="p">[</span><span class="mi">3</span><span class="p">:]</span> |
| <span class="k">if</span> <span class="n">max_bits</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span> |
| <span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">digits</span><span class="p">)</span> <span class="o"><</span> <span class="n">max_bits</span><span class="p">:</span> |
| <span class="n">digits</span> <span class="o">=</span> <span class="p">(</span><span class="n">sign</span><span class="p">[</span><span class="o">-</span><span class="mi">1</span><span class="p">]</span> <span class="o">*</span> <span class="n">max_bits</span> <span class="o">+</span> <span class="n">digits</span><span class="p">)[</span><span class="o">-</span><span class="n">max_bits</span><span class="p">:]</span> |
| <span class="k">return</span> <span class="s2">"</span><span class="si">%s</span><span class="s2"> </span><span class="si">%s</span><span class="s2">"</span> <span class="o">%</span> <span class="p">(</span><span class="n">sign</span><span class="p">,</span> <span class="n">digits</span><span class="p">)</span> |
| |
| <span class="k">def</span><span class="w"> </span><span class="nf">_dedent</span><span class="p">(</span><span class="n">text</span><span class="p">):</span> |
| <span class="w"> </span><span class="sd">"""</span> |
| <span class="sd"> Like textwrap.dedent. Rewritten because we cannot import textwrap.</span> |
| <span class="sd"> """</span> |
| <span class="n">lines</span> <span class="o">=</span> <span class="n">text</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="s1">'</span><span class="se">\n</span><span class="s1">'</span><span class="p">)</span> |
| <span class="k">for</span> <span class="n">i</span><span class="p">,</span> <span class="n">ch</span> <span class="ow">in</span> <span class="nb">enumerate</span><span class="p">(</span><span class="n">lines</span><span class="p">[</span><span class="mi">0</span><span class="p">]):</span> |
| <span class="k">if</span> <span class="n">ch</span> <span class="o">!=</span> <span class="s1">' '</span><span class="p">:</span> |
| <span class="k">break</span> |
| <span class="k">for</span> <span class="n">j</span><span class="p">,</span> <span class="n">l</span> <span class="ow">in</span> <span class="nb">enumerate</span><span class="p">(</span><span class="n">lines</span><span class="p">):</span> |
| <span class="n">lines</span><span class="p">[</span><span class="n">j</span><span class="p">]</span> <span class="o">=</span> <span class="n">l</span><span class="p">[</span><span class="n">i</span><span class="p">:]</span> |
| <span class="k">return</span> <span class="s1">'</span><span class="se">\n</span><span class="s1">'</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">lines</span><span class="p">)</span> |
| |
| <span class="k">class</span><span class="w"> </span><span class="nc">_not_given</span><span class="p">:</span> |
| <span class="k">def</span><span class="w"> </span><span class="fm">__repr__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span> |
| <span class="k">return</span><span class="p">(</span><span class="s1">'<not given>'</span><span class="p">)</span> |
| <span class="n">_not_given</span> <span class="o">=</span> <span class="n">_not_given</span><span class="p">()</span> |
| |
| <span class="k">class</span><span class="w"> </span><span class="nc">_auto_null</span><span class="p">:</span> |
| <span class="k">def</span><span class="w"> </span><span class="fm">__repr__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span> |
| <span class="k">return</span> <span class="s1">'_auto_null'</span> |
| <span class="n">_auto_null</span> <span class="o">=</span> <span class="n">_auto_null</span><span class="p">()</span> |
| |
| <span class="k">class</span><span class="w"> </span><span class="nc">auto</span><span class="p">:</span> |
| <span class="w"> </span><span class="sd">"""</span> |
| <span class="sd"> Instances are replaced with an appropriate value in Enum class suites.</span> |
| <span class="sd"> """</span> |
| <span class="k">def</span><span class="w"> </span><span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">value</span><span class="o">=</span><span class="n">_auto_null</span><span class="p">):</span> |
| <span class="bp">self</span><span class="o">.</span><span class="n">value</span> <span class="o">=</span> <span class="n">value</span> |
| |
| <span class="k">def</span><span class="w"> </span><span class="fm">__repr__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span> |
| <span class="k">return</span> <span class="s2">"auto(</span><span class="si">%r</span><span class="s2">)"</span> <span class="o">%</span> <span class="bp">self</span><span class="o">.</span><span class="n">value</span> |
| |
| <span class="k">class</span><span class="w"> </span><span class="nc">property</span><span class="p">(</span><span class="n">DynamicClassAttribute</span><span class="p">):</span> |
| <span class="w"> </span><span class="sd">"""</span> |
| <span class="sd"> This is a descriptor, used to define attributes that act differently</span> |
| <span class="sd"> when accessed through an enum member and through an enum class.</span> |
| <span class="sd"> Instance access is the same as property(), but access to an attribute</span> |
| <span class="sd"> through the enum class will instead look in the class' _member_map_ for</span> |
| <span class="sd"> a corresponding enum member.</span> |
| <span class="sd"> """</span> |
| |
| <span class="n">member</span> <span class="o">=</span> <span class="kc">None</span> |
| <span class="n">_attr_type</span> <span class="o">=</span> <span class="kc">None</span> |
| <span class="n">_cls_type</span> <span class="o">=</span> <span class="kc">None</span> |
| |
| <span class="k">def</span><span class="w"> </span><span class="fm">__get__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">instance</span><span class="p">,</span> <span class="n">ownerclass</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span> |
| <span class="k">if</span> <span class="n">instance</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span> |
| <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">member</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span> |
| <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">member</span> |
| <span class="k">else</span><span class="p">:</span> |
| <span class="k">raise</span> <span class="ne">AttributeError</span><span class="p">(</span> |
| <span class="s1">'</span><span class="si">%r</span><span class="s1"> has no attribute </span><span class="si">%r</span><span class="s1">'</span> <span class="o">%</span> <span class="p">(</span><span class="n">ownerclass</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">name</span><span class="p">)</span> |
| <span class="p">)</span> |
| <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">fget</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span> |
| <span class="c1"># use previous enum.property</span> |
| <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">fget</span><span class="p">(</span><span class="n">instance</span><span class="p">)</span> |
| <span class="k">elif</span> <span class="bp">self</span><span class="o">.</span><span class="n">_attr_type</span> <span class="o">==</span> <span class="s1">'attr'</span><span class="p">:</span> |
| <span class="c1"># look up previous attibute</span> |
| <span class="k">return</span> <span class="nb">getattr</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_cls_type</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">name</span><span class="p">)</span> |
| <span class="k">elif</span> <span class="bp">self</span><span class="o">.</span><span class="n">_attr_type</span> <span class="o">==</span> <span class="s1">'desc'</span><span class="p">:</span> |
| <span class="c1"># use previous descriptor</span> |
| <span class="k">return</span> <span class="nb">getattr</span><span class="p">(</span><span class="n">instance</span><span class="o">.</span><span class="n">_value_</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">name</span><span class="p">)</span> |
| <span class="c1"># look for a member by this name.</span> |
| <span class="k">try</span><span class="p">:</span> |
| <span class="k">return</span> <span class="n">ownerclass</span><span class="o">.</span><span class="n">_member_map_</span><span class="p">[</span><span class="bp">self</span><span class="o">.</span><span class="n">name</span><span class="p">]</span> |
| <span class="k">except</span> <span class="ne">KeyError</span><span class="p">:</span> |
| <span class="k">raise</span> <span class="ne">AttributeError</span><span class="p">(</span> |
| <span class="s1">'</span><span class="si">%r</span><span class="s1"> has no attribute </span><span class="si">%r</span><span class="s1">'</span> <span class="o">%</span> <span class="p">(</span><span class="n">ownerclass</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">name</span><span class="p">)</span> |
| <span class="p">)</span> <span class="kn">from</span><span class="w"> </span><span class="kc">None</span> |
| |
| <span class="k">def</span><span class="w"> </span><span class="fm">__set__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">instance</span><span class="p">,</span> <span class="n">value</span><span class="p">):</span> |
| <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">fset</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span> |
| <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">fset</span><span class="p">(</span><span class="n">instance</span><span class="p">,</span> <span class="n">value</span><span class="p">)</span> |
| <span class="k">raise</span> <span class="ne">AttributeError</span><span class="p">(</span> |
| <span class="s2">"<enum </span><span class="si">%r</span><span class="s2">> cannot set attribute </span><span class="si">%r</span><span class="s2">"</span> <span class="o">%</span> <span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">clsname</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">name</span><span class="p">)</span> |
| <span class="p">)</span> |
| |
| <span class="k">def</span><span class="w"> </span><span class="fm">__delete__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">instance</span><span class="p">):</span> |
| <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">fdel</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span> |
| <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">fdel</span><span class="p">(</span><span class="n">instance</span><span class="p">)</span> |
| <span class="k">raise</span> <span class="ne">AttributeError</span><span class="p">(</span> |
| <span class="s2">"<enum </span><span class="si">%r</span><span class="s2">> cannot delete attribute </span><span class="si">%r</span><span class="s2">"</span> <span class="o">%</span> <span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">clsname</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">name</span><span class="p">)</span> |
| <span class="p">)</span> |
| |
| <span class="k">def</span><span class="w"> </span><span class="nf">__set_name__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">ownerclass</span><span class="p">,</span> <span class="n">name</span><span class="p">):</span> |
| <span class="bp">self</span><span class="o">.</span><span class="n">name</span> <span class="o">=</span> <span class="n">name</span> |
| <span class="bp">self</span><span class="o">.</span><span class="n">clsname</span> <span class="o">=</span> <span class="n">ownerclass</span><span class="o">.</span><span class="vm">__name__</span> |
| |
| |
| <span class="k">class</span><span class="w"> </span><span class="nc">_proto_member</span><span class="p">:</span> |
| <span class="w"> </span><span class="sd">"""</span> |
| <span class="sd"> intermediate step for enum members between class execution and final creation</span> |
| <span class="sd"> """</span> |
| |
| <span class="k">def</span><span class="w"> </span><span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">value</span><span class="p">):</span> |
| <span class="bp">self</span><span class="o">.</span><span class="n">value</span> <span class="o">=</span> <span class="n">value</span> |
| |
| <span class="k">def</span><span class="w"> </span><span class="nf">__set_name__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">enum_class</span><span class="p">,</span> <span class="n">member_name</span><span class="p">):</span> |
| <span class="w"> </span><span class="sd">"""</span> |
| <span class="sd"> convert each quasi-member into an instance of the new enum class</span> |
| <span class="sd"> """</span> |
| <span class="c1"># first step: remove ourself from enum_class</span> |
| <span class="nb">delattr</span><span class="p">(</span><span class="n">enum_class</span><span class="p">,</span> <span class="n">member_name</span><span class="p">)</span> |
| <span class="c1"># second step: create member based on enum_class</span> |
| <span class="n">value</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">value</span> |
| <span class="k">if</span> <span class="ow">not</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">value</span><span class="p">,</span> <span class="nb">tuple</span><span class="p">):</span> |
| <span class="n">args</span> <span class="o">=</span> <span class="p">(</span><span class="n">value</span><span class="p">,</span> <span class="p">)</span> |
| <span class="k">else</span><span class="p">:</span> |
| <span class="n">args</span> <span class="o">=</span> <span class="n">value</span> |
| <span class="k">if</span> <span class="n">enum_class</span><span class="o">.</span><span class="n">_member_type_</span> <span class="ow">is</span> <span class="nb">tuple</span><span class="p">:</span> <span class="c1"># special case for tuple enums</span> |
| <span class="n">args</span> <span class="o">=</span> <span class="p">(</span><span class="n">args</span><span class="p">,</span> <span class="p">)</span> <span class="c1"># wrap it one more time</span> |
| <span class="k">if</span> <span class="ow">not</span> <span class="n">enum_class</span><span class="o">.</span><span class="n">_use_args_</span><span class="p">:</span> |
| <span class="n">enum_member</span> <span class="o">=</span> <span class="n">enum_class</span><span class="o">.</span><span class="n">_new_member_</span><span class="p">(</span><span class="n">enum_class</span><span class="p">)</span> |
| <span class="k">else</span><span class="p">:</span> |
| <span class="n">enum_member</span> <span class="o">=</span> <span class="n">enum_class</span><span class="o">.</span><span class="n">_new_member_</span><span class="p">(</span><span class="n">enum_class</span><span class="p">,</span> <span class="o">*</span><span class="n">args</span><span class="p">)</span> |
| <span class="k">if</span> <span class="ow">not</span> <span class="nb">hasattr</span><span class="p">(</span><span class="n">enum_member</span><span class="p">,</span> <span class="s1">'_value_'</span><span class="p">):</span> |
| <span class="k">if</span> <span class="n">enum_class</span><span class="o">.</span><span class="n">_member_type_</span> <span class="ow">is</span> <span class="nb">object</span><span class="p">:</span> |
| <span class="n">enum_member</span><span class="o">.</span><span class="n">_value_</span> <span class="o">=</span> <span class="n">value</span> |
| <span class="k">else</span><span class="p">:</span> |
| <span class="k">try</span><span class="p">:</span> |
| <span class="n">enum_member</span><span class="o">.</span><span class="n">_value_</span> <span class="o">=</span> <span class="n">enum_class</span><span class="o">.</span><span class="n">_member_type_</span><span class="p">(</span><span class="o">*</span><span class="n">args</span><span class="p">)</span> |
| <span class="k">except</span> <span class="ne">Exception</span> <span class="k">as</span> <span class="n">exc</span><span class="p">:</span> |
| <span class="n">new_exc</span> <span class="o">=</span> <span class="ne">TypeError</span><span class="p">(</span> |
| <span class="s1">'_value_ not set in __new__, unable to create it'</span> |
| <span class="p">)</span> |
| <span class="n">new_exc</span><span class="o">.</span><span class="n">__cause__</span> <span class="o">=</span> <span class="n">exc</span> |
| <span class="k">raise</span> <span class="n">new_exc</span> |
| <span class="n">value</span> <span class="o">=</span> <span class="n">enum_member</span><span class="o">.</span><span class="n">_value_</span> |
| <span class="n">enum_member</span><span class="o">.</span><span class="n">_name_</span> <span class="o">=</span> <span class="n">member_name</span> |
| <span class="n">enum_member</span><span class="o">.</span><span class="vm">__objclass__</span> <span class="o">=</span> <span class="n">enum_class</span> |
| <span class="n">enum_member</span><span class="o">.</span><span class="fm">__init__</span><span class="p">(</span><span class="o">*</span><span class="n">args</span><span class="p">)</span> |
| <span class="n">enum_member</span><span class="o">.</span><span class="n">_sort_order_</span> <span class="o">=</span> <span class="nb">len</span><span class="p">(</span><span class="n">enum_class</span><span class="o">.</span><span class="n">_member_names_</span><span class="p">)</span> |
| |
| <span class="k">if</span> <span class="n">Flag</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span> <span class="ow">and</span> <span class="nb">issubclass</span><span class="p">(</span><span class="n">enum_class</span><span class="p">,</span> <span class="n">Flag</span><span class="p">):</span> |
| <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">value</span><span class="p">,</span> <span class="nb">int</span><span class="p">):</span> |
| <span class="n">enum_class</span><span class="o">.</span><span class="n">_flag_mask_</span> <span class="o">|=</span> <span class="n">value</span> |
| <span class="k">if</span> <span class="n">_is_single_bit</span><span class="p">(</span><span class="n">value</span><span class="p">):</span> |
| <span class="n">enum_class</span><span class="o">.</span><span class="n">_singles_mask_</span> <span class="o">|=</span> <span class="n">value</span> |
| <span class="n">enum_class</span><span class="o">.</span><span class="n">_all_bits_</span> <span class="o">=</span> <span class="mi">2</span> <span class="o">**</span> <span class="p">((</span><span class="n">enum_class</span><span class="o">.</span><span class="n">_flag_mask_</span><span class="p">)</span><span class="o">.</span><span class="n">bit_length</span><span class="p">())</span> <span class="o">-</span> <span class="mi">1</span> |
| |
| <span class="c1"># If another member with the same value was already defined, the</span> |
| <span class="c1"># new member becomes an alias to the existing one.</span> |
| <span class="k">try</span><span class="p">:</span> |
| <span class="k">try</span><span class="p">:</span> |
| <span class="c1"># try to do a fast lookup to avoid the quadratic loop</span> |
| <span class="n">enum_member</span> <span class="o">=</span> <span class="n">enum_class</span><span class="o">.</span><span class="n">_value2member_map_</span><span class="p">[</span><span class="n">value</span><span class="p">]</span> |
| <span class="k">except</span> <span class="ne">TypeError</span><span class="p">:</span> |
| <span class="k">for</span> <span class="n">name</span><span class="p">,</span> <span class="n">canonical_member</span> <span class="ow">in</span> <span class="n">enum_class</span><span class="o">.</span><span class="n">_member_map_</span><span class="o">.</span><span class="n">items</span><span class="p">():</span> |
| <span class="k">if</span> <span class="n">canonical_member</span><span class="o">.</span><span class="n">_value_</span> <span class="o">==</span> <span class="n">value</span><span class="p">:</span> |
| <span class="n">enum_member</span> <span class="o">=</span> <span class="n">canonical_member</span> |
| <span class="k">break</span> |
| <span class="k">else</span><span class="p">:</span> |
| <span class="k">raise</span> <span class="ne">KeyError</span> |
| <span class="k">except</span> <span class="ne">KeyError</span><span class="p">:</span> |
| <span class="c1"># this could still be an alias if the value is multi-bit and the</span> |
| <span class="c1"># class is a flag class</span> |
| <span class="k">if</span> <span class="p">(</span> |
| <span class="n">Flag</span> <span class="ow">is</span> <span class="kc">None</span> |
| <span class="ow">or</span> <span class="ow">not</span> <span class="nb">issubclass</span><span class="p">(</span><span class="n">enum_class</span><span class="p">,</span> <span class="n">Flag</span><span class="p">)</span> |
| <span class="p">):</span> |
| <span class="c1"># no other instances found, record this member in _member_names_</span> |
| <span class="n">enum_class</span><span class="o">.</span><span class="n">_member_names_</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">member_name</span><span class="p">)</span> |
| <span class="k">elif</span> <span class="p">(</span> |
| <span class="n">Flag</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span> |
| <span class="ow">and</span> <span class="nb">issubclass</span><span class="p">(</span><span class="n">enum_class</span><span class="p">,</span> <span class="n">Flag</span><span class="p">)</span> |
| <span class="ow">and</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">value</span><span class="p">,</span> <span class="nb">int</span><span class="p">)</span> |
| <span class="ow">and</span> <span class="n">_is_single_bit</span><span class="p">(</span><span class="n">value</span><span class="p">)</span> |
| <span class="p">):</span> |
| <span class="c1"># no other instances found, record this member in _member_names_</span> |
| <span class="n">enum_class</span><span class="o">.</span><span class="n">_member_names_</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">member_name</span><span class="p">)</span> |
| |
| <span class="n">enum_class</span><span class="o">.</span><span class="n">_add_member_</span><span class="p">(</span><span class="n">member_name</span><span class="p">,</span> <span class="n">enum_member</span><span class="p">)</span> |
| <span class="k">try</span><span class="p">:</span> |
| <span class="c1"># This may fail if value is not hashable. We can't add the value</span> |
| <span class="c1"># to the map, and by-value lookups for this value will be</span> |
| <span class="c1"># linear.</span> |
| <span class="n">enum_class</span><span class="o">.</span><span class="n">_value2member_map_</span><span class="o">.</span><span class="n">setdefault</span><span class="p">(</span><span class="n">value</span><span class="p">,</span> <span class="n">enum_member</span><span class="p">)</span> |
| <span class="k">if</span> <span class="n">value</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">enum_class</span><span class="o">.</span><span class="n">_hashable_values_</span><span class="p">:</span> |
| <span class="n">enum_class</span><span class="o">.</span><span class="n">_hashable_values_</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">value</span><span class="p">)</span> |
| <span class="k">except</span> <span class="ne">TypeError</span><span class="p">:</span> |
| <span class="c1"># keep track of the value in a list so containment checks are quick</span> |
| <span class="n">enum_class</span><span class="o">.</span><span class="n">_unhashable_values_</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">value</span><span class="p">)</span> |
| <span class="n">enum_class</span><span class="o">.</span><span class="n">_unhashable_values_map_</span><span class="o">.</span><span class="n">setdefault</span><span class="p">(</span><span class="n">member_name</span><span class="p">,</span> <span class="p">[])</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">value</span><span class="p">)</span> |
| |
| |
| <span class="k">class</span><span class="w"> </span><span class="nc">EnumDict</span><span class="p">(</span><span class="nb">dict</span><span class="p">):</span> |
| <span class="w"> </span><span class="sd">"""</span> |
| <span class="sd"> Track enum member order and ensure member names are not reused.</span> |
| |
| <span class="sd"> EnumType will use the names found in self._member_names as the</span> |
| <span class="sd"> enumeration member names.</span> |
| <span class="sd"> """</span> |
| <span class="k">def</span><span class="w"> </span><span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">cls_name</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span> |
| <span class="nb">super</span><span class="p">()</span><span class="o">.</span><span class="fm">__init__</span><span class="p">()</span> |
| <span class="bp">self</span><span class="o">.</span><span class="n">_member_names</span> <span class="o">=</span> <span class="p">{}</span> <span class="c1"># use a dict -- faster look-up than a list, and keeps insertion order since 3.7</span> |
| <span class="bp">self</span><span class="o">.</span><span class="n">_last_values</span> <span class="o">=</span> <span class="p">[]</span> |
| <span class="bp">self</span><span class="o">.</span><span class="n">_ignore</span> <span class="o">=</span> <span class="p">[]</span> |
| <span class="bp">self</span><span class="o">.</span><span class="n">_auto_called</span> <span class="o">=</span> <span class="kc">False</span> |
| <span class="bp">self</span><span class="o">.</span><span class="n">_cls_name</span> <span class="o">=</span> <span class="n">cls_name</span> |
| |
| <span class="k">def</span><span class="w"> </span><span class="fm">__setitem__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">key</span><span class="p">,</span> <span class="n">value</span><span class="p">):</span> |
| <span class="w"> </span><span class="sd">"""</span> |
| <span class="sd"> Changes anything not dundered or not a descriptor.</span> |
| |
| <span class="sd"> If an enum member name is used twice, an error is raised; duplicate</span> |
| <span class="sd"> values are not checked for.</span> |
| |
| <span class="sd"> Single underscore (sunder) names are reserved.</span> |
| <span class="sd"> """</span> |
| <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">_cls_name</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span> <span class="ow">and</span> <span class="n">_is_private</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_cls_name</span><span class="p">,</span> <span class="n">key</span><span class="p">):</span> |
| <span class="c1"># do nothing, name will be a normal attribute</span> |
| <span class="k">pass</span> |
| <span class="k">elif</span> <span class="n">_is_sunder</span><span class="p">(</span><span class="n">key</span><span class="p">):</span> |
| <span class="k">if</span> <span class="n">key</span> <span class="ow">not</span> <span class="ow">in</span> <span class="p">(</span> |
| <span class="s1">'_order_'</span><span class="p">,</span> |
| <span class="s1">'_generate_next_value_'</span><span class="p">,</span> <span class="s1">'_numeric_repr_'</span><span class="p">,</span> <span class="s1">'_missing_'</span><span class="p">,</span> <span class="s1">'_ignore_'</span><span class="p">,</span> |
| <span class="s1">'_iter_member_'</span><span class="p">,</span> <span class="s1">'_iter_member_by_value_'</span><span class="p">,</span> <span class="s1">'_iter_member_by_def_'</span><span class="p">,</span> |
| <span class="s1">'_add_alias_'</span><span class="p">,</span> <span class="s1">'_add_value_alias_'</span><span class="p">,</span> |
| <span class="c1"># While not in use internally, those are common for pretty</span> |
| <span class="c1"># printing and thus excluded from Enum's reservation of</span> |
| <span class="c1"># _sunder_ names</span> |
| <span class="p">)</span> <span class="ow">and</span> <span class="ow">not</span> <span class="n">key</span><span class="o">.</span><span class="n">startswith</span><span class="p">(</span><span class="s1">'_repr_'</span><span class="p">):</span> |
| <span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span> |
| <span class="s1">'_sunder_ names, such as </span><span class="si">%r</span><span class="s1">, are reserved for future Enum use'</span> |
| <span class="o">%</span> <span class="p">(</span><span class="n">key</span><span class="p">,</span> <span class="p">)</span> |
| <span class="p">)</span> |
| <span class="k">if</span> <span class="n">key</span> <span class="o">==</span> <span class="s1">'_generate_next_value_'</span><span class="p">:</span> |
| <span class="c1"># check if members already defined as auto()</span> |
| <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">_auto_called</span><span class="p">:</span> |
| <span class="k">raise</span> <span class="ne">TypeError</span><span class="p">(</span><span class="s2">"_generate_next_value_ must be defined before members"</span><span class="p">)</span> |
| <span class="n">_gnv</span> <span class="o">=</span> <span class="n">value</span><span class="o">.</span><span class="vm">__func__</span> <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">value</span><span class="p">,</span> <span class="nb">staticmethod</span><span class="p">)</span> <span class="k">else</span> <span class="n">value</span> |
| <span class="nb">setattr</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="s1">'_generate_next_value'</span><span class="p">,</span> <span class="n">_gnv</span><span class="p">)</span> |
| <span class="k">elif</span> <span class="n">key</span> <span class="o">==</span> <span class="s1">'_ignore_'</span><span class="p">:</span> |
| <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">value</span><span class="p">,</span> <span class="nb">str</span><span class="p">):</span> |
| <span class="n">value</span> <span class="o">=</span> <span class="n">value</span><span class="o">.</span><span class="n">replace</span><span class="p">(</span><span class="s1">','</span><span class="p">,</span><span class="s1">' '</span><span class="p">)</span><span class="o">.</span><span class="n">split</span><span class="p">()</span> |
| <span class="k">else</span><span class="p">:</span> |
| <span class="n">value</span> <span class="o">=</span> <span class="nb">list</span><span class="p">(</span><span class="n">value</span><span class="p">)</span> |
| <span class="bp">self</span><span class="o">.</span><span class="n">_ignore</span> <span class="o">=</span> <span class="n">value</span> |
| <span class="n">already</span> <span class="o">=</span> <span class="nb">set</span><span class="p">(</span><span class="n">value</span><span class="p">)</span> <span class="o">&</span> <span class="nb">set</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_member_names</span><span class="p">)</span> |
| <span class="k">if</span> <span class="n">already</span><span class="p">:</span> |
| <span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span> |
| <span class="s1">'_ignore_ cannot specify already set names: </span><span class="si">%r</span><span class="s1">'</span> |
| <span class="o">%</span> <span class="p">(</span><span class="n">already</span><span class="p">,</span> <span class="p">)</span> |
| <span class="p">)</span> |
| <span class="k">elif</span> <span class="n">_is_dunder</span><span class="p">(</span><span class="n">key</span><span class="p">):</span> |
| <span class="k">if</span> <span class="n">key</span> <span class="o">==</span> <span class="s1">'__order__'</span><span class="p">:</span> |
| <span class="n">key</span> <span class="o">=</span> <span class="s1">'_order_'</span> |
| <span class="k">elif</span> <span class="n">key</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">_member_names</span><span class="p">:</span> |
| <span class="c1"># descriptor overwriting an enum?</span> |
| <span class="k">raise</span> <span class="ne">TypeError</span><span class="p">(</span><span class="s1">'</span><span class="si">%r</span><span class="s1"> already defined as </span><span class="si">%r</span><span class="s1">'</span> <span class="o">%</span> <span class="p">(</span><span class="n">key</span><span class="p">,</span> <span class="bp">self</span><span class="p">[</span><span class="n">key</span><span class="p">]))</span> |
| <span class="k">elif</span> <span class="n">key</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">_ignore</span><span class="p">:</span> |
| <span class="k">pass</span> |
| <span class="k">elif</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">value</span><span class="p">,</span> <span class="n">nonmember</span><span class="p">):</span> |
| <span class="c1"># unwrap value here; it won't be processed by the below `else`</span> |
| <span class="n">value</span> <span class="o">=</span> <span class="n">value</span><span class="o">.</span><span class="n">value</span> |
| <span class="k">elif</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">value</span><span class="p">,</span> <span class="n">partial</span><span class="p">):</span> |
| <span class="kn">import</span><span class="w"> </span><span class="nn">warnings</span> |
| <span class="n">warnings</span><span class="o">.</span><span class="n">warn</span><span class="p">(</span><span class="s1">'functools.partial will be a method descriptor '</span> |
| <span class="s1">'in future Python versions; wrap it in '</span> |
| <span class="s1">'enum.member() if you want to preserve the '</span> |
| <span class="s1">'old behavior'</span><span class="p">,</span> <span class="ne">FutureWarning</span><span class="p">,</span> <span class="n">stacklevel</span><span class="o">=</span><span class="mi">2</span><span class="p">)</span> |
| <span class="k">elif</span> <span class="n">_is_descriptor</span><span class="p">(</span><span class="n">value</span><span class="p">):</span> |
| <span class="k">pass</span> |
| <span class="k">elif</span> <span class="bp">self</span><span class="o">.</span><span class="n">_cls_name</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span> <span class="ow">and</span> <span class="n">_is_internal_class</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_cls_name</span><span class="p">,</span> <span class="n">value</span><span class="p">):</span> |
| <span class="c1"># do nothing, name will be a normal attribute</span> |
| <span class="k">pass</span> |
| <span class="k">else</span><span class="p">:</span> |
| <span class="k">if</span> <span class="n">key</span> <span class="ow">in</span> <span class="bp">self</span><span class="p">:</span> |
| <span class="c1"># enum overwriting a descriptor?</span> |
| <span class="k">raise</span> <span class="ne">TypeError</span><span class="p">(</span><span class="s1">'</span><span class="si">%r</span><span class="s1"> already defined as </span><span class="si">%r</span><span class="s1">'</span> <span class="o">%</span> <span class="p">(</span><span class="n">key</span><span class="p">,</span> <span class="bp">self</span><span class="p">[</span><span class="n">key</span><span class="p">]))</span> |
| <span class="k">elif</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">value</span><span class="p">,</span> <span class="n">member</span><span class="p">):</span> |
| <span class="c1"># unwrap value here -- it will become a member</span> |
| <span class="n">value</span> <span class="o">=</span> <span class="n">value</span><span class="o">.</span><span class="n">value</span> |
| <span class="n">non_auto_store</span> <span class="o">=</span> <span class="kc">True</span> |
| <span class="n">single</span> <span class="o">=</span> <span class="kc">False</span> |
| <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">value</span><span class="p">,</span> <span class="n">auto</span><span class="p">):</span> |
| <span class="n">single</span> <span class="o">=</span> <span class="kc">True</span> |
| <span class="n">value</span> <span class="o">=</span> <span class="p">(</span><span class="n">value</span><span class="p">,</span> <span class="p">)</span> |
| <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">value</span><span class="p">,</span> <span class="nb">tuple</span><span class="p">)</span> <span class="ow">and</span> <span class="nb">any</span><span class="p">(</span><span class="nb">isinstance</span><span class="p">(</span><span class="n">v</span><span class="p">,</span> <span class="n">auto</span><span class="p">)</span> <span class="k">for</span> <span class="n">v</span> <span class="ow">in</span> <span class="n">value</span><span class="p">):</span> |
| <span class="c1"># insist on an actual tuple, no subclasses, in keeping with only supporting</span> |
| <span class="c1"># top-level auto() usage (not contained in any other data structure)</span> |
| <span class="n">auto_valued</span> <span class="o">=</span> <span class="p">[]</span> |
| <span class="n">t</span> <span class="o">=</span> <span class="nb">type</span><span class="p">(</span><span class="n">value</span><span class="p">)</span> |
| <span class="k">for</span> <span class="n">v</span> <span class="ow">in</span> <span class="n">value</span><span class="p">:</span> |
| <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">v</span><span class="p">,</span> <span class="n">auto</span><span class="p">):</span> |
| <span class="n">non_auto_store</span> <span class="o">=</span> <span class="kc">False</span> |
| <span class="k">if</span> <span class="n">v</span><span class="o">.</span><span class="n">value</span> <span class="o">==</span> <span class="n">_auto_null</span><span class="p">:</span> |
| <span class="n">v</span><span class="o">.</span><span class="n">value</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_generate_next_value</span><span class="p">(</span> |
| <span class="n">key</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="nb">len</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_member_names</span><span class="p">),</span> <span class="bp">self</span><span class="o">.</span><span class="n">_last_values</span><span class="p">[:],</span> |
| <span class="p">)</span> |
| <span class="bp">self</span><span class="o">.</span><span class="n">_auto_called</span> <span class="o">=</span> <span class="kc">True</span> |
| <span class="n">v</span> <span class="o">=</span> <span class="n">v</span><span class="o">.</span><span class="n">value</span> |
| <span class="bp">self</span><span class="o">.</span><span class="n">_last_values</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">v</span><span class="p">)</span> |
| <span class="n">auto_valued</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">v</span><span class="p">)</span> |
| <span class="k">if</span> <span class="n">single</span><span class="p">:</span> |
| <span class="n">value</span> <span class="o">=</span> <span class="n">auto_valued</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> |
| <span class="k">else</span><span class="p">:</span> |
| <span class="k">try</span><span class="p">:</span> |
| <span class="c1"># accepts iterable as multiple arguments?</span> |
| <span class="n">value</span> <span class="o">=</span> <span class="n">t</span><span class="p">(</span><span class="n">auto_valued</span><span class="p">)</span> |
| <span class="k">except</span> <span class="ne">TypeError</span><span class="p">:</span> |
| <span class="c1"># then pass them in singly</span> |
| <span class="n">value</span> <span class="o">=</span> <span class="n">t</span><span class="p">(</span><span class="o">*</span><span class="n">auto_valued</span><span class="p">)</span> |
| <span class="bp">self</span><span class="o">.</span><span class="n">_member_names</span><span class="p">[</span><span class="n">key</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span> |
| <span class="k">if</span> <span class="n">non_auto_store</span><span class="p">:</span> |
| <span class="bp">self</span><span class="o">.</span><span class="n">_last_values</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">value</span><span class="p">)</span> |
| <span class="nb">super</span><span class="p">()</span><span class="o">.</span><span class="fm">__setitem__</span><span class="p">(</span><span class="n">key</span><span class="p">,</span> <span class="n">value</span><span class="p">)</span> |
| |
| <span class="nd">@property</span> |
| <span class="k">def</span><span class="w"> </span><span class="nf">member_names</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span> |
| <span class="k">return</span> <span class="nb">list</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_member_names</span><span class="p">)</span> |
| |
| <span class="k">def</span><span class="w"> </span><span class="nf">update</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">members</span><span class="p">,</span> <span class="o">**</span><span class="n">more_members</span><span class="p">):</span> |
| <span class="k">try</span><span class="p">:</span> |
| <span class="k">for</span> <span class="n">name</span> <span class="ow">in</span> <span class="n">members</span><span class="o">.</span><span class="n">keys</span><span class="p">():</span> |
| <span class="bp">self</span><span class="p">[</span><span class="n">name</span><span class="p">]</span> <span class="o">=</span> <span class="n">members</span><span class="p">[</span><span class="n">name</span><span class="p">]</span> |
| <span class="k">except</span> <span class="ne">AttributeError</span><span class="p">:</span> |
| <span class="k">for</span> <span class="n">name</span><span class="p">,</span> <span class="n">value</span> <span class="ow">in</span> <span class="n">members</span><span class="p">:</span> |
| <span class="bp">self</span><span class="p">[</span><span class="n">name</span><span class="p">]</span> <span class="o">=</span> <span class="n">value</span> |
| <span class="k">for</span> <span class="n">name</span><span class="p">,</span> <span class="n">value</span> <span class="ow">in</span> <span class="n">more_members</span><span class="o">.</span><span class="n">items</span><span class="p">():</span> |
| <span class="bp">self</span><span class="p">[</span><span class="n">name</span><span class="p">]</span> <span class="o">=</span> <span class="n">value</span> |
| |
| <span class="n">_EnumDict</span> <span class="o">=</span> <span class="n">EnumDict</span> <span class="c1"># keep private name for backwards compatibility</span> |
| |
| |
| <span class="k">class</span><span class="w"> </span><span class="nc">EnumType</span><span class="p">(</span><span class="nb">type</span><span class="p">):</span> |
| <span class="w"> </span><span class="sd">"""</span> |
| <span class="sd"> Metaclass for Enum</span> |
| <span class="sd"> """</span> |
| |
| <span class="nd">@classmethod</span> |
| <span class="k">def</span><span class="w"> </span><span class="fm">__prepare__</span><span class="p">(</span><span class="n">metacls</span><span class="p">,</span> <span class="bp">cls</span><span class="p">,</span> <span class="n">bases</span><span class="p">,</span> <span class="o">**</span><span class="n">kwds</span><span class="p">):</span> |
| <span class="c1"># check that previous enum members do not exist</span> |
| <span class="n">metacls</span><span class="o">.</span><span class="n">_check_for_existing_members_</span><span class="p">(</span><span class="bp">cls</span><span class="p">,</span> <span class="n">bases</span><span class="p">)</span> |
| <span class="c1"># create the namespace dict</span> |
| <span class="n">enum_dict</span> <span class="o">=</span> <span class="n">EnumDict</span><span class="p">(</span><span class="bp">cls</span><span class="p">)</span> |
| <span class="c1"># inherit previous flags and _generate_next_value_ function</span> |
| <span class="n">member_type</span><span class="p">,</span> <span class="n">first_enum</span> <span class="o">=</span> <span class="n">metacls</span><span class="o">.</span><span class="n">_get_mixins_</span><span class="p">(</span><span class="bp">cls</span><span class="p">,</span> <span class="n">bases</span><span class="p">)</span> |
| <span class="k">if</span> <span class="n">first_enum</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span> |
| <span class="n">enum_dict</span><span class="p">[</span><span class="s1">'_generate_next_value_'</span><span class="p">]</span> <span class="o">=</span> <span class="nb">getattr</span><span class="p">(</span> |
| <span class="n">first_enum</span><span class="p">,</span> <span class="s1">'_generate_next_value_'</span><span class="p">,</span> <span class="kc">None</span><span class="p">,</span> |
| <span class="p">)</span> |
| <span class="k">return</span> <span class="n">enum_dict</span> |
| |
| <span class="k">def</span><span class="w"> </span><span class="fm">__new__</span><span class="p">(</span><span class="n">metacls</span><span class="p">,</span> <span class="bp">cls</span><span class="p">,</span> <span class="n">bases</span><span class="p">,</span> <span class="n">classdict</span><span class="p">,</span> <span class="o">*</span><span class="p">,</span> <span class="n">boundary</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">_simple</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span> <span class="o">**</span><span class="n">kwds</span><span class="p">):</span> |
| <span class="c1"># an Enum class is final once enumeration items have been defined; it</span> |
| <span class="c1"># cannot be mixed with other types (int, float, etc.) if it has an</span> |
| <span class="c1"># inherited __new__ unless a new __new__ is defined (or the resulting</span> |
| <span class="c1"># class will fail).</span> |
| <span class="c1">#</span> |
| <span class="k">if</span> <span class="n">_simple</span><span class="p">:</span> |
| <span class="k">return</span> <span class="nb">super</span><span class="p">()</span><span class="o">.</span><span class="fm">__new__</span><span class="p">(</span><span class="n">metacls</span><span class="p">,</span> <span class="bp">cls</span><span class="p">,</span> <span class="n">bases</span><span class="p">,</span> <span class="n">classdict</span><span class="p">,</span> <span class="o">**</span><span class="n">kwds</span><span class="p">)</span> |
| <span class="c1">#</span> |
| <span class="c1"># remove any keys listed in _ignore_</span> |
| <span class="n">classdict</span><span class="o">.</span><span class="n">setdefault</span><span class="p">(</span><span class="s1">'_ignore_'</span><span class="p">,</span> <span class="p">[])</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="s1">'_ignore_'</span><span class="p">)</span> |
| <span class="n">ignore</span> <span class="o">=</span> <span class="n">classdict</span><span class="p">[</span><span class="s1">'_ignore_'</span><span class="p">]</span> |
| <span class="k">for</span> <span class="n">key</span> <span class="ow">in</span> <span class="n">ignore</span><span class="p">:</span> |
| <span class="n">classdict</span><span class="o">.</span><span class="n">pop</span><span class="p">(</span><span class="n">key</span><span class="p">,</span> <span class="kc">None</span><span class="p">)</span> |
| <span class="c1">#</span> |
| <span class="c1"># grab member names</span> |
| <span class="n">member_names</span> <span class="o">=</span> <span class="n">classdict</span><span class="o">.</span><span class="n">_member_names</span> |
| <span class="c1">#</span> |
| <span class="c1"># check for illegal enum names (any others?)</span> |
| <span class="n">invalid_names</span> <span class="o">=</span> <span class="nb">set</span><span class="p">(</span><span class="n">member_names</span><span class="p">)</span> <span class="o">&</span> <span class="p">{</span><span class="s1">'mro'</span><span class="p">,</span> <span class="s1">''</span><span class="p">}</span> |
| <span class="k">if</span> <span class="n">invalid_names</span><span class="p">:</span> |
| <span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="s1">'invalid enum member name(s) </span><span class="si">%s</span><span class="s1">'</span> <span class="o">%</span> <span class="p">(</span> |
| <span class="s1">','</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="nb">repr</span><span class="p">(</span><span class="n">n</span><span class="p">)</span> <span class="k">for</span> <span class="n">n</span> <span class="ow">in</span> <span class="n">invalid_names</span><span class="p">)</span> |
| <span class="p">))</span> |
| <span class="c1">#</span> |
| <span class="c1"># adjust the sunders</span> |
| <span class="n">_order_</span> <span class="o">=</span> <span class="n">classdict</span><span class="o">.</span><span class="n">pop</span><span class="p">(</span><span class="s1">'_order_'</span><span class="p">,</span> <span class="kc">None</span><span class="p">)</span> |
| <span class="n">_gnv</span> <span class="o">=</span> <span class="n">classdict</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s1">'_generate_next_value_'</span><span class="p">)</span> |
| <span class="k">if</span> <span class="n">_gnv</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span> <span class="ow">and</span> <span class="nb">type</span><span class="p">(</span><span class="n">_gnv</span><span class="p">)</span> <span class="ow">is</span> <span class="ow">not</span> <span class="nb">staticmethod</span><span class="p">:</span> |
| <span class="n">_gnv</span> <span class="o">=</span> <span class="nb">staticmethod</span><span class="p">(</span><span class="n">_gnv</span><span class="p">)</span> |
| <span class="c1"># convert to normal dict</span> |
| <span class="n">classdict</span> <span class="o">=</span> <span class="nb">dict</span><span class="p">(</span><span class="n">classdict</span><span class="o">.</span><span class="n">items</span><span class="p">())</span> |
| <span class="k">if</span> <span class="n">_gnv</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span> |
| <span class="n">classdict</span><span class="p">[</span><span class="s1">'_generate_next_value_'</span><span class="p">]</span> <span class="o">=</span> <span class="n">_gnv</span> |
| <span class="c1">#</span> |
| <span class="c1"># data type of member and the controlling Enum class</span> |
| <span class="n">member_type</span><span class="p">,</span> <span class="n">first_enum</span> <span class="o">=</span> <span class="n">metacls</span><span class="o">.</span><span class="n">_get_mixins_</span><span class="p">(</span><span class="bp">cls</span><span class="p">,</span> <span class="n">bases</span><span class="p">)</span> |
| <span class="fm">__new__</span><span class="p">,</span> <span class="n">save_new</span><span class="p">,</span> <span class="n">use_args</span> <span class="o">=</span> <span class="n">metacls</span><span class="o">.</span><span class="n">_find_new_</span><span class="p">(</span> |
| <span class="n">classdict</span><span class="p">,</span> <span class="n">member_type</span><span class="p">,</span> <span class="n">first_enum</span><span class="p">,</span> |
| <span class="p">)</span> |
| <span class="n">classdict</span><span class="p">[</span><span class="s1">'_new_member_'</span><span class="p">]</span> <span class="o">=</span> <span class="fm">__new__</span> |
| <span class="n">classdict</span><span class="p">[</span><span class="s1">'_use_args_'</span><span class="p">]</span> <span class="o">=</span> <span class="n">use_args</span> |
| <span class="c1">#</span> |
| <span class="c1"># convert future enum members into temporary _proto_members</span> |
| <span class="k">for</span> <span class="n">name</span> <span class="ow">in</span> <span class="n">member_names</span><span class="p">:</span> |
| <span class="n">value</span> <span class="o">=</span> <span class="n">classdict</span><span class="p">[</span><span class="n">name</span><span class="p">]</span> |
| <span class="n">classdict</span><span class="p">[</span><span class="n">name</span><span class="p">]</span> <span class="o">=</span> <span class="n">_proto_member</span><span class="p">(</span><span class="n">value</span><span class="p">)</span> |
| <span class="c1">#</span> |
| <span class="c1"># house-keeping structures</span> |
| <span class="n">classdict</span><span class="p">[</span><span class="s1">'_member_names_'</span><span class="p">]</span> <span class="o">=</span> <span class="p">[]</span> |
| <span class="n">classdict</span><span class="p">[</span><span class="s1">'_member_map_'</span><span class="p">]</span> <span class="o">=</span> <span class="p">{}</span> |
| <span class="n">classdict</span><span class="p">[</span><span class="s1">'_value2member_map_'</span><span class="p">]</span> <span class="o">=</span> <span class="p">{}</span> |
| <span class="n">classdict</span><span class="p">[</span><span class="s1">'_hashable_values_'</span><span class="p">]</span> <span class="o">=</span> <span class="p">[]</span> <span class="c1"># for comparing with non-hashable types</span> |
| <span class="n">classdict</span><span class="p">[</span><span class="s1">'_unhashable_values_'</span><span class="p">]</span> <span class="o">=</span> <span class="p">[]</span> <span class="c1"># e.g. frozenset() with set()</span> |
| <span class="n">classdict</span><span class="p">[</span><span class="s1">'_unhashable_values_map_'</span><span class="p">]</span> <span class="o">=</span> <span class="p">{}</span> |
| <span class="n">classdict</span><span class="p">[</span><span class="s1">'_member_type_'</span><span class="p">]</span> <span class="o">=</span> <span class="n">member_type</span> |
| <span class="c1"># now set the __repr__ for the value</span> |
| <span class="n">classdict</span><span class="p">[</span><span class="s1">'_value_repr_'</span><span class="p">]</span> <span class="o">=</span> <span class="n">metacls</span><span class="o">.</span><span class="n">_find_data_repr_</span><span class="p">(</span><span class="bp">cls</span><span class="p">,</span> <span class="n">bases</span><span class="p">)</span> |
| <span class="c1">#</span> |
| <span class="c1"># Flag structures (will be removed if final class is not a Flag</span> |
| <span class="n">classdict</span><span class="p">[</span><span class="s1">'_boundary_'</span><span class="p">]</span> <span class="o">=</span> <span class="p">(</span> |
| <span class="n">boundary</span> |
| <span class="ow">or</span> <span class="nb">getattr</span><span class="p">(</span><span class="n">first_enum</span><span class="p">,</span> <span class="s1">'_boundary_'</span><span class="p">,</span> <span class="kc">None</span><span class="p">)</span> |
| <span class="p">)</span> |
| <span class="n">classdict</span><span class="p">[</span><span class="s1">'_flag_mask_'</span><span class="p">]</span> <span class="o">=</span> <span class="mi">0</span> |
| <span class="n">classdict</span><span class="p">[</span><span class="s1">'_singles_mask_'</span><span class="p">]</span> <span class="o">=</span> <span class="mi">0</span> |
| <span class="n">classdict</span><span class="p">[</span><span class="s1">'_all_bits_'</span><span class="p">]</span> <span class="o">=</span> <span class="mi">0</span> |
| <span class="n">classdict</span><span class="p">[</span><span class="s1">'_inverted_'</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span> |
| <span class="k">try</span><span class="p">:</span> |
| <span class="n">classdict</span><span class="p">[</span><span class="s1">'_</span><span class="si">%s</span><span class="s1">__in_progress'</span> <span class="o">%</span> <span class="bp">cls</span><span class="p">]</span> <span class="o">=</span> <span class="kc">True</span> |
| <span class="n">enum_class</span> <span class="o">=</span> <span class="nb">super</span><span class="p">()</span><span class="o">.</span><span class="fm">__new__</span><span class="p">(</span><span class="n">metacls</span><span class="p">,</span> <span class="bp">cls</span><span class="p">,</span> <span class="n">bases</span><span class="p">,</span> <span class="n">classdict</span><span class="p">,</span> <span class="o">**</span><span class="n">kwds</span><span class="p">)</span> |
| <span class="n">classdict</span><span class="p">[</span><span class="s1">'_</span><span class="si">%s</span><span class="s1">__in_progress'</span> <span class="o">%</span> <span class="bp">cls</span><span class="p">]</span> <span class="o">=</span> <span class="kc">False</span> |
| <span class="nb">delattr</span><span class="p">(</span><span class="n">enum_class</span><span class="p">,</span> <span class="s1">'_</span><span class="si">%s</span><span class="s1">__in_progress'</span> <span class="o">%</span> <span class="bp">cls</span><span class="p">)</span> |
| <span class="k">except</span> <span class="ne">Exception</span> <span class="k">as</span> <span class="n">e</span><span class="p">:</span> |
| <span class="c1"># since 3.12 the note "Error calling __set_name__ on '_proto_member' instance ..."</span> |
| <span class="c1"># is tacked on to the error instead of raising a RuntimeError, so discard it</span> |
| <span class="k">if</span> <span class="nb">hasattr</span><span class="p">(</span><span class="n">e</span><span class="p">,</span> <span class="s1">'__notes__'</span><span class="p">):</span> |
| <span class="k">del</span> <span class="n">e</span><span class="o">.</span><span class="n">__notes__</span> |
| <span class="k">raise</span> |
| <span class="c1"># update classdict with any changes made by __init_subclass__</span> |
| <span class="n">classdict</span><span class="o">.</span><span class="n">update</span><span class="p">(</span><span class="n">enum_class</span><span class="o">.</span><span class="vm">__dict__</span><span class="p">)</span> |
| <span class="c1">#</span> |
| <span class="c1"># double check that repr and friends are not the mixin's or various</span> |
| <span class="c1"># things break (such as pickle)</span> |
| <span class="c1"># however, if the method is defined in the Enum itself, don't replace</span> |
| <span class="c1"># it</span> |
| <span class="c1">#</span> |
| <span class="c1"># Also, special handling for ReprEnum</span> |
| <span class="k">if</span> <span class="n">ReprEnum</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span> <span class="ow">and</span> <span class="n">ReprEnum</span> <span class="ow">in</span> <span class="n">bases</span><span class="p">:</span> |
| <span class="k">if</span> <span class="n">member_type</span> <span class="ow">is</span> <span class="nb">object</span><span class="p">:</span> |
| <span class="k">raise</span> <span class="ne">TypeError</span><span class="p">(</span> |
| <span class="s1">'ReprEnum subclasses must be mixed with a data type (i.e.'</span> |
| <span class="s1">' int, str, float, etc.)'</span> |
| <span class="p">)</span> |
| <span class="k">if</span> <span class="s1">'__format__'</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">classdict</span><span class="p">:</span> |
| <span class="n">enum_class</span><span class="o">.</span><span class="fm">__format__</span> <span class="o">=</span> <span class="n">member_type</span><span class="o">.</span><span class="fm">__format__</span> |
| <span class="n">classdict</span><span class="p">[</span><span class="s1">'__format__'</span><span class="p">]</span> <span class="o">=</span> <span class="n">enum_class</span><span class="o">.</span><span class="fm">__format__</span> |
| <span class="k">if</span> <span class="s1">'__str__'</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">classdict</span><span class="p">:</span> |
| <span class="n">method</span> <span class="o">=</span> <span class="n">member_type</span><span class="o">.</span><span class="fm">__str__</span> |
| <span class="k">if</span> <span class="n">method</span> <span class="ow">is</span> <span class="nb">object</span><span class="o">.</span><span class="fm">__str__</span><span class="p">:</span> |
| <span class="c1"># if member_type does not define __str__, object.__str__ will use</span> |
| <span class="c1"># its __repr__ instead, so we'll also use its __repr__</span> |
| <span class="n">method</span> <span class="o">=</span> <span class="n">member_type</span><span class="o">.</span><span class="fm">__repr__</span> |
| <span class="n">enum_class</span><span class="o">.</span><span class="fm">__str__</span> <span class="o">=</span> <span class="n">method</span> |
| <span class="n">classdict</span><span class="p">[</span><span class="s1">'__str__'</span><span class="p">]</span> <span class="o">=</span> <span class="n">enum_class</span><span class="o">.</span><span class="fm">__str__</span> |
| <span class="k">for</span> <span class="n">name</span> <span class="ow">in</span> <span class="p">(</span><span class="s1">'__repr__'</span><span class="p">,</span> <span class="s1">'__str__'</span><span class="p">,</span> <span class="s1">'__format__'</span><span class="p">,</span> <span class="s1">'__reduce_ex__'</span><span class="p">):</span> |
| <span class="k">if</span> <span class="n">name</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">classdict</span><span class="p">:</span> |
| <span class="c1"># check for mixin overrides before replacing</span> |
| <span class="n">enum_method</span> <span class="o">=</span> <span class="nb">getattr</span><span class="p">(</span><span class="n">first_enum</span><span class="p">,</span> <span class="n">name</span><span class="p">)</span> |
| <span class="n">found_method</span> <span class="o">=</span> <span class="nb">getattr</span><span class="p">(</span><span class="n">enum_class</span><span class="p">,</span> <span class="n">name</span><span class="p">)</span> |
| <span class="n">object_method</span> <span class="o">=</span> <span class="nb">getattr</span><span class="p">(</span><span class="nb">object</span><span class="p">,</span> <span class="n">name</span><span class="p">)</span> |
| <span class="n">data_type_method</span> <span class="o">=</span> <span class="nb">getattr</span><span class="p">(</span><span class="n">member_type</span><span class="p">,</span> <span class="n">name</span><span class="p">)</span> |
| <span class="k">if</span> <span class="n">found_method</span> <span class="ow">in</span> <span class="p">(</span><span class="n">data_type_method</span><span class="p">,</span> <span class="n">object_method</span><span class="p">):</span> |
| <span class="nb">setattr</span><span class="p">(</span><span class="n">enum_class</span><span class="p">,</span> <span class="n">name</span><span class="p">,</span> <span class="n">enum_method</span><span class="p">)</span> |
| <span class="c1">#</span> |
| <span class="c1"># for Flag, add __or__, __and__, __xor__, and __invert__</span> |
| <span class="k">if</span> <span class="n">Flag</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span> <span class="ow">and</span> <span class="nb">issubclass</span><span class="p">(</span><span class="n">enum_class</span><span class="p">,</span> <span class="n">Flag</span><span class="p">):</span> |
| <span class="k">for</span> <span class="n">name</span> <span class="ow">in</span> <span class="p">(</span> |
| <span class="s1">'__or__'</span><span class="p">,</span> <span class="s1">'__and__'</span><span class="p">,</span> <span class="s1">'__xor__'</span><span class="p">,</span> |
| <span class="s1">'__ror__'</span><span class="p">,</span> <span class="s1">'__rand__'</span><span class="p">,</span> <span class="s1">'__rxor__'</span><span class="p">,</span> |
| <span class="s1">'__invert__'</span> |
| <span class="p">):</span> |
| <span class="k">if</span> <span class="n">name</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">classdict</span><span class="p">:</span> |
| <span class="n">enum_method</span> <span class="o">=</span> <span class="nb">getattr</span><span class="p">(</span><span class="n">Flag</span><span class="p">,</span> <span class="n">name</span><span class="p">)</span> |
| <span class="nb">setattr</span><span class="p">(</span><span class="n">enum_class</span><span class="p">,</span> <span class="n">name</span><span class="p">,</span> <span class="n">enum_method</span><span class="p">)</span> |
| <span class="n">classdict</span><span class="p">[</span><span class="n">name</span><span class="p">]</span> <span class="o">=</span> <span class="n">enum_method</span> |
| <span class="c1">#</span> |
| <span class="c1"># replace any other __new__ with our own (as long as Enum is not None,</span> |
| <span class="c1"># anyway) -- again, this is to support pickle</span> |
| <span class="k">if</span> <span class="n">Enum</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span> |
| <span class="c1"># if the user defined their own __new__, save it before it gets</span> |
| <span class="c1"># clobbered in case they subclass later</span> |
| <span class="k">if</span> <span class="n">save_new</span><span class="p">:</span> |
| <span class="n">enum_class</span><span class="o">.</span><span class="n">__new_member__</span> <span class="o">=</span> <span class="fm">__new__</span> |
| <span class="n">enum_class</span><span class="o">.</span><span class="fm">__new__</span> <span class="o">=</span> <span class="n">Enum</span><span class="o">.</span><span class="fm">__new__</span> |
| <span class="c1">#</span> |
| <span class="c1"># py3 support for definition order (helps keep py2/py3 code in sync)</span> |
| <span class="c1">#</span> |
| <span class="c1"># _order_ checking is spread out into three/four steps</span> |
| <span class="c1"># - if enum_class is a Flag:</span> |
| <span class="c1"># - remove any non-single-bit flags from _order_</span> |
| <span class="c1"># - remove any aliases from _order_</span> |
| <span class="c1"># - check that _order_ and _member_names_ match</span> |
| <span class="c1">#</span> |
| <span class="c1"># step 1: ensure we have a list</span> |
| <span class="k">if</span> <span class="n">_order_</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span> |
| <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">_order_</span><span class="p">,</span> <span class="nb">str</span><span class="p">):</span> |
| <span class="n">_order_</span> <span class="o">=</span> <span class="n">_order_</span><span class="o">.</span><span class="n">replace</span><span class="p">(</span><span class="s1">','</span><span class="p">,</span> <span class="s1">' '</span><span class="p">)</span><span class="o">.</span><span class="n">split</span><span class="p">()</span> |
| <span class="c1">#</span> |
| <span class="c1"># remove Flag structures if final class is not a Flag</span> |
| <span class="k">if</span> <span class="p">(</span> |
| <span class="n">Flag</span> <span class="ow">is</span> <span class="kc">None</span> <span class="ow">and</span> <span class="bp">cls</span> <span class="o">!=</span> <span class="s1">'Flag'</span> |
| <span class="ow">or</span> <span class="n">Flag</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span> <span class="ow">and</span> <span class="ow">not</span> <span class="nb">issubclass</span><span class="p">(</span><span class="n">enum_class</span><span class="p">,</span> <span class="n">Flag</span><span class="p">)</span> |
| <span class="p">):</span> |
| <span class="nb">delattr</span><span class="p">(</span><span class="n">enum_class</span><span class="p">,</span> <span class="s1">'_boundary_'</span><span class="p">)</span> |
| <span class="nb">delattr</span><span class="p">(</span><span class="n">enum_class</span><span class="p">,</span> <span class="s1">'_flag_mask_'</span><span class="p">)</span> |
| <span class="nb">delattr</span><span class="p">(</span><span class="n">enum_class</span><span class="p">,</span> <span class="s1">'_singles_mask_'</span><span class="p">)</span> |
| <span class="nb">delattr</span><span class="p">(</span><span class="n">enum_class</span><span class="p">,</span> <span class="s1">'_all_bits_'</span><span class="p">)</span> |
| <span class="nb">delattr</span><span class="p">(</span><span class="n">enum_class</span><span class="p">,</span> <span class="s1">'_inverted_'</span><span class="p">)</span> |
| <span class="k">elif</span> <span class="n">Flag</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span> <span class="ow">and</span> <span class="nb">issubclass</span><span class="p">(</span><span class="n">enum_class</span><span class="p">,</span> <span class="n">Flag</span><span class="p">):</span> |
| <span class="c1"># set correct __iter__</span> |
| <span class="n">member_list</span> <span class="o">=</span> <span class="p">[</span><span class="n">m</span><span class="o">.</span><span class="n">_value_</span> <span class="k">for</span> <span class="n">m</span> <span class="ow">in</span> <span class="n">enum_class</span><span class="p">]</span> |
| <span class="k">if</span> <span class="n">member_list</span> <span class="o">!=</span> <span class="nb">sorted</span><span class="p">(</span><span class="n">member_list</span><span class="p">):</span> |
| <span class="n">enum_class</span><span class="o">.</span><span class="n">_iter_member_</span> <span class="o">=</span> <span class="n">enum_class</span><span class="o">.</span><span class="n">_iter_member_by_def_</span> |
| <span class="k">if</span> <span class="n">_order_</span><span class="p">:</span> |
| <span class="c1"># _order_ step 2: remove any items from _order_ that are not single-bit</span> |
| <span class="n">_order_</span> <span class="o">=</span> <span class="p">[</span> |
| <span class="n">o</span> |
| <span class="k">for</span> <span class="n">o</span> <span class="ow">in</span> <span class="n">_order_</span> |
| <span class="k">if</span> <span class="n">o</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">enum_class</span><span class="o">.</span><span class="n">_member_map_</span> <span class="ow">or</span> <span class="n">_is_single_bit</span><span class="p">(</span><span class="n">enum_class</span><span class="p">[</span><span class="n">o</span><span class="p">]</span><span class="o">.</span><span class="n">_value_</span><span class="p">)</span> |
| <span class="p">]</span> |
| <span class="c1">#</span> |
| <span class="k">if</span> <span class="n">_order_</span><span class="p">:</span> |
| <span class="c1"># _order_ step 3: remove aliases from _order_</span> |
| <span class="n">_order_</span> <span class="o">=</span> <span class="p">[</span> |
| <span class="n">o</span> |
| <span class="k">for</span> <span class="n">o</span> <span class="ow">in</span> <span class="n">_order_</span> |
| <span class="k">if</span> <span class="p">(</span> |
| <span class="n">o</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">enum_class</span><span class="o">.</span><span class="n">_member_map_</span> |
| <span class="ow">or</span> |
| <span class="p">(</span><span class="n">o</span> <span class="ow">in</span> <span class="n">enum_class</span><span class="o">.</span><span class="n">_member_map_</span> <span class="ow">and</span> <span class="n">o</span> <span class="ow">in</span> <span class="n">enum_class</span><span class="o">.</span><span class="n">_member_names_</span><span class="p">)</span> |
| <span class="p">)]</span> |
| <span class="c1"># _order_ step 4: verify that _order_ and _member_names_ match</span> |
| <span class="k">if</span> <span class="n">_order_</span> <span class="o">!=</span> <span class="n">enum_class</span><span class="o">.</span><span class="n">_member_names_</span><span class="p">:</span> |
| <span class="k">raise</span> <span class="ne">TypeError</span><span class="p">(</span> |
| <span class="s1">'member order does not match _order_:</span><span class="se">\n</span><span class="s1"> </span><span class="si">%r</span><span class="se">\n</span><span class="s1"> </span><span class="si">%r</span><span class="s1">'</span> |
| <span class="o">%</span> <span class="p">(</span><span class="n">enum_class</span><span class="o">.</span><span class="n">_member_names_</span><span class="p">,</span> <span class="n">_order_</span><span class="p">)</span> |
| <span class="p">)</span> |
| <span class="c1">#</span> |
| <span class="k">return</span> <span class="n">enum_class</span> |
| |
| <span class="k">def</span><span class="w"> </span><span class="fm">__bool__</span><span class="p">(</span><span class="bp">cls</span><span class="p">):</span> |
| <span class="w"> </span><span class="sd">"""</span> |
| <span class="sd"> classes/types should always be True.</span> |
| <span class="sd"> """</span> |
| <span class="k">return</span> <span class="kc">True</span> |
| |
| <span class="k">def</span><span class="w"> </span><span class="fm">__call__</span><span class="p">(</span><span class="bp">cls</span><span class="p">,</span> <span class="n">value</span><span class="p">,</span> <span class="n">names</span><span class="o">=</span><span class="n">_not_given</span><span class="p">,</span> <span class="o">*</span><span class="n">values</span><span class="p">,</span> <span class="n">module</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">qualname</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="nb">type</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">start</span><span class="o">=</span><span class="mi">1</span><span class="p">,</span> <span class="n">boundary</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span> |
| <span class="w"> </span><span class="sd">"""</span> |
| <span class="sd"> Either returns an existing member, or creates a new enum class.</span> |
| |
| <span class="sd"> This method is used both when an enum class is given a value to match</span> |
| <span class="sd"> to an enumeration member (i.e. Color(3)) and for the functional API</span> |
| <span class="sd"> (i.e. Color = Enum('Color', names='RED GREEN BLUE')).</span> |
| |
| <span class="sd"> The value lookup branch is chosen if the enum is final.</span> |
| |
| <span class="sd"> When used for the functional API:</span> |
| |
| <span class="sd"> `value` will be the name of the new class.</span> |
| |
| <span class="sd"> `names` should be either a string of white-space/comma delimited names</span> |
| <span class="sd"> (values will start at `start`), or an iterator/mapping of name, value pairs.</span> |
| |
| <span class="sd"> `module` should be set to the module this class is being created in;</span> |
| <span class="sd"> if it is not set, an attempt to find that module will be made, but if</span> |
| <span class="sd"> it fails the class will not be picklable.</span> |
| |
| <span class="sd"> `qualname` should be set to the actual location this class can be found</span> |
| <span class="sd"> at in its module; by default it is set to the global scope. If this is</span> |
| <span class="sd"> not correct, unpickling will fail in some circumstances.</span> |
| |
| <span class="sd"> `type`, if set, will be mixed in as the first base class.</span> |
| <span class="sd"> """</span> |
| <span class="k">if</span> <span class="bp">cls</span><span class="o">.</span><span class="n">_member_map_</span><span class="p">:</span> |
| <span class="c1"># simple value lookup if members exist</span> |
| <span class="k">if</span> <span class="n">names</span> <span class="ow">is</span> <span class="ow">not</span> <span class="n">_not_given</span><span class="p">:</span> |
| <span class="n">value</span> <span class="o">=</span> <span class="p">(</span><span class="n">value</span><span class="p">,</span> <span class="n">names</span><span class="p">)</span> <span class="o">+</span> <span class="n">values</span> |
| <span class="k">return</span> <span class="bp">cls</span><span class="o">.</span><span class="fm">__new__</span><span class="p">(</span><span class="bp">cls</span><span class="p">,</span> <span class="n">value</span><span class="p">)</span> |
| <span class="c1"># otherwise, functional API: we're creating a new Enum type</span> |
| <span class="k">if</span> <span class="n">names</span> <span class="ow">is</span> <span class="n">_not_given</span> <span class="ow">and</span> <span class="nb">type</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span> |
| <span class="c1"># no body? no data-type? possibly wrong usage</span> |
| <span class="k">raise</span> <span class="ne">TypeError</span><span class="p">(</span> |
| <span class="sa">f</span><span class="s2">"</span><span class="si">{</span><span class="bp">cls</span><span class="si">}</span><span class="s2"> has no members; specify `names=()` if you meant to create a new, empty, enum"</span> |
| <span class="p">)</span> |
| <span class="k">return</span> <span class="bp">cls</span><span class="o">.</span><span class="n">_create_</span><span class="p">(</span> |
| <span class="n">class_name</span><span class="o">=</span><span class="n">value</span><span class="p">,</span> |
| <span class="n">names</span><span class="o">=</span><span class="kc">None</span> <span class="k">if</span> <span class="n">names</span> <span class="ow">is</span> <span class="n">_not_given</span> <span class="k">else</span> <span class="n">names</span><span class="p">,</span> |
| <span class="n">module</span><span class="o">=</span><span class="n">module</span><span class="p">,</span> |
| <span class="n">qualname</span><span class="o">=</span><span class="n">qualname</span><span class="p">,</span> |
| <span class="nb">type</span><span class="o">=</span><span class="nb">type</span><span class="p">,</span> |
| <span class="n">start</span><span class="o">=</span><span class="n">start</span><span class="p">,</span> |
| <span class="n">boundary</span><span class="o">=</span><span class="n">boundary</span><span class="p">,</span> |
| <span class="p">)</span> |
| |
| <span class="k">def</span><span class="w"> </span><span class="fm">__contains__</span><span class="p">(</span><span class="bp">cls</span><span class="p">,</span> <span class="n">value</span><span class="p">):</span> |
| <span class="w"> </span><span class="sd">"""Return True if `value` is in `cls`.</span> |
| |
| <span class="sd"> `value` is in `cls` if:</span> |
| <span class="sd"> 1) `value` is a member of `cls`, or</span> |
| <span class="sd"> 2) `value` is the value of one of the `cls`'s members.</span> |
| <span class="sd"> 3) `value` is a pseudo-member (flags)</span> |
| <span class="sd"> """</span> |
| <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">value</span><span class="p">,</span> <span class="bp">cls</span><span class="p">):</span> |
| <span class="k">return</span> <span class="kc">True</span> |
| <span class="k">if</span> <span class="nb">issubclass</span><span class="p">(</span><span class="bp">cls</span><span class="p">,</span> <span class="n">Flag</span><span class="p">):</span> |
| <span class="k">try</span><span class="p">:</span> |
| <span class="n">result</span> <span class="o">=</span> <span class="bp">cls</span><span class="o">.</span><span class="n">_missing_</span><span class="p">(</span><span class="n">value</span><span class="p">)</span> |
| <span class="k">return</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">result</span><span class="p">,</span> <span class="bp">cls</span><span class="p">)</span> |
| <span class="k">except</span> <span class="ne">ValueError</span><span class="p">:</span> |
| <span class="k">pass</span> |
| <span class="k">return</span> <span class="p">(</span> |
| <span class="n">value</span> <span class="ow">in</span> <span class="bp">cls</span><span class="o">.</span><span class="n">_unhashable_values_</span> <span class="c1"># both structures are lists</span> |
| <span class="ow">or</span> <span class="n">value</span> <span class="ow">in</span> <span class="bp">cls</span><span class="o">.</span><span class="n">_hashable_values_</span> |
| <span class="p">)</span> |
| |
| <span class="k">def</span><span class="w"> </span><span class="fm">__delattr__</span><span class="p">(</span><span class="bp">cls</span><span class="p">,</span> <span class="n">attr</span><span class="p">):</span> |
| <span class="c1"># nicer error message when someone tries to delete an attribute</span> |
| <span class="c1"># (see issue19025).</span> |
| <span class="k">if</span> <span class="n">attr</span> <span class="ow">in</span> <span class="bp">cls</span><span class="o">.</span><span class="n">_member_map_</span><span class="p">:</span> |
| <span class="k">raise</span> <span class="ne">AttributeError</span><span class="p">(</span><span class="s2">"</span><span class="si">%r</span><span class="s2"> cannot delete member </span><span class="si">%r</span><span class="s2">."</span> <span class="o">%</span> <span class="p">(</span><span class="bp">cls</span><span class="o">.</span><span class="vm">__name__</span><span class="p">,</span> <span class="n">attr</span><span class="p">))</span> |
| <span class="nb">super</span><span class="p">()</span><span class="o">.</span><span class="fm">__delattr__</span><span class="p">(</span><span class="n">attr</span><span class="p">)</span> |
| |
| <span class="k">def</span><span class="w"> </span><span class="fm">__dir__</span><span class="p">(</span><span class="bp">cls</span><span class="p">):</span> |
| <span class="n">interesting</span> <span class="o">=</span> <span class="nb">set</span><span class="p">([</span> |
| <span class="s1">'__class__'</span><span class="p">,</span> <span class="s1">'__contains__'</span><span class="p">,</span> <span class="s1">'__doc__'</span><span class="p">,</span> <span class="s1">'__getitem__'</span><span class="p">,</span> |
| <span class="s1">'__iter__'</span><span class="p">,</span> <span class="s1">'__len__'</span><span class="p">,</span> <span class="s1">'__members__'</span><span class="p">,</span> <span class="s1">'__module__'</span><span class="p">,</span> |
| <span class="s1">'__name__'</span><span class="p">,</span> <span class="s1">'__qualname__'</span><span class="p">,</span> |
| <span class="p">]</span> |
| <span class="o">+</span> <span class="bp">cls</span><span class="o">.</span><span class="n">_member_names_</span> |
| <span class="p">)</span> |
| <span class="k">if</span> <span class="bp">cls</span><span class="o">.</span><span class="n">_new_member_</span> <span class="ow">is</span> <span class="ow">not</span> <span class="nb">object</span><span class="o">.</span><span class="fm">__new__</span><span class="p">:</span> |
| <span class="n">interesting</span><span class="o">.</span><span class="n">add</span><span class="p">(</span><span class="s1">'__new__'</span><span class="p">)</span> |
| <span class="k">if</span> <span class="bp">cls</span><span class="o">.</span><span class="n">__init_subclass__</span> <span class="ow">is</span> <span class="ow">not</span> <span class="nb">object</span><span class="o">.</span><span class="n">__init_subclass__</span><span class="p">:</span> |
| <span class="n">interesting</span><span class="o">.</span><span class="n">add</span><span class="p">(</span><span class="s1">'__init_subclass__'</span><span class="p">)</span> |
| <span class="k">if</span> <span class="bp">cls</span><span class="o">.</span><span class="n">_member_type_</span> <span class="ow">is</span> <span class="nb">object</span><span class="p">:</span> |
| <span class="k">return</span> <span class="nb">sorted</span><span class="p">(</span><span class="n">interesting</span><span class="p">)</span> |
| <span class="k">else</span><span class="p">:</span> |
| <span class="c1"># return whatever mixed-in data type has</span> |
| <span class="k">return</span> <span class="nb">sorted</span><span class="p">(</span><span class="nb">set</span><span class="p">(</span><span class="nb">dir</span><span class="p">(</span><span class="bp">cls</span><span class="o">.</span><span class="n">_member_type_</span><span class="p">))</span> <span class="o">|</span> <span class="n">interesting</span><span class="p">)</span> |
| |
| <span class="k">def</span><span class="w"> </span><span class="fm">__getitem__</span><span class="p">(</span><span class="bp">cls</span><span class="p">,</span> <span class="n">name</span><span class="p">):</span> |
| <span class="w"> </span><span class="sd">"""</span> |
| <span class="sd"> Return the member matching `name`.</span> |
| <span class="sd"> """</span> |
| <span class="k">return</span> <span class="bp">cls</span><span class="o">.</span><span class="n">_member_map_</span><span class="p">[</span><span class="n">name</span><span class="p">]</span> |
| |
| <span class="k">def</span><span class="w"> </span><span class="fm">__iter__</span><span class="p">(</span><span class="bp">cls</span><span class="p">):</span> |
| <span class="w"> </span><span class="sd">"""</span> |
| <span class="sd"> Return members in definition order.</span> |
| <span class="sd"> """</span> |
| <span class="k">return</span> <span class="p">(</span><span class="bp">cls</span><span class="o">.</span><span class="n">_member_map_</span><span class="p">[</span><span class="n">name</span><span class="p">]</span> <span class="k">for</span> <span class="n">name</span> <span class="ow">in</span> <span class="bp">cls</span><span class="o">.</span><span class="n">_member_names_</span><span class="p">)</span> |
| |
| <span class="k">def</span><span class="w"> </span><span class="fm">__len__</span><span class="p">(</span><span class="bp">cls</span><span class="p">):</span> |
| <span class="w"> </span><span class="sd">"""</span> |
| <span class="sd"> Return the number of members (no aliases)</span> |
| <span class="sd"> """</span> |
| <span class="k">return</span> <span class="nb">len</span><span class="p">(</span><span class="bp">cls</span><span class="o">.</span><span class="n">_member_names_</span><span class="p">)</span> |
| |
| <span class="nd">@bltns</span><span class="o">.</span><span class="n">property</span> |
| <span class="k">def</span><span class="w"> </span><span class="nf">__members__</span><span class="p">(</span><span class="bp">cls</span><span class="p">):</span> |
| <span class="w"> </span><span class="sd">"""</span> |
| <span class="sd"> Returns a mapping of member name->value.</span> |
| |
| <span class="sd"> This mapping lists all enum members, including aliases. Note that this</span> |
| <span class="sd"> is a read-only view of the internal mapping.</span> |
| <span class="sd"> """</span> |
| <span class="k">return</span> <span class="n">MappingProxyType</span><span class="p">(</span><span class="bp">cls</span><span class="o">.</span><span class="n">_member_map_</span><span class="p">)</span> |
| |
| <span class="k">def</span><span class="w"> </span><span class="fm">__repr__</span><span class="p">(</span><span class="bp">cls</span><span class="p">):</span> |
| <span class="k">if</span> <span class="n">Flag</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span> <span class="ow">and</span> <span class="nb">issubclass</span><span class="p">(</span><span class="bp">cls</span><span class="p">,</span> <span class="n">Flag</span><span class="p">):</span> |
| <span class="k">return</span> <span class="s2">"<flag </span><span class="si">%r</span><span class="s2">>"</span> <span class="o">%</span> <span class="bp">cls</span><span class="o">.</span><span class="vm">__name__</span> |
| <span class="k">else</span><span class="p">:</span> |
| <span class="k">return</span> <span class="s2">"<enum </span><span class="si">%r</span><span class="s2">>"</span> <span class="o">%</span> <span class="bp">cls</span><span class="o">.</span><span class="vm">__name__</span> |
| |
| <span class="k">def</span><span class="w"> </span><span class="fm">__reversed__</span><span class="p">(</span><span class="bp">cls</span><span class="p">):</span> |
| <span class="w"> </span><span class="sd">"""</span> |
| <span class="sd"> Return members in reverse definition order.</span> |
| <span class="sd"> """</span> |
| <span class="k">return</span> <span class="p">(</span><span class="bp">cls</span><span class="o">.</span><span class="n">_member_map_</span><span class="p">[</span><span class="n">name</span><span class="p">]</span> <span class="k">for</span> <span class="n">name</span> <span class="ow">in</span> <span class="nb">reversed</span><span class="p">(</span><span class="bp">cls</span><span class="o">.</span><span class="n">_member_names_</span><span class="p">))</span> |
| |
| <span class="k">def</span><span class="w"> </span><span class="fm">__setattr__</span><span class="p">(</span><span class="bp">cls</span><span class="p">,</span> <span class="n">name</span><span class="p">,</span> <span class="n">value</span><span class="p">):</span> |
| <span class="w"> </span><span class="sd">"""</span> |
| <span class="sd"> Block attempts to reassign Enum members.</span> |
| |
| <span class="sd"> A simple assignment to the class namespace only changes one of the</span> |
| <span class="sd"> several possible ways to get an Enum member from the Enum class,</span> |
| <span class="sd"> resulting in an inconsistent Enumeration.</span> |
| <span class="sd"> """</span> |
| <span class="n">member_map</span> <span class="o">=</span> <span class="bp">cls</span><span class="o">.</span><span class="vm">__dict__</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s1">'_member_map_'</span><span class="p">,</span> <span class="p">{})</span> |
| <span class="k">if</span> <span class="n">name</span> <span class="ow">in</span> <span class="n">member_map</span><span class="p">:</span> |
| <span class="k">raise</span> <span class="ne">AttributeError</span><span class="p">(</span><span class="s1">'cannot reassign member </span><span class="si">%r</span><span class="s1">'</span> <span class="o">%</span> <span class="p">(</span><span class="n">name</span><span class="p">,</span> <span class="p">))</span> |
| <span class="nb">super</span><span class="p">()</span><span class="o">.</span><span class="fm">__setattr__</span><span class="p">(</span><span class="n">name</span><span class="p">,</span> <span class="n">value</span><span class="p">)</span> |
| |
| <span class="k">def</span><span class="w"> </span><span class="nf">_create_</span><span class="p">(</span><span class="bp">cls</span><span class="p">,</span> <span class="n">class_name</span><span class="p">,</span> <span class="n">names</span><span class="p">,</span> <span class="o">*</span><span class="p">,</span> <span class="n">module</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">qualname</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="nb">type</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">start</span><span class="o">=</span><span class="mi">1</span><span class="p">,</span> <span class="n">boundary</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span> |
| <span class="w"> </span><span class="sd">"""</span> |
| <span class="sd"> Convenience method to create a new Enum class.</span> |
| |
| <span class="sd"> `names` can be:</span> |
| |
| <span class="sd"> * A string containing member names, separated either with spaces or</span> |
| <span class="sd"> commas. Values are incremented by 1 from `start`.</span> |
| <span class="sd"> * An iterable of member names. Values are incremented by 1 from `start`.</span> |
| <span class="sd"> * An iterable of (member name, value) pairs.</span> |
| <span class="sd"> * A mapping of member name -> value pairs.</span> |
| <span class="sd"> """</span> |
| <span class="n">metacls</span> <span class="o">=</span> <span class="bp">cls</span><span class="o">.</span><span class="vm">__class__</span> |
| <span class="n">bases</span> <span class="o">=</span> <span class="p">(</span><span class="bp">cls</span><span class="p">,</span> <span class="p">)</span> <span class="k">if</span> <span class="nb">type</span> <span class="ow">is</span> <span class="kc">None</span> <span class="k">else</span> <span class="p">(</span><span class="nb">type</span><span class="p">,</span> <span class="bp">cls</span><span class="p">)</span> |
| <span class="n">_</span><span class="p">,</span> <span class="n">first_enum</span> <span class="o">=</span> <span class="bp">cls</span><span class="o">.</span><span class="n">_get_mixins_</span><span class="p">(</span><span class="n">class_name</span><span class="p">,</span> <span class="n">bases</span><span class="p">)</span> |
| <span class="n">classdict</span> <span class="o">=</span> <span class="n">metacls</span><span class="o">.</span><span class="fm">__prepare__</span><span class="p">(</span><span class="n">class_name</span><span class="p">,</span> <span class="n">bases</span><span class="p">)</span> |
| |
| <span class="c1"># special processing needed for names?</span> |
| <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">names</span><span class="p">,</span> <span class="nb">str</span><span class="p">):</span> |
| <span class="n">names</span> <span class="o">=</span> <span class="n">names</span><span class="o">.</span><span class="n">replace</span><span class="p">(</span><span class="s1">','</span><span class="p">,</span> <span class="s1">' '</span><span class="p">)</span><span class="o">.</span><span class="n">split</span><span class="p">()</span> |
| <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">names</span><span class="p">,</span> <span class="p">(</span><span class="nb">tuple</span><span class="p">,</span> <span class="nb">list</span><span class="p">))</span> <span class="ow">and</span> <span class="n">names</span> <span class="ow">and</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">names</span><span class="p">[</span><span class="mi">0</span><span class="p">],</span> <span class="nb">str</span><span class="p">):</span> |
| <span class="n">original_names</span><span class="p">,</span> <span class="n">names</span> <span class="o">=</span> <span class="n">names</span><span class="p">,</span> <span class="p">[]</span> |
| <span class="n">last_values</span> <span class="o">=</span> <span class="p">[]</span> |
| <span class="k">for</span> <span class="n">count</span><span class="p">,</span> <span class="n">name</span> <span class="ow">in</span> <span class="nb">enumerate</span><span class="p">(</span><span class="n">original_names</span><span class="p">):</span> |
| <span class="n">value</span> <span class="o">=</span> <span class="n">first_enum</span><span class="o">.</span><span class="n">_generate_next_value_</span><span class="p">(</span><span class="n">name</span><span class="p">,</span> <span class="n">start</span><span class="p">,</span> <span class="n">count</span><span class="p">,</span> <span class="n">last_values</span><span class="p">[:])</span> |
| <span class="n">last_values</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">value</span><span class="p">)</span> |
| <span class="n">names</span><span class="o">.</span><span class="n">append</span><span class="p">((</span><span class="n">name</span><span class="p">,</span> <span class="n">value</span><span class="p">))</span> |
| <span class="k">if</span> <span class="n">names</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span> |
| <span class="n">names</span> <span class="o">=</span> <span class="p">()</span> |
| |
| <span class="c1"># Here, names is either an iterable of (name, value) or a mapping.</span> |
| <span class="k">for</span> <span class="n">item</span> <span class="ow">in</span> <span class="n">names</span><span class="p">:</span> |
| <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">item</span><span class="p">,</span> <span class="nb">str</span><span class="p">):</span> |
| <span class="n">member_name</span><span class="p">,</span> <span class="n">member_value</span> <span class="o">=</span> <span class="n">item</span><span class="p">,</span> <span class="n">names</span><span class="p">[</span><span class="n">item</span><span class="p">]</span> |
| <span class="k">else</span><span class="p">:</span> |
| <span class="n">member_name</span><span class="p">,</span> <span class="n">member_value</span> <span class="o">=</span> <span class="n">item</span> |
| <span class="n">classdict</span><span class="p">[</span><span class="n">member_name</span><span class="p">]</span> <span class="o">=</span> <span class="n">member_value</span> |
| |
| <span class="k">if</span> <span class="n">module</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span> |
| <span class="k">try</span><span class="p">:</span> |
| <span class="n">module</span> <span class="o">=</span> <span class="n">sys</span><span class="o">.</span><span class="n">_getframemodulename</span><span class="p">(</span><span class="mi">2</span><span class="p">)</span> |
| <span class="k">except</span> <span class="ne">AttributeError</span><span class="p">:</span> |
| <span class="c1"># Fall back on _getframe if _getframemodulename is missing</span> |
| <span class="k">try</span><span class="p">:</span> |
| <span class="n">module</span> <span class="o">=</span> <span class="n">sys</span><span class="o">.</span><span class="n">_getframe</span><span class="p">(</span><span class="mi">2</span><span class="p">)</span><span class="o">.</span><span class="n">f_globals</span><span class="p">[</span><span class="s1">'__name__'</span><span class="p">]</span> |
| <span class="k">except</span> <span class="p">(</span><span class="ne">AttributeError</span><span class="p">,</span> <span class="ne">ValueError</span><span class="p">,</span> <span class="ne">KeyError</span><span class="p">):</span> |
| <span class="k">pass</span> |
| <span class="k">if</span> <span class="n">module</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span> |
| <span class="n">_make_class_unpicklable</span><span class="p">(</span><span class="n">classdict</span><span class="p">)</span> |
| <span class="k">else</span><span class="p">:</span> |
| <span class="n">classdict</span><span class="p">[</span><span class="s1">'__module__'</span><span class="p">]</span> <span class="o">=</span> <span class="n">module</span> |
| <span class="k">if</span> <span class="n">qualname</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span> |
| <span class="n">classdict</span><span class="p">[</span><span class="s1">'__qualname__'</span><span class="p">]</span> <span class="o">=</span> <span class="n">qualname</span> |
| |
| <span class="k">return</span> <span class="n">metacls</span><span class="o">.</span><span class="fm">__new__</span><span class="p">(</span><span class="n">metacls</span><span class="p">,</span> <span class="n">class_name</span><span class="p">,</span> <span class="n">bases</span><span class="p">,</span> <span class="n">classdict</span><span class="p">,</span> <span class="n">boundary</span><span class="o">=</span><span class="n">boundary</span><span class="p">)</span> |
| |
| <span class="k">def</span><span class="w"> </span><span class="nf">_convert_</span><span class="p">(</span><span class="bp">cls</span><span class="p">,</span> <span class="n">name</span><span class="p">,</span> <span class="n">module</span><span class="p">,</span> <span class="nb">filter</span><span class="p">,</span> <span class="n">source</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="o">*</span><span class="p">,</span> <span class="n">boundary</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">as_global</span><span class="o">=</span><span class="kc">False</span><span class="p">):</span> |
| <span class="w"> </span><span class="sd">"""</span> |
| <span class="sd"> Create a new Enum subclass that replaces a collection of global constants</span> |
| <span class="sd"> """</span> |
| <span class="c1"># convert all constants from source (or module) that pass filter() to</span> |
| <span class="c1"># a new Enum called name, and export the enum and its members back to</span> |
| <span class="c1"># module;</span> |
| <span class="c1"># also, replace the __reduce_ex__ method so unpickling works in</span> |
| <span class="c1"># previous Python versions</span> |
| <span class="n">module_globals</span> <span class="o">=</span> <span class="n">sys</span><span class="o">.</span><span class="n">modules</span><span class="p">[</span><span class="n">module</span><span class="p">]</span><span class="o">.</span><span class="vm">__dict__</span> |
| <span class="k">if</span> <span class="n">source</span><span class="p">:</span> |
| <span class="n">source</span> <span class="o">=</span> <span class="n">source</span><span class="o">.</span><span class="vm">__dict__</span> |
| <span class="k">else</span><span class="p">:</span> |
| <span class="n">source</span> <span class="o">=</span> <span class="n">module_globals</span> |
| <span class="c1"># _value2member_map_ is populated in the same order every time</span> |
| <span class="c1"># for a consistent reverse mapping of number to name when there</span> |
| <span class="c1"># are multiple names for the same number.</span> |
| <span class="n">members</span> <span class="o">=</span> <span class="p">[</span> |
| <span class="p">(</span><span class="n">name</span><span class="p">,</span> <span class="n">value</span><span class="p">)</span> |
| <span class="k">for</span> <span class="n">name</span><span class="p">,</span> <span class="n">value</span> <span class="ow">in</span> <span class="n">source</span><span class="o">.</span><span class="n">items</span><span class="p">()</span> |
| <span class="k">if</span> <span class="nb">filter</span><span class="p">(</span><span class="n">name</span><span class="p">)]</span> |
| <span class="k">try</span><span class="p">:</span> |
| <span class="c1"># sort by value</span> |
| <span class="n">members</span><span class="o">.</span><span class="n">sort</span><span class="p">(</span><span class="n">key</span><span class="o">=</span><span class="k">lambda</span> <span class="n">t</span><span class="p">:</span> <span class="p">(</span><span class="n">t</span><span class="p">[</span><span class="mi">1</span><span class="p">],</span> <span class="n">t</span><span class="p">[</span><span class="mi">0</span><span class="p">]))</span> |
| <span class="k">except</span> <span class="ne">TypeError</span><span class="p">:</span> |
| <span class="c1"># unless some values aren't comparable, in which case sort by name</span> |
| <span class="n">members</span><span class="o">.</span><span class="n">sort</span><span class="p">(</span><span class="n">key</span><span class="o">=</span><span class="k">lambda</span> <span class="n">t</span><span class="p">:</span> <span class="n">t</span><span class="p">[</span><span class="mi">0</span><span class="p">])</span> |
| <span class="n">body</span> <span class="o">=</span> <span class="p">{</span><span class="n">t</span><span class="p">[</span><span class="mi">0</span><span class="p">]:</span> <span class="n">t</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span> <span class="k">for</span> <span class="n">t</span> <span class="ow">in</span> <span class="n">members</span><span class="p">}</span> |
| <span class="n">body</span><span class="p">[</span><span class="s1">'__module__'</span><span class="p">]</span> <span class="o">=</span> <span class="n">module</span> |
| <span class="n">tmp_cls</span> <span class="o">=</span> <span class="nb">type</span><span class="p">(</span><span class="n">name</span><span class="p">,</span> <span class="p">(</span><span class="nb">object</span><span class="p">,</span> <span class="p">),</span> <span class="n">body</span><span class="p">)</span> |
| <span class="bp">cls</span> <span class="o">=</span> <span class="n">_simple_enum</span><span class="p">(</span><span class="n">etype</span><span class="o">=</span><span class="bp">cls</span><span class="p">,</span> <span class="n">boundary</span><span class="o">=</span><span class="n">boundary</span> <span class="ow">or</span> <span class="n">KEEP</span><span class="p">)(</span><span class="n">tmp_cls</span><span class="p">)</span> |
| <span class="k">if</span> <span class="n">as_global</span><span class="p">:</span> |
| <span class="n">global_enum</span><span class="p">(</span><span class="bp">cls</span><span class="p">)</span> |
| <span class="k">else</span><span class="p">:</span> |
| <span class="n">sys</span><span class="o">.</span><span class="n">modules</span><span class="p">[</span><span class="bp">cls</span><span class="o">.</span><span class="vm">__module__</span><span class="p">]</span><span class="o">.</span><span class="vm">__dict__</span><span class="o">.</span><span class="n">update</span><span class="p">(</span><span class="bp">cls</span><span class="o">.</span><span class="n">__members__</span><span class="p">)</span> |
| <span class="n">module_globals</span><span class="p">[</span><span class="n">name</span><span class="p">]</span> <span class="o">=</span> <span class="bp">cls</span> |
| <span class="k">return</span> <span class="bp">cls</span> |
| |
| <span class="nd">@classmethod</span> |
| <span class="k">def</span><span class="w"> </span><span class="nf">_check_for_existing_members_</span><span class="p">(</span><span class="n">mcls</span><span class="p">,</span> <span class="n">class_name</span><span class="p">,</span> <span class="n">bases</span><span class="p">):</span> |
| <span class="k">for</span> <span class="n">chain</span> <span class="ow">in</span> <span class="n">bases</span><span class="p">:</span> |
| <span class="k">for</span> <span class="n">base</span> <span class="ow">in</span> <span class="n">chain</span><span class="o">.</span><span class="vm">__mro__</span><span class="p">:</span> |
| <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">base</span><span class="p">,</span> <span class="n">EnumType</span><span class="p">)</span> <span class="ow">and</span> <span class="n">base</span><span class="o">.</span><span class="n">_member_names_</span><span class="p">:</span> |
| <span class="k">raise</span> <span class="ne">TypeError</span><span class="p">(</span> |
| <span class="s2">"<enum </span><span class="si">%r</span><span class="s2">> cannot extend </span><span class="si">%r</span><span class="s2">"</span> |
| <span class="o">%</span> <span class="p">(</span><span class="n">class_name</span><span class="p">,</span> <span class="n">base</span><span class="p">)</span> |
| <span class="p">)</span> |
| |
| <span class="nd">@classmethod</span> |
| <span class="k">def</span><span class="w"> </span><span class="nf">_get_mixins_</span><span class="p">(</span><span class="n">mcls</span><span class="p">,</span> <span class="n">class_name</span><span class="p">,</span> <span class="n">bases</span><span class="p">):</span> |
| <span class="w"> </span><span class="sd">"""</span> |
| <span class="sd"> Returns the type for creating enum members, and the first inherited</span> |
| <span class="sd"> enum class.</span> |
| |
| <span class="sd"> bases: the tuple of bases that was given to __new__</span> |
| <span class="sd"> """</span> |
| <span class="k">if</span> <span class="ow">not</span> <span class="n">bases</span><span class="p">:</span> |
| <span class="k">return</span> <span class="nb">object</span><span class="p">,</span> <span class="n">Enum</span> |
| <span class="c1"># ensure final parent class is an Enum derivative, find any concrete</span> |
| <span class="c1"># data type, and check that Enum has no members</span> |
| <span class="n">first_enum</span> <span class="o">=</span> <span class="n">bases</span><span class="p">[</span><span class="o">-</span><span class="mi">1</span><span class="p">]</span> |
| <span class="k">if</span> <span class="ow">not</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">first_enum</span><span class="p">,</span> <span class="n">EnumType</span><span class="p">):</span> |
| <span class="k">raise</span> <span class="ne">TypeError</span><span class="p">(</span><span class="s2">"new enumerations should be created as "</span> |
| <span class="s2">"`EnumName([mixin_type, ...] [data_type,] enum_type)`"</span><span class="p">)</span> |
| <span class="n">member_type</span> <span class="o">=</span> <span class="n">mcls</span><span class="o">.</span><span class="n">_find_data_type_</span><span class="p">(</span><span class="n">class_name</span><span class="p">,</span> <span class="n">bases</span><span class="p">)</span> <span class="ow">or</span> <span class="nb">object</span> |
| <span class="k">return</span> <span class="n">member_type</span><span class="p">,</span> <span class="n">first_enum</span> |
| |
| <span class="nd">@classmethod</span> |
| <span class="k">def</span><span class="w"> </span><span class="nf">_find_data_repr_</span><span class="p">(</span><span class="n">mcls</span><span class="p">,</span> <span class="n">class_name</span><span class="p">,</span> <span class="n">bases</span><span class="p">):</span> |
| <span class="k">for</span> <span class="n">chain</span> <span class="ow">in</span> <span class="n">bases</span><span class="p">:</span> |
| <span class="k">for</span> <span class="n">base</span> <span class="ow">in</span> <span class="n">chain</span><span class="o">.</span><span class="vm">__mro__</span><span class="p">:</span> |
| <span class="k">if</span> <span class="n">base</span> <span class="ow">is</span> <span class="nb">object</span><span class="p">:</span> |
| <span class="k">continue</span> |
| <span class="k">elif</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">base</span><span class="p">,</span> <span class="n">EnumType</span><span class="p">):</span> |
| <span class="c1"># if we hit an Enum, use it's _value_repr_</span> |
| <span class="k">return</span> <span class="n">base</span><span class="o">.</span><span class="n">_value_repr_</span> |
| <span class="k">elif</span> <span class="s1">'__repr__'</span> <span class="ow">in</span> <span class="n">base</span><span class="o">.</span><span class="vm">__dict__</span><span class="p">:</span> |
| <span class="c1"># this is our data repr</span> |
| <span class="c1"># double-check if a dataclass with a default __repr__</span> |
| <span class="k">if</span> <span class="p">(</span> |
| <span class="s1">'__dataclass_fields__'</span> <span class="ow">in</span> <span class="n">base</span><span class="o">.</span><span class="vm">__dict__</span> |
| <span class="ow">and</span> <span class="s1">'__dataclass_params__'</span> <span class="ow">in</span> <span class="n">base</span><span class="o">.</span><span class="vm">__dict__</span> |
| <span class="ow">and</span> <span class="n">base</span><span class="o">.</span><span class="vm">__dict__</span><span class="p">[</span><span class="s1">'__dataclass_params__'</span><span class="p">]</span><span class="o">.</span><span class="n">repr</span> |
| <span class="p">):</span> |
| <span class="k">return</span> <span class="n">_dataclass_repr</span> |
| <span class="k">else</span><span class="p">:</span> |
| <span class="k">return</span> <span class="n">base</span><span class="o">.</span><span class="vm">__dict__</span><span class="p">[</span><span class="s1">'__repr__'</span><span class="p">]</span> |
| <span class="k">return</span> <span class="kc">None</span> |
| |
| <span class="nd">@classmethod</span> |
| <span class="k">def</span><span class="w"> </span><span class="nf">_find_data_type_</span><span class="p">(</span><span class="n">mcls</span><span class="p">,</span> <span class="n">class_name</span><span class="p">,</span> <span class="n">bases</span><span class="p">):</span> |
| <span class="c1"># a datatype has a __new__ method, or a __dataclass_fields__ attribute</span> |
| <span class="n">data_types</span> <span class="o">=</span> <span class="nb">set</span><span class="p">()</span> |
| <span class="n">base_chain</span> <span class="o">=</span> <span class="nb">set</span><span class="p">()</span> |
| <span class="k">for</span> <span class="n">chain</span> <span class="ow">in</span> <span class="n">bases</span><span class="p">:</span> |
| <span class="n">candidate</span> <span class="o">=</span> <span class="kc">None</span> |
| <span class="k">for</span> <span class="n">base</span> <span class="ow">in</span> <span class="n">chain</span><span class="o">.</span><span class="vm">__mro__</span><span class="p">:</span> |
| <span class="n">base_chain</span><span class="o">.</span><span class="n">add</span><span class="p">(</span><span class="n">base</span><span class="p">)</span> |
| <span class="k">if</span> <span class="n">base</span> <span class="ow">is</span> <span class="nb">object</span><span class="p">:</span> |
| <span class="k">continue</span> |
| <span class="k">elif</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">base</span><span class="p">,</span> <span class="n">EnumType</span><span class="p">):</span> |
| <span class="k">if</span> <span class="n">base</span><span class="o">.</span><span class="n">_member_type_</span> <span class="ow">is</span> <span class="ow">not</span> <span class="nb">object</span><span class="p">:</span> |
| <span class="n">data_types</span><span class="o">.</span><span class="n">add</span><span class="p">(</span><span class="n">base</span><span class="o">.</span><span class="n">_member_type_</span><span class="p">)</span> |
| <span class="k">break</span> |
| <span class="k">elif</span> <span class="s1">'__new__'</span> <span class="ow">in</span> <span class="n">base</span><span class="o">.</span><span class="vm">__dict__</span> <span class="ow">or</span> <span class="s1">'__dataclass_fields__'</span> <span class="ow">in</span> <span class="n">base</span><span class="o">.</span><span class="vm">__dict__</span><span class="p">:</span> |
| <span class="n">data_types</span><span class="o">.</span><span class="n">add</span><span class="p">(</span><span class="n">candidate</span> <span class="ow">or</span> <span class="n">base</span><span class="p">)</span> |
| <span class="k">break</span> |
| <span class="k">else</span><span class="p">:</span> |
| <span class="n">candidate</span> <span class="o">=</span> <span class="n">candidate</span> <span class="ow">or</span> <span class="n">base</span> |
| <span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">data_types</span><span class="p">)</span> <span class="o">></span> <span class="mi">1</span><span class="p">:</span> |
| <span class="k">raise</span> <span class="ne">TypeError</span><span class="p">(</span><span class="s1">'too many data types for </span><span class="si">%r</span><span class="s1">: </span><span class="si">%r</span><span class="s1">'</span> <span class="o">%</span> <span class="p">(</span><span class="n">class_name</span><span class="p">,</span> <span class="n">data_types</span><span class="p">))</span> |
| <span class="k">elif</span> <span class="n">data_types</span><span class="p">:</span> |
| <span class="k">return</span> <span class="n">data_types</span><span class="o">.</span><span class="n">pop</span><span class="p">()</span> |
| <span class="k">else</span><span class="p">:</span> |
| <span class="k">return</span> <span class="kc">None</span> |
| |
| <span class="nd">@classmethod</span> |
| <span class="k">def</span><span class="w"> </span><span class="nf">_find_new_</span><span class="p">(</span><span class="n">mcls</span><span class="p">,</span> <span class="n">classdict</span><span class="p">,</span> <span class="n">member_type</span><span class="p">,</span> <span class="n">first_enum</span><span class="p">):</span> |
| <span class="w"> </span><span class="sd">"""</span> |
| <span class="sd"> Returns the __new__ to be used for creating the enum members.</span> |
| |
| <span class="sd"> classdict: the class dictionary given to __new__</span> |
| <span class="sd"> member_type: the data type whose __new__ will be used by default</span> |
| <span class="sd"> first_enum: enumeration to check for an overriding __new__</span> |
| <span class="sd"> """</span> |
| <span class="c1"># now find the correct __new__, checking to see of one was defined</span> |
| <span class="c1"># by the user; also check earlier enum classes in case a __new__ was</span> |
| <span class="c1"># saved as __new_member__</span> |
| <span class="fm">__new__</span> <span class="o">=</span> <span class="n">classdict</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s1">'__new__'</span><span class="p">,</span> <span class="kc">None</span><span class="p">)</span> |
| |
| <span class="c1"># should __new__ be saved as __new_member__ later?</span> |
| <span class="n">save_new</span> <span class="o">=</span> <span class="n">first_enum</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span> <span class="ow">and</span> <span class="fm">__new__</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span> |
| |
| <span class="k">if</span> <span class="fm">__new__</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span> |
| <span class="c1"># check all possibles for __new_member__ before falling back to</span> |
| <span class="c1"># __new__</span> |
| <span class="k">for</span> <span class="n">method</span> <span class="ow">in</span> <span class="p">(</span><span class="s1">'__new_member__'</span><span class="p">,</span> <span class="s1">'__new__'</span><span class="p">):</span> |
| <span class="k">for</span> <span class="n">possible</span> <span class="ow">in</span> <span class="p">(</span><span class="n">member_type</span><span class="p">,</span> <span class="n">first_enum</span><span class="p">):</span> |
| <span class="n">target</span> <span class="o">=</span> <span class="nb">getattr</span><span class="p">(</span><span class="n">possible</span><span class="p">,</span> <span class="n">method</span><span class="p">,</span> <span class="kc">None</span><span class="p">)</span> |
| <span class="k">if</span> <span class="n">target</span> <span class="ow">not</span> <span class="ow">in</span> <span class="p">{</span> |
| <span class="kc">None</span><span class="p">,</span> |
| <span class="kc">None</span><span class="o">.</span><span class="fm">__new__</span><span class="p">,</span> |
| <span class="nb">object</span><span class="o">.</span><span class="fm">__new__</span><span class="p">,</span> |
| <span class="n">Enum</span><span class="o">.</span><span class="fm">__new__</span><span class="p">,</span> |
| <span class="p">}:</span> |
| <span class="fm">__new__</span> <span class="o">=</span> <span class="n">target</span> |
| <span class="k">break</span> |
| <span class="k">if</span> <span class="fm">__new__</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span> |
| <span class="k">break</span> |
| <span class="k">else</span><span class="p">:</span> |
| <span class="fm">__new__</span> <span class="o">=</span> <span class="nb">object</span><span class="o">.</span><span class="fm">__new__</span> |
| |
| <span class="c1"># if a non-object.__new__ is used then whatever value/tuple was</span> |
| <span class="c1"># assigned to the enum member name will be passed to __new__ and to the</span> |
| <span class="c1"># new enum member's __init__</span> |
| <span class="k">if</span> <span class="n">first_enum</span> <span class="ow">is</span> <span class="kc">None</span> <span class="ow">or</span> <span class="fm">__new__</span> <span class="ow">in</span> <span class="p">(</span><span class="n">Enum</span><span class="o">.</span><span class="fm">__new__</span><span class="p">,</span> <span class="nb">object</span><span class="o">.</span><span class="fm">__new__</span><span class="p">):</span> |
| <span class="n">use_args</span> <span class="o">=</span> <span class="kc">False</span> |
| <span class="k">else</span><span class="p">:</span> |
| <span class="n">use_args</span> <span class="o">=</span> <span class="kc">True</span> |
| <span class="k">return</span> <span class="fm">__new__</span><span class="p">,</span> <span class="n">save_new</span><span class="p">,</span> <span class="n">use_args</span> |
| |
| <span class="k">def</span><span class="w"> </span><span class="nf">_add_member_</span><span class="p">(</span><span class="bp">cls</span><span class="p">,</span> <span class="n">name</span><span class="p">,</span> <span class="n">member</span><span class="p">):</span> |
| <span class="c1"># _value_ structures are not updated</span> |
| <span class="k">if</span> <span class="n">name</span> <span class="ow">in</span> <span class="bp">cls</span><span class="o">.</span><span class="n">_member_map_</span><span class="p">:</span> |
| <span class="k">if</span> <span class="bp">cls</span><span class="o">.</span><span class="n">_member_map_</span><span class="p">[</span><span class="n">name</span><span class="p">]</span> <span class="ow">is</span> <span class="ow">not</span> <span class="n">member</span><span class="p">:</span> |
| <span class="k">raise</span> <span class="ne">NameError</span><span class="p">(</span><span class="s1">'</span><span class="si">%r</span><span class="s1"> is already bound: </span><span class="si">%r</span><span class="s1">'</span> <span class="o">%</span> <span class="p">(</span><span class="n">name</span><span class="p">,</span> <span class="bp">cls</span><span class="o">.</span><span class="n">_member_map_</span><span class="p">[</span><span class="n">name</span><span class="p">]))</span> |
| <span class="k">return</span> |
| <span class="c1">#</span> |
| <span class="c1"># if necessary, get redirect in place and then add it to _member_map_</span> |
| <span class="n">found_descriptor</span> <span class="o">=</span> <span class="kc">None</span> |
| <span class="n">descriptor_type</span> <span class="o">=</span> <span class="kc">None</span> |
| <span class="n">class_type</span> <span class="o">=</span> <span class="kc">None</span> |
| <span class="k">for</span> <span class="n">base</span> <span class="ow">in</span> <span class="bp">cls</span><span class="o">.</span><span class="vm">__mro__</span><span class="p">[</span><span class="mi">1</span><span class="p">:]:</span> |
| <span class="n">attr</span> <span class="o">=</span> <span class="n">base</span><span class="o">.</span><span class="vm">__dict__</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="n">name</span><span class="p">)</span> |
| <span class="k">if</span> <span class="n">attr</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span> |
| <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">attr</span><span class="p">,</span> <span class="p">(</span><span class="nb">property</span><span class="p">,</span> <span class="n">DynamicClassAttribute</span><span class="p">)):</span> |
| <span class="n">found_descriptor</span> <span class="o">=</span> <span class="n">attr</span> |
| <span class="n">class_type</span> <span class="o">=</span> <span class="n">base</span> |
| <span class="n">descriptor_type</span> <span class="o">=</span> <span class="s1">'enum'</span> |
| <span class="k">break</span> |
| <span class="k">elif</span> <span class="n">_is_descriptor</span><span class="p">(</span><span class="n">attr</span><span class="p">):</span> |
| <span class="n">found_descriptor</span> <span class="o">=</span> <span class="n">attr</span> |
| <span class="n">descriptor_type</span> <span class="o">=</span> <span class="n">descriptor_type</span> <span class="ow">or</span> <span class="s1">'desc'</span> |
| <span class="n">class_type</span> <span class="o">=</span> <span class="n">class_type</span> <span class="ow">or</span> <span class="n">base</span> |
| <span class="k">continue</span> |
| <span class="k">else</span><span class="p">:</span> |
| <span class="n">descriptor_type</span> <span class="o">=</span> <span class="s1">'attr'</span> |
| <span class="n">class_type</span> <span class="o">=</span> <span class="n">base</span> |
| <span class="k">if</span> <span class="n">found_descriptor</span><span class="p">:</span> |
| <span class="n">redirect</span> <span class="o">=</span> <span class="nb">property</span><span class="p">()</span> |
| <span class="n">redirect</span><span class="o">.</span><span class="n">member</span> <span class="o">=</span> <span class="n">member</span> |
| <span class="n">redirect</span><span class="o">.</span><span class="n">__set_name__</span><span class="p">(</span><span class="bp">cls</span><span class="p">,</span> <span class="n">name</span><span class="p">)</span> |
| <span class="k">if</span> <span class="n">descriptor_type</span> <span class="ow">in</span> <span class="p">(</span><span class="s1">'enum'</span><span class="p">,</span> <span class="s1">'desc'</span><span class="p">):</span> |
| <span class="c1"># earlier descriptor found; copy fget, fset, fdel to this one.</span> |
| <span class="n">redirect</span><span class="o">.</span><span class="n">fget</span> <span class="o">=</span> <span class="nb">getattr</span><span class="p">(</span><span class="n">found_descriptor</span><span class="p">,</span> <span class="s1">'fget'</span><span class="p">,</span> <span class="kc">None</span><span class="p">)</span> |
| <span class="n">redirect</span><span class="o">.</span><span class="n">_get</span> <span class="o">=</span> <span class="nb">getattr</span><span class="p">(</span><span class="n">found_descriptor</span><span class="p">,</span> <span class="s1">'__get__'</span><span class="p">,</span> <span class="kc">None</span><span class="p">)</span> |
| <span class="n">redirect</span><span class="o">.</span><span class="n">fset</span> <span class="o">=</span> <span class="nb">getattr</span><span class="p">(</span><span class="n">found_descriptor</span><span class="p">,</span> <span class="s1">'fset'</span><span class="p">,</span> <span class="kc">None</span><span class="p">)</span> |
| <span class="n">redirect</span><span class="o">.</span><span class="n">_set</span> <span class="o">=</span> <span class="nb">getattr</span><span class="p">(</span><span class="n">found_descriptor</span><span class="p">,</span> <span class="s1">'__set__'</span><span class="p">,</span> <span class="kc">None</span><span class="p">)</span> |
| <span class="n">redirect</span><span class="o">.</span><span class="n">fdel</span> <span class="o">=</span> <span class="nb">getattr</span><span class="p">(</span><span class="n">found_descriptor</span><span class="p">,</span> <span class="s1">'fdel'</span><span class="p">,</span> <span class="kc">None</span><span class="p">)</span> |
| <span class="n">redirect</span><span class="o">.</span><span class="n">_del</span> <span class="o">=</span> <span class="nb">getattr</span><span class="p">(</span><span class="n">found_descriptor</span><span class="p">,</span> <span class="s1">'__delete__'</span><span class="p">,</span> <span class="kc">None</span><span class="p">)</span> |
| <span class="n">redirect</span><span class="o">.</span><span class="n">_attr_type</span> <span class="o">=</span> <span class="n">descriptor_type</span> |
| <span class="n">redirect</span><span class="o">.</span><span class="n">_cls_type</span> <span class="o">=</span> <span class="n">class_type</span> |
| <span class="nb">setattr</span><span class="p">(</span><span class="bp">cls</span><span class="p">,</span> <span class="n">name</span><span class="p">,</span> <span class="n">redirect</span><span class="p">)</span> |
| <span class="k">else</span><span class="p">:</span> |
| <span class="nb">setattr</span><span class="p">(</span><span class="bp">cls</span><span class="p">,</span> <span class="n">name</span><span class="p">,</span> <span class="n">member</span><span class="p">)</span> |
| <span class="c1"># now add to _member_map_ (even aliases)</span> |
| <span class="bp">cls</span><span class="o">.</span><span class="n">_member_map_</span><span class="p">[</span><span class="n">name</span><span class="p">]</span> <span class="o">=</span> <span class="n">member</span> |
| |
| <span class="n">EnumMeta</span> <span class="o">=</span> <span class="n">EnumType</span> <span class="c1"># keep EnumMeta name for backwards compatibility</span> |
| |
| |
| <span class="k">class</span><span class="w"> </span><span class="nc">Enum</span><span class="p">(</span><span class="n">metaclass</span><span class="o">=</span><span class="n">EnumType</span><span class="p">):</span> |
| <span class="w"> </span><span class="sd">"""</span> |
| <span class="sd"> Create a collection of name/value pairs.</span> |
| |
| <span class="sd"> Example enumeration:</span> |
| |
| <span class="sd"> >>> class Color(Enum):</span> |
| <span class="sd"> ... RED = 1</span> |
| <span class="sd"> ... BLUE = 2</span> |
| <span class="sd"> ... GREEN = 3</span> |
| |
| <span class="sd"> Access them by:</span> |
| |
| <span class="sd"> - attribute access:</span> |
| |
| <span class="sd"> >>> Color.RED</span> |
| <span class="sd"> <Color.RED: 1></span> |
| |
| <span class="sd"> - value lookup:</span> |
| |
| <span class="sd"> >>> Color(1)</span> |
| <span class="sd"> <Color.RED: 1></span> |
| |
| <span class="sd"> - name lookup:</span> |
| |
| <span class="sd"> >>> Color['RED']</span> |
| <span class="sd"> <Color.RED: 1></span> |
| |
| <span class="sd"> Enumerations can be iterated over, and know how many members they have:</span> |
| |
| <span class="sd"> >>> len(Color)</span> |
| <span class="sd"> 3</span> |
| |
| <span class="sd"> >>> list(Color)</span> |
| <span class="sd"> [<Color.RED: 1>, <Color.BLUE: 2>, <Color.GREEN: 3>]</span> |
| |
| <span class="sd"> Methods can be added to enumerations, and members can have their own</span> |
| <span class="sd"> attributes -- see the documentation for details.</span> |
| <span class="sd"> """</span> |
| |
| <span class="nd">@classmethod</span> |
| <span class="k">def</span><span class="w"> </span><span class="nf">__signature__</span><span class="p">(</span><span class="bp">cls</span><span class="p">):</span> |
| <span class="k">if</span> <span class="bp">cls</span><span class="o">.</span><span class="n">_member_names_</span><span class="p">:</span> |
| <span class="k">return</span> <span class="s1">'(*values)'</span> |
| <span class="k">else</span><span class="p">:</span> |
| <span class="k">return</span> <span class="s1">'(new_class_name, /, names, *, module=None, qualname=None, type=None, start=1, boundary=None)'</span> |
| |
| <span class="k">def</span><span class="w"> </span><span class="fm">__new__</span><span class="p">(</span><span class="bp">cls</span><span class="p">,</span> <span class="n">value</span><span class="p">):</span> |
| <span class="c1"># all enum instances are actually created during class construction</span> |
| <span class="c1"># without calling this method; this method is called by the metaclass'</span> |
| <span class="c1"># __call__ (i.e. Color(3) ), and by pickle</span> |
| <span class="k">if</span> <span class="nb">type</span><span class="p">(</span><span class="n">value</span><span class="p">)</span> <span class="ow">is</span> <span class="bp">cls</span><span class="p">:</span> |
| <span class="c1"># For lookups like Color(Color.RED)</span> |
| <span class="k">return</span> <span class="n">value</span> |
| <span class="c1"># by-value search for a matching enum member</span> |
| <span class="c1"># see if it's in the reverse mapping (for hashable values)</span> |
| <span class="k">try</span><span class="p">:</span> |
| <span class="k">return</span> <span class="bp">cls</span><span class="o">.</span><span class="n">_value2member_map_</span><span class="p">[</span><span class="n">value</span><span class="p">]</span> |
| <span class="k">except</span> <span class="ne">KeyError</span><span class="p">:</span> |
| <span class="c1"># Not found, no need to do long O(n) search</span> |
| <span class="k">pass</span> |
| <span class="k">except</span> <span class="ne">TypeError</span><span class="p">:</span> |
| <span class="c1"># not there, now do long search -- O(n) behavior</span> |
| <span class="k">for</span> <span class="n">name</span><span class="p">,</span> <span class="n">unhashable_values</span> <span class="ow">in</span> <span class="bp">cls</span><span class="o">.</span><span class="n">_unhashable_values_map_</span><span class="o">.</span><span class="n">items</span><span class="p">():</span> |
| <span class="k">if</span> <span class="n">value</span> <span class="ow">in</span> <span class="n">unhashable_values</span><span class="p">:</span> |
| <span class="k">return</span> <span class="bp">cls</span><span class="p">[</span><span class="n">name</span><span class="p">]</span> |
| <span class="k">for</span> <span class="n">name</span><span class="p">,</span> <span class="n">member</span> <span class="ow">in</span> <span class="bp">cls</span><span class="o">.</span><span class="n">_member_map_</span><span class="o">.</span><span class="n">items</span><span class="p">():</span> |
| <span class="k">if</span> <span class="n">value</span> <span class="o">==</span> <span class="n">member</span><span class="o">.</span><span class="n">_value_</span><span class="p">:</span> |
| <span class="k">return</span> <span class="bp">cls</span><span class="p">[</span><span class="n">name</span><span class="p">]</span> |
| <span class="c1"># still not found -- verify that members exist, in-case somebody got here mistakenly</span> |
| <span class="c1"># (such as via super when trying to override __new__)</span> |
| <span class="k">if</span> <span class="ow">not</span> <span class="bp">cls</span><span class="o">.</span><span class="n">_member_map_</span><span class="p">:</span> |
| <span class="k">if</span> <span class="nb">getattr</span><span class="p">(</span><span class="bp">cls</span><span class="p">,</span> <span class="s1">'_</span><span class="si">%s</span><span class="s1">__in_progress'</span> <span class="o">%</span> <span class="bp">cls</span><span class="o">.</span><span class="vm">__name__</span><span class="p">,</span> <span class="kc">False</span><span class="p">):</span> |
| <span class="k">raise</span> <span class="ne">TypeError</span><span class="p">(</span><span class="s1">'do not use `super().__new__; call the appropriate __new__ directly'</span><span class="p">)</span> <span class="kn">from</span><span class="w"> </span><span class="kc">None</span> |
| <span class="k">raise</span> <span class="ne">TypeError</span><span class="p">(</span><span class="s2">"</span><span class="si">%r</span><span class="s2"> has no members defined"</span> <span class="o">%</span> <span class="bp">cls</span><span class="p">)</span> |
| <span class="c1">#</span> |
| <span class="c1"># still not found -- try _missing_ hook</span> |
| <span class="k">try</span><span class="p">:</span> |
| <span class="n">exc</span> <span class="o">=</span> <span class="kc">None</span> |
| <span class="n">result</span> <span class="o">=</span> <span class="bp">cls</span><span class="o">.</span><span class="n">_missing_</span><span class="p">(</span><span class="n">value</span><span class="p">)</span> |
| <span class="k">except</span> <span class="ne">Exception</span> <span class="k">as</span> <span class="n">e</span><span class="p">:</span> |
| <span class="n">exc</span> <span class="o">=</span> <span class="n">e</span> |
| <span class="n">result</span> <span class="o">=</span> <span class="kc">None</span> |
| <span class="k">try</span><span class="p">:</span> |
| <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">result</span><span class="p">,</span> <span class="bp">cls</span><span class="p">):</span> |
| <span class="k">return</span> <span class="n">result</span> |
| <span class="k">elif</span> <span class="p">(</span> |
| <span class="n">Flag</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span> <span class="ow">and</span> <span class="nb">issubclass</span><span class="p">(</span><span class="bp">cls</span><span class="p">,</span> <span class="n">Flag</span><span class="p">)</span> |
| <span class="ow">and</span> <span class="bp">cls</span><span class="o">.</span><span class="n">_boundary_</span> <span class="ow">is</span> <span class="n">EJECT</span> <span class="ow">and</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">result</span><span class="p">,</span> <span class="nb">int</span><span class="p">)</span> |
| <span class="p">):</span> |
| <span class="k">return</span> <span class="n">result</span> |
| <span class="k">else</span><span class="p">:</span> |
| <span class="n">ve_exc</span> <span class="o">=</span> <span class="ne">ValueError</span><span class="p">(</span><span class="s2">"</span><span class="si">%r</span><span class="s2"> is not a valid </span><span class="si">%s</span><span class="s2">"</span> <span class="o">%</span> <span class="p">(</span><span class="n">value</span><span class="p">,</span> <span class="bp">cls</span><span class="o">.</span><span class="vm">__qualname__</span><span class="p">))</span> |
| <span class="k">if</span> <span class="n">result</span> <span class="ow">is</span> <span class="kc">None</span> <span class="ow">and</span> <span class="n">exc</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span> |
| <span class="k">raise</span> <span class="n">ve_exc</span> |
| <span class="k">elif</span> <span class="n">exc</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span> |
| <span class="n">exc</span> <span class="o">=</span> <span class="ne">TypeError</span><span class="p">(</span> |
| <span class="s1">'error in </span><span class="si">%s</span><span class="s1">._missing_: returned </span><span class="si">%r</span><span class="s1"> instead of None or a valid member'</span> |
| <span class="o">%</span> <span class="p">(</span><span class="bp">cls</span><span class="o">.</span><span class="vm">__name__</span><span class="p">,</span> <span class="n">result</span><span class="p">)</span> |
| <span class="p">)</span> |
| <span class="k">if</span> <span class="ow">not</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">exc</span><span class="p">,</span> <span class="ne">ValueError</span><span class="p">):</span> |
| <span class="n">exc</span><span class="o">.</span><span class="n">__context__</span> <span class="o">=</span> <span class="n">ve_exc</span> |
| <span class="k">raise</span> <span class="n">exc</span> |
| <span class="k">finally</span><span class="p">:</span> |
| <span class="c1"># ensure all variables that could hold an exception are destroyed</span> |
| <span class="n">exc</span> <span class="o">=</span> <span class="kc">None</span> |
| <span class="n">ve_exc</span> <span class="o">=</span> <span class="kc">None</span> |
| |
| <span class="k">def</span><span class="w"> </span><span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="o">**</span><span class="n">kwds</span><span class="p">):</span> |
| <span class="k">pass</span> |
| |
| <span class="k">def</span><span class="w"> </span><span class="nf">_add_alias_</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">name</span><span class="p">):</span> |
| <span class="bp">self</span><span class="o">.</span><span class="vm">__class__</span><span class="o">.</span><span class="n">_add_member_</span><span class="p">(</span><span class="n">name</span><span class="p">,</span> <span class="bp">self</span><span class="p">)</span> |
| |
| <span class="k">def</span><span class="w"> </span><span class="nf">_add_value_alias_</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">value</span><span class="p">):</span> |
| <span class="bp">cls</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="vm">__class__</span> |
| <span class="k">try</span><span class="p">:</span> |
| <span class="k">if</span> <span class="n">value</span> <span class="ow">in</span> <span class="bp">cls</span><span class="o">.</span><span class="n">_value2member_map_</span><span class="p">:</span> |
| <span class="k">if</span> <span class="bp">cls</span><span class="o">.</span><span class="n">_value2member_map_</span><span class="p">[</span><span class="n">value</span><span class="p">]</span> <span class="ow">is</span> <span class="ow">not</span> <span class="bp">self</span><span class="p">:</span> |
| <span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="s1">'</span><span class="si">%r</span><span class="s1"> is already bound: </span><span class="si">%r</span><span class="s1">'</span> <span class="o">%</span> <span class="p">(</span><span class="n">value</span><span class="p">,</span> <span class="bp">cls</span><span class="o">.</span><span class="n">_value2member_map_</span><span class="p">[</span><span class="n">value</span><span class="p">]))</span> |
| <span class="k">return</span> |
| <span class="k">except</span> <span class="ne">TypeError</span><span class="p">:</span> |
| <span class="c1"># unhashable value, do long search</span> |
| <span class="k">for</span> <span class="n">m</span> <span class="ow">in</span> <span class="bp">cls</span><span class="o">.</span><span class="n">_member_map_</span><span class="o">.</span><span class="n">values</span><span class="p">():</span> |
| <span class="k">if</span> <span class="n">m</span><span class="o">.</span><span class="n">_value_</span> <span class="o">==</span> <span class="n">value</span><span class="p">:</span> |
| <span class="k">if</span> <span class="n">m</span> <span class="ow">is</span> <span class="ow">not</span> <span class="bp">self</span><span class="p">:</span> |
| <span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="s1">'</span><span class="si">%r</span><span class="s1"> is already bound: </span><span class="si">%r</span><span class="s1">'</span> <span class="o">%</span> <span class="p">(</span><span class="n">value</span><span class="p">,</span> <span class="bp">cls</span><span class="o">.</span><span class="n">_value2member_map_</span><span class="p">[</span><span class="n">value</span><span class="p">]))</span> |
| <span class="k">return</span> |
| <span class="k">try</span><span class="p">:</span> |
| <span class="c1"># This may fail if value is not hashable. We can't add the value</span> |
| <span class="c1"># to the map, and by-value lookups for this value will be</span> |
| <span class="c1"># linear.</span> |
| <span class="bp">cls</span><span class="o">.</span><span class="n">_value2member_map_</span><span class="o">.</span><span class="n">setdefault</span><span class="p">(</span><span class="n">value</span><span class="p">,</span> <span class="bp">self</span><span class="p">)</span> |
| <span class="bp">cls</span><span class="o">.</span><span class="n">_hashable_values_</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">value</span><span class="p">)</span> |
| <span class="k">except</span> <span class="ne">TypeError</span><span class="p">:</span> |
| <span class="c1"># keep track of the value in a list so containment checks are quick</span> |
| <span class="bp">cls</span><span class="o">.</span><span class="n">_unhashable_values_</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">value</span><span class="p">)</span> |
| <span class="bp">cls</span><span class="o">.</span><span class="n">_unhashable_values_map_</span><span class="o">.</span><span class="n">setdefault</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">name</span><span class="p">,</span> <span class="p">[])</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">value</span><span class="p">)</span> |
| |
| <span class="nd">@staticmethod</span> |
| <span class="k">def</span><span class="w"> </span><span class="nf">_generate_next_value_</span><span class="p">(</span><span class="n">name</span><span class="p">,</span> <span class="n">start</span><span class="p">,</span> <span class="n">count</span><span class="p">,</span> <span class="n">last_values</span><span class="p">):</span> |
| <span class="w"> </span><span class="sd">"""</span> |
| <span class="sd"> Generate the next value when not given.</span> |
| |
| <span class="sd"> name: the name of the member</span> |
| <span class="sd"> start: the initial start value or None</span> |
| <span class="sd"> count: the number of existing members</span> |
| <span class="sd"> last_values: the list of values assigned</span> |
| <span class="sd"> """</span> |
| <span class="k">if</span> <span class="ow">not</span> <span class="n">last_values</span><span class="p">:</span> |
| <span class="k">return</span> <span class="n">start</span> |
| <span class="k">try</span><span class="p">:</span> |
| <span class="n">last_value</span> <span class="o">=</span> <span class="nb">sorted</span><span class="p">(</span><span class="n">last_values</span><span class="p">)</span><span class="o">.</span><span class="n">pop</span><span class="p">()</span> |
| <span class="k">except</span> <span class="ne">TypeError</span><span class="p">:</span> |
| <span class="k">raise</span> <span class="ne">TypeError</span><span class="p">(</span><span class="s1">'unable to sort non-numeric values'</span><span class="p">)</span> <span class="kn">from</span><span class="w"> </span><span class="kc">None</span> |
| <span class="k">try</span><span class="p">:</span> |
| <span class="k">return</span> <span class="n">last_value</span> <span class="o">+</span> <span class="mi">1</span> |
| <span class="k">except</span> <span class="ne">TypeError</span><span class="p">:</span> |
| <span class="k">raise</span> <span class="ne">TypeError</span><span class="p">(</span><span class="s1">'unable to increment </span><span class="si">%r</span><span class="s1">'</span> <span class="o">%</span> <span class="p">(</span><span class="n">last_value</span><span class="p">,</span> <span class="p">))</span> <span class="kn">from</span><span class="w"> </span><span class="kc">None</span> |
| |
| <span class="nd">@classmethod</span> |
| <span class="k">def</span><span class="w"> </span><span class="nf">_missing_</span><span class="p">(</span><span class="bp">cls</span><span class="p">,</span> <span class="n">value</span><span class="p">):</span> |
| <span class="k">return</span> <span class="kc">None</span> |
| |
| <span class="k">def</span><span class="w"> </span><span class="fm">__repr__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span> |
| <span class="n">v_repr</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="vm">__class__</span><span class="o">.</span><span class="n">_value_repr_</span> <span class="ow">or</span> <span class="nb">repr</span> |
| <span class="k">return</span> <span class="s2">"<</span><span class="si">%s</span><span class="s2">.</span><span class="si">%s</span><span class="s2">: </span><span class="si">%s</span><span class="s2">>"</span> <span class="o">%</span> <span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="vm">__class__</span><span class="o">.</span><span class="vm">__name__</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">_name_</span><span class="p">,</span> <span class="n">v_repr</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_value_</span><span class="p">))</span> |
| |
| <span class="k">def</span><span class="w"> </span><span class="fm">__str__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span> |
| <span class="k">return</span> <span class="s2">"</span><span class="si">%s</span><span class="s2">.</span><span class="si">%s</span><span class="s2">"</span> <span class="o">%</span> <span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="vm">__class__</span><span class="o">.</span><span class="vm">__name__</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">_name_</span><span class="p">,</span> <span class="p">)</span> |
| |
| <span class="k">def</span><span class="w"> </span><span class="fm">__dir__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span> |
| <span class="w"> </span><span class="sd">"""</span> |
| <span class="sd"> Returns public methods and other interesting attributes.</span> |
| <span class="sd"> """</span> |
| <span class="n">interesting</span> <span class="o">=</span> <span class="nb">set</span><span class="p">()</span> |
| <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="vm">__class__</span><span class="o">.</span><span class="n">_member_type_</span> <span class="ow">is</span> <span class="ow">not</span> <span class="nb">object</span><span class="p">:</span> |
| <span class="n">interesting</span> <span class="o">=</span> <span class="nb">set</span><span class="p">(</span><span class="nb">object</span><span class="o">.</span><span class="fm">__dir__</span><span class="p">(</span><span class="bp">self</span><span class="p">))</span> |
| <span class="k">for</span> <span class="n">name</span> <span class="ow">in</span> <span class="nb">getattr</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="s1">'__dict__'</span><span class="p">,</span> <span class="p">[]):</span> |
| <span class="k">if</span> <span class="n">name</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">!=</span> <span class="s1">'_'</span> <span class="ow">and</span> <span class="n">name</span> <span class="ow">not</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">_member_map_</span><span class="p">:</span> |
| <span class="n">interesting</span><span class="o">.</span><span class="n">add</span><span class="p">(</span><span class="n">name</span><span class="p">)</span> |
| <span class="k">for</span> <span class="bp">cls</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="vm">__class__</span><span class="o">.</span><span class="n">mro</span><span class="p">():</span> |
| <span class="k">for</span> <span class="n">name</span><span class="p">,</span> <span class="n">obj</span> <span class="ow">in</span> <span class="bp">cls</span><span class="o">.</span><span class="vm">__dict__</span><span class="o">.</span><span class="n">items</span><span class="p">():</span> |
| <span class="k">if</span> <span class="n">name</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">==</span> <span class="s1">'_'</span><span class="p">:</span> |
| <span class="k">continue</span> |
| <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">obj</span><span class="p">,</span> <span class="nb">property</span><span class="p">):</span> |
| <span class="c1"># that's an enum.property</span> |
| <span class="k">if</span> <span class="n">obj</span><span class="o">.</span><span class="n">fget</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span> <span class="ow">or</span> <span class="n">name</span> <span class="ow">not</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">_member_map_</span><span class="p">:</span> |
| <span class="n">interesting</span><span class="o">.</span><span class="n">add</span><span class="p">(</span><span class="n">name</span><span class="p">)</span> |
| <span class="k">else</span><span class="p">:</span> |
| <span class="c1"># in case it was added by `dir(self)`</span> |
| <span class="n">interesting</span><span class="o">.</span><span class="n">discard</span><span class="p">(</span><span class="n">name</span><span class="p">)</span> |
| <span class="k">elif</span> <span class="n">name</span> <span class="ow">not</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">_member_map_</span><span class="p">:</span> |
| <span class="n">interesting</span><span class="o">.</span><span class="n">add</span><span class="p">(</span><span class="n">name</span><span class="p">)</span> |
| <span class="n">names</span> <span class="o">=</span> <span class="nb">sorted</span><span class="p">(</span> |
| <span class="nb">set</span><span class="p">([</span><span class="s1">'__class__'</span><span class="p">,</span> <span class="s1">'__doc__'</span><span class="p">,</span> <span class="s1">'__eq__'</span><span class="p">,</span> <span class="s1">'__hash__'</span><span class="p">,</span> <span class="s1">'__module__'</span><span class="p">])</span> |
| <span class="o">|</span> <span class="n">interesting</span> |
| <span class="p">)</span> |
| <span class="k">return</span> <span class="n">names</span> |
| |
| <span class="k">def</span><span class="w"> </span><span class="fm">__format__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">format_spec</span><span class="p">):</span> |
| <span class="k">return</span> <span class="nb">str</span><span class="o">.</span><span class="fm">__format__</span><span class="p">(</span><span class="nb">str</span><span class="p">(</span><span class="bp">self</span><span class="p">),</span> <span class="n">format_spec</span><span class="p">)</span> |
| |
| <span class="k">def</span><span class="w"> </span><span class="fm">__hash__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span> |
| <span class="k">return</span> <span class="nb">hash</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_name_</span><span class="p">)</span> |
| |
| <span class="k">def</span><span class="w"> </span><span class="nf">__reduce_ex__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">proto</span><span class="p">):</span> |
| <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="vm">__class__</span><span class="p">,</span> <span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_value_</span><span class="p">,</span> <span class="p">)</span> |
| |
| <span class="k">def</span><span class="w"> </span><span class="nf">__deepcopy__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span><span class="n">memo</span><span class="p">):</span> |
| <span class="k">return</span> <span class="bp">self</span> |
| |
| <span class="k">def</span><span class="w"> </span><span class="nf">__copy__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span> |
| <span class="k">return</span> <span class="bp">self</span> |
| |
| <span class="c1"># enum.property is used to provide access to the `name` and</span> |
| <span class="c1"># `value` attributes of enum members while keeping some measure of</span> |
| <span class="c1"># protection from modification, while still allowing for an enumeration</span> |
| <span class="c1"># to have members named `name` and `value`. This works because each</span> |
| <span class="c1"># instance of enum.property saves its companion member, which it returns</span> |
| <span class="c1"># on class lookup; on instance lookup it either executes a provided function</span> |
| <span class="c1"># or raises an AttributeError.</span> |
| |
| <span class="nd">@property</span> |
| <span class="k">def</span><span class="w"> </span><span class="nf">name</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span> |
| <span class="w"> </span><span class="sd">"""The name of the Enum member."""</span> |
| <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_name_</span> |
| |
| <span class="nd">@property</span> |
| <span class="k">def</span><span class="w"> </span><span class="nf">value</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span> |
| <span class="w"> </span><span class="sd">"""The value of the Enum member."""</span> |
| <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_value_</span> |
| |
| |
| <span class="k">class</span><span class="w"> </span><span class="nc">ReprEnum</span><span class="p">(</span><span class="n">Enum</span><span class="p">):</span> |
| <span class="w"> </span><span class="sd">"""</span> |
| <span class="sd"> Only changes the repr(), leaving str() and format() to the mixed-in type.</span> |
| <span class="sd"> """</span> |
| |
| |
| <span class="k">class</span><span class="w"> </span><span class="nc">IntEnum</span><span class="p">(</span><span class="nb">int</span><span class="p">,</span> <span class="n">ReprEnum</span><span class="p">):</span> |
| <span class="w"> </span><span class="sd">"""</span> |
| <span class="sd"> Enum where members are also (and must be) ints</span> |
| <span class="sd"> """</span> |
| |
| |
| <span class="k">class</span><span class="w"> </span><span class="nc">StrEnum</span><span class="p">(</span><span class="nb">str</span><span class="p">,</span> <span class="n">ReprEnum</span><span class="p">):</span> |
| <span class="w"> </span><span class="sd">"""</span> |
| <span class="sd"> Enum where members are also (and must be) strings</span> |
| <span class="sd"> """</span> |
| |
| <span class="k">def</span><span class="w"> </span><span class="fm">__new__</span><span class="p">(</span><span class="bp">cls</span><span class="p">,</span> <span class="o">*</span><span class="n">values</span><span class="p">):</span> |
| <span class="s2">"values must already be of type `str`"</span> |
| <span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">values</span><span class="p">)</span> <span class="o">></span> <span class="mi">3</span><span class="p">:</span> |
| <span class="k">raise</span> <span class="ne">TypeError</span><span class="p">(</span><span class="s1">'too many arguments for str(): </span><span class="si">%r</span><span class="s1">'</span> <span class="o">%</span> <span class="p">(</span><span class="n">values</span><span class="p">,</span> <span class="p">))</span> |
| <span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">values</span><span class="p">)</span> <span class="o">==</span> <span class="mi">1</span><span class="p">:</span> |
| <span class="c1"># it must be a string</span> |
| <span class="k">if</span> <span class="ow">not</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">values</span><span class="p">[</span><span class="mi">0</span><span class="p">],</span> <span class="nb">str</span><span class="p">):</span> |
| <span class="k">raise</span> <span class="ne">TypeError</span><span class="p">(</span><span class="s1">'</span><span class="si">%r</span><span class="s1"> is not a string'</span> <span class="o">%</span> <span class="p">(</span><span class="n">values</span><span class="p">[</span><span class="mi">0</span><span class="p">],</span> <span class="p">))</span> |
| <span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">values</span><span class="p">)</span> <span class="o">>=</span> <span class="mi">2</span><span class="p">:</span> |
| <span class="c1"># check that encoding argument is a string</span> |
| <span class="k">if</span> <span class="ow">not</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">values</span><span class="p">[</span><span class="mi">1</span><span class="p">],</span> <span class="nb">str</span><span class="p">):</span> |
| <span class="k">raise</span> <span class="ne">TypeError</span><span class="p">(</span><span class="s1">'encoding must be a string, not </span><span class="si">%r</span><span class="s1">'</span> <span class="o">%</span> <span class="p">(</span><span class="n">values</span><span class="p">[</span><span class="mi">1</span><span class="p">],</span> <span class="p">))</span> |
| <span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">values</span><span class="p">)</span> <span class="o">==</span> <span class="mi">3</span><span class="p">:</span> |
| <span class="c1"># check that errors argument is a string</span> |
| <span class="k">if</span> <span class="ow">not</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">values</span><span class="p">[</span><span class="mi">2</span><span class="p">],</span> <span class="nb">str</span><span class="p">):</span> |
| <span class="k">raise</span> <span class="ne">TypeError</span><span class="p">(</span><span class="s1">'errors must be a string, not </span><span class="si">%r</span><span class="s1">'</span> <span class="o">%</span> <span class="p">(</span><span class="n">values</span><span class="p">[</span><span class="mi">2</span><span class="p">]))</span> |
| <span class="n">value</span> <span class="o">=</span> <span class="nb">str</span><span class="p">(</span><span class="o">*</span><span class="n">values</span><span class="p">)</span> |
| <span class="n">member</span> <span class="o">=</span> <span class="nb">str</span><span class="o">.</span><span class="fm">__new__</span><span class="p">(</span><span class="bp">cls</span><span class="p">,</span> <span class="n">value</span><span class="p">)</span> |
| <span class="n">member</span><span class="o">.</span><span class="n">_value_</span> <span class="o">=</span> <span class="n">value</span> |
| <span class="k">return</span> <span class="n">member</span> |
| |
| <span class="nd">@staticmethod</span> |
| <span class="k">def</span><span class="w"> </span><span class="nf">_generate_next_value_</span><span class="p">(</span><span class="n">name</span><span class="p">,</span> <span class="n">start</span><span class="p">,</span> <span class="n">count</span><span class="p">,</span> <span class="n">last_values</span><span class="p">):</span> |
| <span class="w"> </span><span class="sd">"""</span> |
| <span class="sd"> Return the lower-cased version of the member name.</span> |
| <span class="sd"> """</span> |
| <span class="k">return</span> <span class="n">name</span><span class="o">.</span><span class="n">lower</span><span class="p">()</span> |
| |
| |
| <span class="k">def</span><span class="w"> </span><span class="nf">pickle_by_global_name</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">proto</span><span class="p">):</span> |
| <span class="c1"># should not be used with Flag-type enums</span> |
| <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">name</span> |
| <span class="n">_reduce_ex_by_global_name</span> <span class="o">=</span> <span class="n">pickle_by_global_name</span> |
| |
| <span class="k">def</span><span class="w"> </span><span class="nf">pickle_by_enum_name</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">proto</span><span class="p">):</span> |
| <span class="c1"># should not be used with Flag-type enums</span> |
| <span class="k">return</span> <span class="nb">getattr</span><span class="p">,</span> <span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="vm">__class__</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">_name_</span><span class="p">)</span> |
| |
| <span class="k">class</span><span class="w"> </span><span class="nc">FlagBoundary</span><span class="p">(</span><span class="n">StrEnum</span><span class="p">):</span> |
| <span class="w"> </span><span class="sd">"""</span> |
| <span class="sd"> control how out of range values are handled</span> |
| <span class="sd"> "strict" -> error is raised [default for Flag]</span> |
| <span class="sd"> "conform" -> extra bits are discarded</span> |
| <span class="sd"> "eject" -> lose flag status</span> |
| <span class="sd"> "keep" -> keep flag status and all bits [default for IntFlag]</span> |
| <span class="sd"> """</span> |
| <span class="n">STRICT</span> <span class="o">=</span> <span class="n">auto</span><span class="p">()</span> |
| <span class="n">CONFORM</span> <span class="o">=</span> <span class="n">auto</span><span class="p">()</span> |
| <span class="n">EJECT</span> <span class="o">=</span> <span class="n">auto</span><span class="p">()</span> |
| <span class="n">KEEP</span> <span class="o">=</span> <span class="n">auto</span><span class="p">()</span> |
| <span class="n">STRICT</span><span class="p">,</span> <span class="n">CONFORM</span><span class="p">,</span> <span class="n">EJECT</span><span class="p">,</span> <span class="n">KEEP</span> <span class="o">=</span> <span class="n">FlagBoundary</span> |
| |
| |
| <span class="k">class</span><span class="w"> </span><span class="nc">Flag</span><span class="p">(</span><span class="n">Enum</span><span class="p">,</span> <span class="n">boundary</span><span class="o">=</span><span class="n">STRICT</span><span class="p">):</span> |
| <span class="w"> </span><span class="sd">"""</span> |
| <span class="sd"> Support for flags</span> |
| <span class="sd"> """</span> |
| |
| <span class="n">_numeric_repr_</span> <span class="o">=</span> <span class="nb">repr</span> |
| |
| <span class="nd">@staticmethod</span> |
| <span class="k">def</span><span class="w"> </span><span class="nf">_generate_next_value_</span><span class="p">(</span><span class="n">name</span><span class="p">,</span> <span class="n">start</span><span class="p">,</span> <span class="n">count</span><span class="p">,</span> <span class="n">last_values</span><span class="p">):</span> |
| <span class="w"> </span><span class="sd">"""</span> |
| <span class="sd"> Generate the next value when not given.</span> |
| |
| <span class="sd"> name: the name of the member</span> |
| <span class="sd"> start: the initial start value or None</span> |
| <span class="sd"> count: the number of existing members</span> |
| <span class="sd"> last_values: the last value assigned or None</span> |
| <span class="sd"> """</span> |
| <span class="k">if</span> <span class="ow">not</span> <span class="n">count</span><span class="p">:</span> |
| <span class="k">return</span> <span class="n">start</span> <span class="k">if</span> <span class="n">start</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span> <span class="k">else</span> <span class="mi">1</span> |
| <span class="n">last_value</span> <span class="o">=</span> <span class="nb">max</span><span class="p">(</span><span class="n">last_values</span><span class="p">)</span> |
| <span class="k">try</span><span class="p">:</span> |
| <span class="n">high_bit</span> <span class="o">=</span> <span class="n">_high_bit</span><span class="p">(</span><span class="n">last_value</span><span class="p">)</span> |
| <span class="k">except</span> <span class="ne">Exception</span><span class="p">:</span> |
| <span class="k">raise</span> <span class="ne">TypeError</span><span class="p">(</span><span class="s1">'invalid flag value </span><span class="si">%r</span><span class="s1">'</span> <span class="o">%</span> <span class="n">last_value</span><span class="p">)</span> <span class="kn">from</span><span class="w"> </span><span class="kc">None</span> |
| <span class="k">return</span> <span class="mi">2</span> <span class="o">**</span> <span class="p">(</span><span class="n">high_bit</span><span class="o">+</span><span class="mi">1</span><span class="p">)</span> |
| |
| <span class="nd">@classmethod</span> |
| <span class="k">def</span><span class="w"> </span><span class="nf">_iter_member_by_value_</span><span class="p">(</span><span class="bp">cls</span><span class="p">,</span> <span class="n">value</span><span class="p">):</span> |
| <span class="w"> </span><span class="sd">"""</span> |
| <span class="sd"> Extract all members from the value in definition (i.e. increasing value) order.</span> |
| <span class="sd"> """</span> |
| <span class="k">for</span> <span class="n">val</span> <span class="ow">in</span> <span class="n">_iter_bits_lsb</span><span class="p">(</span><span class="n">value</span> <span class="o">&</span> <span class="bp">cls</span><span class="o">.</span><span class="n">_flag_mask_</span><span class="p">):</span> |
| <span class="k">yield</span> <span class="bp">cls</span><span class="o">.</span><span class="n">_value2member_map_</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="n">val</span><span class="p">)</span> |
| |
| <span class="n">_iter_member_</span> <span class="o">=</span> <span class="n">_iter_member_by_value_</span> |
| |
| <span class="nd">@classmethod</span> |
| <span class="k">def</span><span class="w"> </span><span class="nf">_iter_member_by_def_</span><span class="p">(</span><span class="bp">cls</span><span class="p">,</span> <span class="n">value</span><span class="p">):</span> |
| <span class="w"> </span><span class="sd">"""</span> |
| <span class="sd"> Extract all members from the value in definition order.</span> |
| <span class="sd"> """</span> |
| <span class="k">yield from</span> <span class="nb">sorted</span><span class="p">(</span> |
| <span class="bp">cls</span><span class="o">.</span><span class="n">_iter_member_by_value_</span><span class="p">(</span><span class="n">value</span><span class="p">),</span> |
| <span class="n">key</span><span class="o">=</span><span class="k">lambda</span> <span class="n">m</span><span class="p">:</span> <span class="n">m</span><span class="o">.</span><span class="n">_sort_order_</span><span class="p">,</span> |
| <span class="p">)</span> |
| |
| <span class="nd">@classmethod</span> |
| <span class="k">def</span><span class="w"> </span><span class="nf">_missing_</span><span class="p">(</span><span class="bp">cls</span><span class="p">,</span> <span class="n">value</span><span class="p">):</span> |
| <span class="w"> </span><span class="sd">"""</span> |
| <span class="sd"> Create a composite member containing all canonical members present in `value`.</span> |
| |
| <span class="sd"> If non-member values are present, result depends on `_boundary_` setting.</span> |
| <span class="sd"> """</span> |
| <span class="k">if</span> <span class="ow">not</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">value</span><span class="p">,</span> <span class="nb">int</span><span class="p">):</span> |
| <span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span> |
| <span class="s2">"</span><span class="si">%r</span><span class="s2"> is not a valid </span><span class="si">%s</span><span class="s2">"</span> <span class="o">%</span> <span class="p">(</span><span class="n">value</span><span class="p">,</span> <span class="bp">cls</span><span class="o">.</span><span class="vm">__qualname__</span><span class="p">)</span> |
| <span class="p">)</span> |
| <span class="c1"># check boundaries</span> |
| <span class="c1"># - value must be in range (e.g. -16 <-> +15, i.e. ~15 <-> 15)</span> |
| <span class="c1"># - value must not include any skipped flags (e.g. if bit 2 is not</span> |
| <span class="c1"># defined, then 0d10 is invalid)</span> |
| <span class="n">flag_mask</span> <span class="o">=</span> <span class="bp">cls</span><span class="o">.</span><span class="n">_flag_mask_</span> |
| <span class="n">singles_mask</span> <span class="o">=</span> <span class="bp">cls</span><span class="o">.</span><span class="n">_singles_mask_</span> |
| <span class="n">all_bits</span> <span class="o">=</span> <span class="bp">cls</span><span class="o">.</span><span class="n">_all_bits_</span> |
| <span class="n">neg_value</span> <span class="o">=</span> <span class="kc">None</span> |
| <span class="k">if</span> <span class="p">(</span> |
| <span class="ow">not</span> <span class="o">~</span><span class="n">all_bits</span> <span class="o"><=</span> <span class="n">value</span> <span class="o"><=</span> <span class="n">all_bits</span> |
| <span class="ow">or</span> <span class="n">value</span> <span class="o">&</span> <span class="p">(</span><span class="n">all_bits</span> <span class="o">^</span> <span class="n">flag_mask</span><span class="p">)</span> |
| <span class="p">):</span> |
| <span class="k">if</span> <span class="bp">cls</span><span class="o">.</span><span class="n">_boundary_</span> <span class="ow">is</span> <span class="n">STRICT</span><span class="p">:</span> |
| <span class="n">max_bits</span> <span class="o">=</span> <span class="nb">max</span><span class="p">(</span><span class="n">value</span><span class="o">.</span><span class="n">bit_length</span><span class="p">(),</span> <span class="n">flag_mask</span><span class="o">.</span><span class="n">bit_length</span><span class="p">())</span> |
| <span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span> |
| <span class="s2">"</span><span class="si">%r</span><span class="s2"> invalid value </span><span class="si">%r</span><span class="se">\n</span><span class="s2"> given </span><span class="si">%s</span><span class="se">\n</span><span class="s2"> allowed </span><span class="si">%s</span><span class="s2">"</span> <span class="o">%</span> <span class="p">(</span> |
| <span class="bp">cls</span><span class="p">,</span> <span class="n">value</span><span class="p">,</span> <span class="nb">bin</span><span class="p">(</span><span class="n">value</span><span class="p">,</span> <span class="n">max_bits</span><span class="p">),</span> <span class="nb">bin</span><span class="p">(</span><span class="n">flag_mask</span><span class="p">,</span> <span class="n">max_bits</span><span class="p">),</span> |
| <span class="p">))</span> |
| <span class="k">elif</span> <span class="bp">cls</span><span class="o">.</span><span class="n">_boundary_</span> <span class="ow">is</span> <span class="n">CONFORM</span><span class="p">:</span> |
| <span class="n">value</span> <span class="o">=</span> <span class="n">value</span> <span class="o">&</span> <span class="n">flag_mask</span> |
| <span class="k">elif</span> <span class="bp">cls</span><span class="o">.</span><span class="n">_boundary_</span> <span class="ow">is</span> <span class="n">EJECT</span><span class="p">:</span> |
| <span class="k">return</span> <span class="n">value</span> |
| <span class="k">elif</span> <span class="bp">cls</span><span class="o">.</span><span class="n">_boundary_</span> <span class="ow">is</span> <span class="n">KEEP</span><span class="p">:</span> |
| <span class="k">if</span> <span class="n">value</span> <span class="o"><</span> <span class="mi">0</span><span class="p">:</span> |
| <span class="n">value</span> <span class="o">=</span> <span class="p">(</span> |
| <span class="nb">max</span><span class="p">(</span><span class="n">all_bits</span><span class="o">+</span><span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="o">**</span><span class="p">(</span><span class="n">value</span><span class="o">.</span><span class="n">bit_length</span><span class="p">()))</span> |
| <span class="o">+</span> <span class="n">value</span> |
| <span class="p">)</span> |
| <span class="k">else</span><span class="p">:</span> |
| <span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span> |
| <span class="s1">'</span><span class="si">%r</span><span class="s1"> unknown flag boundary </span><span class="si">%r</span><span class="s1">'</span> <span class="o">%</span> <span class="p">(</span><span class="bp">cls</span><span class="p">,</span> <span class="bp">cls</span><span class="o">.</span><span class="n">_boundary_</span><span class="p">,</span> <span class="p">)</span> |
| <span class="p">)</span> |
| <span class="k">if</span> <span class="n">value</span> <span class="o"><</span> <span class="mi">0</span><span class="p">:</span> |
| <span class="n">neg_value</span> <span class="o">=</span> <span class="n">value</span> |
| <span class="n">value</span> <span class="o">=</span> <span class="n">all_bits</span> <span class="o">+</span> <span class="mi">1</span> <span class="o">+</span> <span class="n">value</span> |
| <span class="c1"># get members and unknown</span> |
| <span class="n">unknown</span> <span class="o">=</span> <span class="n">value</span> <span class="o">&</span> <span class="o">~</span><span class="n">flag_mask</span> |
| <span class="n">aliases</span> <span class="o">=</span> <span class="n">value</span> <span class="o">&</span> <span class="o">~</span><span class="n">singles_mask</span> |
| <span class="n">member_value</span> <span class="o">=</span> <span class="n">value</span> <span class="o">&</span> <span class="n">singles_mask</span> |
| <span class="k">if</span> <span class="n">unknown</span> <span class="ow">and</span> <span class="bp">cls</span><span class="o">.</span><span class="n">_boundary_</span> <span class="ow">is</span> <span class="ow">not</span> <span class="n">KEEP</span><span class="p">:</span> |
| <span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span> |
| <span class="s1">'</span><span class="si">%s</span><span class="s1">(</span><span class="si">%r</span><span class="s1">) --> unknown values </span><span class="si">%r</span><span class="s1"> [</span><span class="si">%s</span><span class="s1">]'</span> |
| <span class="o">%</span> <span class="p">(</span><span class="bp">cls</span><span class="o">.</span><span class="vm">__name__</span><span class="p">,</span> <span class="n">value</span><span class="p">,</span> <span class="n">unknown</span><span class="p">,</span> <span class="nb">bin</span><span class="p">(</span><span class="n">unknown</span><span class="p">))</span> |
| <span class="p">)</span> |
| <span class="c1"># normal Flag?</span> |
| <span class="k">if</span> <span class="bp">cls</span><span class="o">.</span><span class="n">_member_type_</span> <span class="ow">is</span> <span class="nb">object</span><span class="p">:</span> |
| <span class="c1"># construct a singleton enum pseudo-member</span> |
| <span class="n">pseudo_member</span> <span class="o">=</span> <span class="nb">object</span><span class="o">.</span><span class="fm">__new__</span><span class="p">(</span><span class="bp">cls</span><span class="p">)</span> |
| <span class="k">else</span><span class="p">:</span> |
| <span class="n">pseudo_member</span> <span class="o">=</span> <span class="bp">cls</span><span class="o">.</span><span class="n">_member_type_</span><span class="o">.</span><span class="fm">__new__</span><span class="p">(</span><span class="bp">cls</span><span class="p">,</span> <span class="n">value</span><span class="p">)</span> |
| <span class="k">if</span> <span class="ow">not</span> <span class="nb">hasattr</span><span class="p">(</span><span class="n">pseudo_member</span><span class="p">,</span> <span class="s1">'_value_'</span><span class="p">):</span> |
| <span class="n">pseudo_member</span><span class="o">.</span><span class="n">_value_</span> <span class="o">=</span> <span class="n">value</span> |
| <span class="k">if</span> <span class="n">member_value</span> <span class="ow">or</span> <span class="n">aliases</span><span class="p">:</span> |
| <span class="n">members</span> <span class="o">=</span> <span class="p">[]</span> |
| <span class="n">combined_value</span> <span class="o">=</span> <span class="mi">0</span> |
| <span class="k">for</span> <span class="n">m</span> <span class="ow">in</span> <span class="bp">cls</span><span class="o">.</span><span class="n">_iter_member_</span><span class="p">(</span><span class="n">member_value</span><span class="p">):</span> |
| <span class="n">members</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">m</span><span class="p">)</span> |
| <span class="n">combined_value</span> <span class="o">|=</span> <span class="n">m</span><span class="o">.</span><span class="n">_value_</span> |
| <span class="k">if</span> <span class="n">aliases</span><span class="p">:</span> |
| <span class="n">value</span> <span class="o">=</span> <span class="n">member_value</span> <span class="o">|</span> <span class="n">aliases</span> |
| <span class="k">for</span> <span class="n">n</span><span class="p">,</span> <span class="n">pm</span> <span class="ow">in</span> <span class="bp">cls</span><span class="o">.</span><span class="n">_member_map_</span><span class="o">.</span><span class="n">items</span><span class="p">():</span> |
| <span class="k">if</span> <span class="n">pm</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">members</span> <span class="ow">and</span> <span class="n">pm</span><span class="o">.</span><span class="n">_value_</span> <span class="ow">and</span> <span class="n">pm</span><span class="o">.</span><span class="n">_value_</span> <span class="o">&</span> <span class="n">value</span> <span class="o">==</span> <span class="n">pm</span><span class="o">.</span><span class="n">_value_</span><span class="p">:</span> |
| <span class="n">members</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">pm</span><span class="p">)</span> |
| <span class="n">combined_value</span> <span class="o">|=</span> <span class="n">pm</span><span class="o">.</span><span class="n">_value_</span> |
| <span class="n">unknown</span> <span class="o">=</span> <span class="n">value</span> <span class="o">^</span> <span class="n">combined_value</span> |
| <span class="n">pseudo_member</span><span class="o">.</span><span class="n">_name_</span> <span class="o">=</span> <span class="s1">'|'</span><span class="o">.</span><span class="n">join</span><span class="p">([</span><span class="n">m</span><span class="o">.</span><span class="n">_name_</span> <span class="k">for</span> <span class="n">m</span> <span class="ow">in</span> <span class="n">members</span><span class="p">])</span> |
| <span class="k">if</span> <span class="ow">not</span> <span class="n">combined_value</span><span class="p">:</span> |
| <span class="n">pseudo_member</span><span class="o">.</span><span class="n">_name_</span> <span class="o">=</span> <span class="kc">None</span> |
| <span class="k">elif</span> <span class="n">unknown</span> <span class="ow">and</span> <span class="bp">cls</span><span class="o">.</span><span class="n">_boundary_</span> <span class="ow">is</span> <span class="n">STRICT</span><span class="p">:</span> |
| <span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="s1">'</span><span class="si">%r</span><span class="s1">: no members with value </span><span class="si">%r</span><span class="s1">'</span> <span class="o">%</span> <span class="p">(</span><span class="bp">cls</span><span class="p">,</span> <span class="n">unknown</span><span class="p">))</span> |
| <span class="k">elif</span> <span class="n">unknown</span><span class="p">:</span> |
| <span class="n">pseudo_member</span><span class="o">.</span><span class="n">_name_</span> <span class="o">+=</span> <span class="s1">'|</span><span class="si">%s</span><span class="s1">'</span> <span class="o">%</span> <span class="bp">cls</span><span class="o">.</span><span class="n">_numeric_repr_</span><span class="p">(</span><span class="n">unknown</span><span class="p">)</span> |
| <span class="k">else</span><span class="p">:</span> |
| <span class="n">pseudo_member</span><span class="o">.</span><span class="n">_name_</span> <span class="o">=</span> <span class="kc">None</span> |
| <span class="c1"># use setdefault in case another thread already created a composite</span> |
| <span class="c1"># with this value</span> |
| <span class="c1"># note: zero is a special case -- always add it</span> |
| <span class="n">pseudo_member</span> <span class="o">=</span> <span class="bp">cls</span><span class="o">.</span><span class="n">_value2member_map_</span><span class="o">.</span><span class="n">setdefault</span><span class="p">(</span><span class="n">value</span><span class="p">,</span> <span class="n">pseudo_member</span><span class="p">)</span> |
| <span class="k">if</span> <span class="n">neg_value</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span> |
| <span class="bp">cls</span><span class="o">.</span><span class="n">_value2member_map_</span><span class="p">[</span><span class="n">neg_value</span><span class="p">]</span> <span class="o">=</span> <span class="n">pseudo_member</span> |
| <span class="k">return</span> <span class="n">pseudo_member</span> |
| |
| <span class="k">def</span><span class="w"> </span><span class="fm">__contains__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">other</span><span class="p">):</span> |
| <span class="w"> </span><span class="sd">"""</span> |
| <span class="sd"> Returns True if self has at least the same flags set as other.</span> |
| <span class="sd"> """</span> |
| <span class="k">if</span> <span class="ow">not</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">other</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="vm">__class__</span><span class="p">):</span> |
| <span class="k">raise</span> <span class="ne">TypeError</span><span class="p">(</span> |
| <span class="s2">"unsupported operand type(s) for 'in': </span><span class="si">%r</span><span class="s2"> and </span><span class="si">%r</span><span class="s2">"</span> <span class="o">%</span> <span class="p">(</span> |
| <span class="nb">type</span><span class="p">(</span><span class="n">other</span><span class="p">)</span><span class="o">.</span><span class="vm">__qualname__</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="vm">__class__</span><span class="o">.</span><span class="vm">__qualname__</span><span class="p">))</span> |
| <span class="k">return</span> <span class="n">other</span><span class="o">.</span><span class="n">_value_</span> <span class="o">&</span> <span class="bp">self</span><span class="o">.</span><span class="n">_value_</span> <span class="o">==</span> <span class="n">other</span><span class="o">.</span><span class="n">_value_</span> |
| |
| <span class="k">def</span><span class="w"> </span><span class="fm">__iter__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span> |
| <span class="w"> </span><span class="sd">"""</span> |
| <span class="sd"> Returns flags in definition order.</span> |
| <span class="sd"> """</span> |
| <span class="k">yield from</span> <span class="bp">self</span><span class="o">.</span><span class="n">_iter_member_</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_value_</span><span class="p">)</span> |
| |
| <span class="k">def</span><span class="w"> </span><span class="fm">__len__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span> |
| <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_value_</span><span class="o">.</span><span class="n">bit_count</span><span class="p">()</span> |
| |
| <span class="k">def</span><span class="w"> </span><span class="fm">__repr__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span> |
| <span class="n">cls_name</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="vm">__class__</span><span class="o">.</span><span class="vm">__name__</span> |
| <span class="n">v_repr</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="vm">__class__</span><span class="o">.</span><span class="n">_value_repr_</span> <span class="ow">or</span> <span class="nb">repr</span> |
| <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">_name_</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span> |
| <span class="k">return</span> <span class="s2">"<</span><span class="si">%s</span><span class="s2">: </span><span class="si">%s</span><span class="s2">>"</span> <span class="o">%</span> <span class="p">(</span><span class="n">cls_name</span><span class="p">,</span> <span class="n">v_repr</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_value_</span><span class="p">))</span> |
| <span class="k">else</span><span class="p">:</span> |
| <span class="k">return</span> <span class="s2">"<</span><span class="si">%s</span><span class="s2">.</span><span class="si">%s</span><span class="s2">: </span><span class="si">%s</span><span class="s2">>"</span> <span class="o">%</span> <span class="p">(</span><span class="n">cls_name</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">_name_</span><span class="p">,</span> <span class="n">v_repr</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_value_</span><span class="p">))</span> |
| |
| <span class="k">def</span><span class="w"> </span><span class="fm">__str__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span> |
| <span class="n">cls_name</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="vm">__class__</span><span class="o">.</span><span class="vm">__name__</span> |
| <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">_name_</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span> |
| <span class="k">return</span> <span class="s1">'</span><span class="si">%s</span><span class="s1">(</span><span class="si">%r</span><span class="s1">)'</span> <span class="o">%</span> <span class="p">(</span><span class="n">cls_name</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">_value_</span><span class="p">)</span> |
| <span class="k">else</span><span class="p">:</span> |
| <span class="k">return</span> <span class="s2">"</span><span class="si">%s</span><span class="s2">.</span><span class="si">%s</span><span class="s2">"</span> <span class="o">%</span> <span class="p">(</span><span class="n">cls_name</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">_name_</span><span class="p">)</span> |
| |
| <span class="k">def</span><span class="w"> </span><span class="fm">__bool__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span> |
| <span class="k">return</span> <span class="nb">bool</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_value_</span><span class="p">)</span> |
| |
| <span class="k">def</span><span class="w"> </span><span class="nf">_get_value</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">flag</span><span class="p">):</span> |
| <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">flag</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="vm">__class__</span><span class="p">):</span> |
| <span class="k">return</span> <span class="n">flag</span><span class="o">.</span><span class="n">_value_</span> |
| <span class="k">elif</span> <span class="bp">self</span><span class="o">.</span><span class="n">_member_type_</span> <span class="ow">is</span> <span class="ow">not</span> <span class="nb">object</span> <span class="ow">and</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">flag</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">_member_type_</span><span class="p">):</span> |
| <span class="k">return</span> <span class="n">flag</span> |
| <span class="k">return</span> <span class="bp">NotImplemented</span> |
| |
| <span class="k">def</span><span class="w"> </span><span class="fm">__or__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">other</span><span class="p">):</span> |
| <span class="n">other_value</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_get_value</span><span class="p">(</span><span class="n">other</span><span class="p">)</span> |
| <span class="k">if</span> <span class="n">other_value</span> <span class="ow">is</span> <span class="bp">NotImplemented</span><span class="p">:</span> |
| <span class="k">return</span> <span class="bp">NotImplemented</span> |
| |
| <span class="k">for</span> <span class="n">flag</span> <span class="ow">in</span> <span class="bp">self</span><span class="p">,</span> <span class="n">other</span><span class="p">:</span> |
| <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">_get_value</span><span class="p">(</span><span class="n">flag</span><span class="p">)</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span> |
| <span class="k">raise</span> <span class="ne">TypeError</span><span class="p">(</span><span class="sa">f</span><span class="s2">"'</span><span class="si">{</span><span class="n">flag</span><span class="si">}</span><span class="s2">' cannot be combined with other flags with |"</span><span class="p">)</span> |
| <span class="n">value</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_value_</span> |
| <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="vm">__class__</span><span class="p">(</span><span class="n">value</span> <span class="o">|</span> <span class="n">other_value</span><span class="p">)</span> |
| |
| <span class="k">def</span><span class="w"> </span><span class="fm">__and__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">other</span><span class="p">):</span> |
| <span class="n">other_value</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_get_value</span><span class="p">(</span><span class="n">other</span><span class="p">)</span> |
| <span class="k">if</span> <span class="n">other_value</span> <span class="ow">is</span> <span class="bp">NotImplemented</span><span class="p">:</span> |
| <span class="k">return</span> <span class="bp">NotImplemented</span> |
| |
| <span class="k">for</span> <span class="n">flag</span> <span class="ow">in</span> <span class="bp">self</span><span class="p">,</span> <span class="n">other</span><span class="p">:</span> |
| <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">_get_value</span><span class="p">(</span><span class="n">flag</span><span class="p">)</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span> |
| <span class="k">raise</span> <span class="ne">TypeError</span><span class="p">(</span><span class="sa">f</span><span class="s2">"'</span><span class="si">{</span><span class="n">flag</span><span class="si">}</span><span class="s2">' cannot be combined with other flags with &"</span><span class="p">)</span> |
| <span class="n">value</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_value_</span> |
| <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="vm">__class__</span><span class="p">(</span><span class="n">value</span> <span class="o">&</span> <span class="n">other_value</span><span class="p">)</span> |
| |
| <span class="k">def</span><span class="w"> </span><span class="fm">__xor__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">other</span><span class="p">):</span> |
| <span class="n">other_value</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_get_value</span><span class="p">(</span><span class="n">other</span><span class="p">)</span> |
| <span class="k">if</span> <span class="n">other_value</span> <span class="ow">is</span> <span class="bp">NotImplemented</span><span class="p">:</span> |
| <span class="k">return</span> <span class="bp">NotImplemented</span> |
| |
| <span class="k">for</span> <span class="n">flag</span> <span class="ow">in</span> <span class="bp">self</span><span class="p">,</span> <span class="n">other</span><span class="p">:</span> |
| <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">_get_value</span><span class="p">(</span><span class="n">flag</span><span class="p">)</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span> |
| <span class="k">raise</span> <span class="ne">TypeError</span><span class="p">(</span><span class="sa">f</span><span class="s2">"'</span><span class="si">{</span><span class="n">flag</span><span class="si">}</span><span class="s2">' cannot be combined with other flags with ^"</span><span class="p">)</span> |
| <span class="n">value</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_value_</span> |
| <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="vm">__class__</span><span class="p">(</span><span class="n">value</span> <span class="o">^</span> <span class="n">other_value</span><span class="p">)</span> |
| |
| <span class="k">def</span><span class="w"> </span><span class="fm">__invert__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span> |
| <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">_get_value</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span> |
| <span class="k">raise</span> <span class="ne">TypeError</span><span class="p">(</span><span class="sa">f</span><span class="s2">"'</span><span class="si">{</span><span class="bp">self</span><span class="si">}</span><span class="s2">' cannot be inverted"</span><span class="p">)</span> |
| |
| <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">_inverted_</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span> |
| <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">_boundary_</span> <span class="ow">in</span> <span class="p">(</span><span class="n">EJECT</span><span class="p">,</span> <span class="n">KEEP</span><span class="p">):</span> |
| <span class="bp">self</span><span class="o">.</span><span class="n">_inverted_</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="vm">__class__</span><span class="p">(</span><span class="o">~</span><span class="bp">self</span><span class="o">.</span><span class="n">_value_</span><span class="p">)</span> |
| <span class="k">else</span><span class="p">:</span> |
| <span class="bp">self</span><span class="o">.</span><span class="n">_inverted_</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="vm">__class__</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_singles_mask_</span> <span class="o">&</span> <span class="o">~</span><span class="bp">self</span><span class="o">.</span><span class="n">_value_</span><span class="p">)</span> |
| <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_inverted_</span> |
| |
| <span class="fm">__rand__</span> <span class="o">=</span> <span class="fm">__and__</span> |
| <span class="fm">__ror__</span> <span class="o">=</span> <span class="fm">__or__</span> |
| <span class="fm">__rxor__</span> <span class="o">=</span> <span class="fm">__xor__</span> |
| |
| |
| <span class="k">class</span><span class="w"> </span><span class="nc">IntFlag</span><span class="p">(</span><span class="nb">int</span><span class="p">,</span> <span class="n">ReprEnum</span><span class="p">,</span> <span class="n">Flag</span><span class="p">,</span> <span class="n">boundary</span><span class="o">=</span><span class="n">KEEP</span><span class="p">):</span> |
| <span class="w"> </span><span class="sd">"""</span> |
| <span class="sd"> Support for integer-based Flags</span> |
| <span class="sd"> """</span> |
| |
| |
| <span class="k">def</span><span class="w"> </span><span class="nf">_high_bit</span><span class="p">(</span><span class="n">value</span><span class="p">):</span> |
| <span class="w"> </span><span class="sd">"""</span> |
| <span class="sd"> returns index of highest bit, or -1 if value is zero or negative</span> |
| <span class="sd"> """</span> |
| <span class="k">return</span> <span class="n">value</span><span class="o">.</span><span class="n">bit_length</span><span class="p">()</span> <span class="o">-</span> <span class="mi">1</span> |
| |
| <span class="k">def</span><span class="w"> </span><span class="nf">unique</span><span class="p">(</span><span class="n">enumeration</span><span class="p">):</span> |
| <span class="w"> </span><span class="sd">"""</span> |
| <span class="sd"> Class decorator for enumerations ensuring unique member values.</span> |
| <span class="sd"> """</span> |
| <span class="n">duplicates</span> <span class="o">=</span> <span class="p">[]</span> |
| <span class="k">for</span> <span class="n">name</span><span class="p">,</span> <span class="n">member</span> <span class="ow">in</span> <span class="n">enumeration</span><span class="o">.</span><span class="n">__members__</span><span class="o">.</span><span class="n">items</span><span class="p">():</span> |
| <span class="k">if</span> <span class="n">name</span> <span class="o">!=</span> <span class="n">member</span><span class="o">.</span><span class="n">name</span><span class="p">:</span> |
| <span class="n">duplicates</span><span class="o">.</span><span class="n">append</span><span class="p">((</span><span class="n">name</span><span class="p">,</span> <span class="n">member</span><span class="o">.</span><span class="n">name</span><span class="p">))</span> |
| <span class="k">if</span> <span class="n">duplicates</span><span class="p">:</span> |
| <span class="n">alias_details</span> <span class="o">=</span> <span class="s1">', '</span><span class="o">.</span><span class="n">join</span><span class="p">(</span> |
| <span class="p">[</span><span class="s2">"</span><span class="si">%s</span><span class="s2"> -> </span><span class="si">%s</span><span class="s2">"</span> <span class="o">%</span> <span class="p">(</span><span class="n">alias</span><span class="p">,</span> <span class="n">name</span><span class="p">)</span> <span class="k">for</span> <span class="p">(</span><span class="n">alias</span><span class="p">,</span> <span class="n">name</span><span class="p">)</span> <span class="ow">in</span> <span class="n">duplicates</span><span class="p">])</span> |
| <span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="s1">'duplicate values found in </span><span class="si">%r</span><span class="s1">: </span><span class="si">%s</span><span class="s1">'</span> <span class="o">%</span> |
| <span class="p">(</span><span class="n">enumeration</span><span class="p">,</span> <span class="n">alias_details</span><span class="p">))</span> |
| <span class="k">return</span> <span class="n">enumeration</span> |
| |
| <span class="k">def</span><span class="w"> </span><span class="nf">_dataclass_repr</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span> |
| <span class="n">dcf</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">__dataclass_fields__</span> |
| <span class="k">return</span> <span class="s1">', '</span><span class="o">.</span><span class="n">join</span><span class="p">(</span> |
| <span class="s1">'</span><span class="si">%s</span><span class="s1">=</span><span class="si">%r</span><span class="s1">'</span> <span class="o">%</span> <span class="p">(</span><span class="n">k</span><span class="p">,</span> <span class="nb">getattr</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">k</span><span class="p">))</span> |
| <span class="k">for</span> <span class="n">k</span> <span class="ow">in</span> <span class="n">dcf</span><span class="o">.</span><span class="n">keys</span><span class="p">()</span> |
| <span class="k">if</span> <span class="n">dcf</span><span class="p">[</span><span class="n">k</span><span class="p">]</span><span class="o">.</span><span class="n">repr</span> |
| <span class="p">)</span> |
| |
| <span class="k">def</span><span class="w"> </span><span class="nf">global_enum_repr</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span> |
| <span class="w"> </span><span class="sd">"""</span> |
| <span class="sd"> use module.enum_name instead of class.enum_name</span> |
| |
| <span class="sd"> the module is the last module in case of a multi-module name</span> |
| <span class="sd"> """</span> |
| <span class="n">module</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="vm">__class__</span><span class="o">.</span><span class="vm">__module__</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="s1">'.'</span><span class="p">)[</span><span class="o">-</span><span class="mi">1</span><span class="p">]</span> |
| <span class="k">return</span> <span class="s1">'</span><span class="si">%s</span><span class="s1">.</span><span class="si">%s</span><span class="s1">'</span> <span class="o">%</span> <span class="p">(</span><span class="n">module</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">_name_</span><span class="p">)</span> |
| |
| <span class="k">def</span><span class="w"> </span><span class="nf">global_flag_repr</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span> |
| <span class="w"> </span><span class="sd">"""</span> |
| <span class="sd"> use module.flag_name instead of class.flag_name</span> |
| |
| <span class="sd"> the module is the last module in case of a multi-module name</span> |
| <span class="sd"> """</span> |
| <span class="n">module</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="vm">__class__</span><span class="o">.</span><span class="vm">__module__</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="s1">'.'</span><span class="p">)[</span><span class="o">-</span><span class="mi">1</span><span class="p">]</span> |
| <span class="n">cls_name</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="vm">__class__</span><span class="o">.</span><span class="vm">__name__</span> |
| <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">_name_</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span> |
| <span class="k">return</span> <span class="s2">"</span><span class="si">%s</span><span class="s2">.</span><span class="si">%s</span><span class="s2">(</span><span class="si">%r</span><span class="s2">)"</span> <span class="o">%</span> <span class="p">(</span><span class="n">module</span><span class="p">,</span> <span class="n">cls_name</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">_value_</span><span class="p">)</span> |
| <span class="k">if</span> <span class="n">_is_single_bit</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_value_</span><span class="p">):</span> |
| <span class="k">return</span> <span class="s1">'</span><span class="si">%s</span><span class="s1">.</span><span class="si">%s</span><span class="s1">'</span> <span class="o">%</span> <span class="p">(</span><span class="n">module</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">_name_</span><span class="p">)</span> |
| <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">_boundary_</span> <span class="ow">is</span> <span class="ow">not</span> <span class="n">FlagBoundary</span><span class="o">.</span><span class="n">KEEP</span><span class="p">:</span> |
| <span class="k">return</span> <span class="s1">'|'</span><span class="o">.</span><span class="n">join</span><span class="p">([</span><span class="s1">'</span><span class="si">%s</span><span class="s1">.</span><span class="si">%s</span><span class="s1">'</span> <span class="o">%</span> <span class="p">(</span><span class="n">module</span><span class="p">,</span> <span class="n">name</span><span class="p">)</span> <span class="k">for</span> <span class="n">name</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">name</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="s1">'|'</span><span class="p">)])</span> |
| <span class="k">else</span><span class="p">:</span> |
| <span class="n">name</span> <span class="o">=</span> <span class="p">[]</span> |
| <span class="k">for</span> <span class="n">n</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">_name_</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="s1">'|'</span><span class="p">):</span> |
| <span class="k">if</span> <span class="n">n</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span><span class="o">.</span><span class="n">isdigit</span><span class="p">():</span> |
| <span class="n">name</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">n</span><span class="p">)</span> |
| <span class="k">else</span><span class="p">:</span> |
| <span class="n">name</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="s1">'</span><span class="si">%s</span><span class="s1">.</span><span class="si">%s</span><span class="s1">'</span> <span class="o">%</span> <span class="p">(</span><span class="n">module</span><span class="p">,</span> <span class="n">n</span><span class="p">))</span> |
| <span class="k">return</span> <span class="s1">'|'</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">name</span><span class="p">)</span> |
| |
| <span class="k">def</span><span class="w"> </span><span class="nf">global_str</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span> |
| <span class="w"> </span><span class="sd">"""</span> |
| <span class="sd"> use enum_name instead of class.enum_name</span> |
| <span class="sd"> """</span> |
| <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">_name_</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span> |
| <span class="n">cls_name</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="vm">__class__</span><span class="o">.</span><span class="vm">__name__</span> |
| <span class="k">return</span> <span class="s2">"</span><span class="si">%s</span><span class="s2">(</span><span class="si">%r</span><span class="s2">)"</span> <span class="o">%</span> <span class="p">(</span><span class="n">cls_name</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">_value_</span><span class="p">)</span> |
| <span class="k">else</span><span class="p">:</span> |
| <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_name_</span> |
| |
| <span class="k">def</span><span class="w"> </span><span class="nf">global_enum</span><span class="p">(</span><span class="bp">cls</span><span class="p">,</span> <span class="n">update_str</span><span class="o">=</span><span class="kc">False</span><span class="p">):</span> |
| <span class="w"> </span><span class="sd">"""</span> |
| <span class="sd"> decorator that makes the repr() of an enum member reference its module</span> |
| <span class="sd"> instead of its class; also exports all members to the enum's module's</span> |
| <span class="sd"> global namespace</span> |
| <span class="sd"> """</span> |
| <span class="k">if</span> <span class="nb">issubclass</span><span class="p">(</span><span class="bp">cls</span><span class="p">,</span> <span class="n">Flag</span><span class="p">):</span> |
| <span class="bp">cls</span><span class="o">.</span><span class="fm">__repr__</span> <span class="o">=</span> <span class="n">global_flag_repr</span> |
| <span class="k">else</span><span class="p">:</span> |
| <span class="bp">cls</span><span class="o">.</span><span class="fm">__repr__</span> <span class="o">=</span> <span class="n">global_enum_repr</span> |
| <span class="k">if</span> <span class="ow">not</span> <span class="nb">issubclass</span><span class="p">(</span><span class="bp">cls</span><span class="p">,</span> <span class="n">ReprEnum</span><span class="p">)</span> <span class="ow">or</span> <span class="n">update_str</span><span class="p">:</span> |
| <span class="bp">cls</span><span class="o">.</span><span class="fm">__str__</span> <span class="o">=</span> <span class="n">global_str</span> |
| <span class="n">sys</span><span class="o">.</span><span class="n">modules</span><span class="p">[</span><span class="bp">cls</span><span class="o">.</span><span class="vm">__module__</span><span class="p">]</span><span class="o">.</span><span class="vm">__dict__</span><span class="o">.</span><span class="n">update</span><span class="p">(</span><span class="bp">cls</span><span class="o">.</span><span class="n">__members__</span><span class="p">)</span> |
| <span class="k">return</span> <span class="bp">cls</span> |
| |
| <span class="k">def</span><span class="w"> </span><span class="nf">_simple_enum</span><span class="p">(</span><span class="n">etype</span><span class="o">=</span><span class="n">Enum</span><span class="p">,</span> <span class="o">*</span><span class="p">,</span> <span class="n">boundary</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">use_args</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span> |
| <span class="w"> </span><span class="sd">"""</span> |
| <span class="sd"> Class decorator that converts a normal class into an :class:`Enum`. No</span> |
| <span class="sd"> safety checks are done, and some advanced behavior (such as</span> |
| <span class="sd"> :func:`__init_subclass__`) is not available. Enum creation can be faster</span> |
| <span class="sd"> using :func:`_simple_enum`.</span> |
| |
| <span class="sd"> >>> from enum import Enum, _simple_enum</span> |
| <span class="sd"> >>> @_simple_enum(Enum)</span> |
| <span class="sd"> ... class Color:</span> |
| <span class="sd"> ... RED = auto()</span> |
| <span class="sd"> ... GREEN = auto()</span> |
| <span class="sd"> ... BLUE = auto()</span> |
| <span class="sd"> >>> Color</span> |
| <span class="sd"> <enum 'Color'></span> |
| <span class="sd"> """</span> |
| <span class="k">def</span><span class="w"> </span><span class="nf">convert_class</span><span class="p">(</span><span class="bp">cls</span><span class="p">):</span> |
| <span class="k">nonlocal</span> <span class="n">use_args</span> |
| <span class="n">cls_name</span> <span class="o">=</span> <span class="bp">cls</span><span class="o">.</span><span class="vm">__name__</span> |
| <span class="k">if</span> <span class="n">use_args</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span> |
| <span class="n">use_args</span> <span class="o">=</span> <span class="n">etype</span><span class="o">.</span><span class="n">_use_args_</span> |
| <span class="fm">__new__</span> <span class="o">=</span> <span class="bp">cls</span><span class="o">.</span><span class="vm">__dict__</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s1">'__new__'</span><span class="p">)</span> |
| <span class="k">if</span> <span class="fm">__new__</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span> |
| <span class="n">new_member</span> <span class="o">=</span> <span class="fm">__new__</span><span class="o">.</span><span class="vm">__func__</span> |
| <span class="k">else</span><span class="p">:</span> |
| <span class="n">new_member</span> <span class="o">=</span> <span class="n">etype</span><span class="o">.</span><span class="n">_member_type_</span><span class="o">.</span><span class="fm">__new__</span> |
| <span class="n">attrs</span> <span class="o">=</span> <span class="p">{}</span> |
| <span class="n">body</span> <span class="o">=</span> <span class="p">{}</span> |
| <span class="k">if</span> <span class="fm">__new__</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span> |
| <span class="n">body</span><span class="p">[</span><span class="s1">'__new_member__'</span><span class="p">]</span> <span class="o">=</span> <span class="n">new_member</span> |
| <span class="n">body</span><span class="p">[</span><span class="s1">'_new_member_'</span><span class="p">]</span> <span class="o">=</span> <span class="n">new_member</span> |
| <span class="n">body</span><span class="p">[</span><span class="s1">'_use_args_'</span><span class="p">]</span> <span class="o">=</span> <span class="n">use_args</span> |
| <span class="n">body</span><span class="p">[</span><span class="s1">'_generate_next_value_'</span><span class="p">]</span> <span class="o">=</span> <span class="n">gnv</span> <span class="o">=</span> <span class="n">etype</span><span class="o">.</span><span class="n">_generate_next_value_</span> |
| <span class="n">body</span><span class="p">[</span><span class="s1">'_member_names_'</span><span class="p">]</span> <span class="o">=</span> <span class="n">member_names</span> <span class="o">=</span> <span class="p">[]</span> |
| <span class="n">body</span><span class="p">[</span><span class="s1">'_member_map_'</span><span class="p">]</span> <span class="o">=</span> <span class="n">member_map</span> <span class="o">=</span> <span class="p">{}</span> |
| <span class="n">body</span><span class="p">[</span><span class="s1">'_value2member_map_'</span><span class="p">]</span> <span class="o">=</span> <span class="n">value2member_map</span> <span class="o">=</span> <span class="p">{}</span> |
| <span class="n">body</span><span class="p">[</span><span class="s1">'_hashable_values_'</span><span class="p">]</span> <span class="o">=</span> <span class="n">hashable_values</span> <span class="o">=</span> <span class="p">[]</span> |
| <span class="n">body</span><span class="p">[</span><span class="s1">'_unhashable_values_'</span><span class="p">]</span> <span class="o">=</span> <span class="n">unhashable_values</span> <span class="o">=</span> <span class="p">[]</span> |
| <span class="n">body</span><span class="p">[</span><span class="s1">'_unhashable_values_map_'</span><span class="p">]</span> <span class="o">=</span> <span class="p">{}</span> |
| <span class="n">body</span><span class="p">[</span><span class="s1">'_member_type_'</span><span class="p">]</span> <span class="o">=</span> <span class="n">member_type</span> <span class="o">=</span> <span class="n">etype</span><span class="o">.</span><span class="n">_member_type_</span> |
| <span class="n">body</span><span class="p">[</span><span class="s1">'_value_repr_'</span><span class="p">]</span> <span class="o">=</span> <span class="n">etype</span><span class="o">.</span><span class="n">_value_repr_</span> |
| <span class="k">if</span> <span class="nb">issubclass</span><span class="p">(</span><span class="n">etype</span><span class="p">,</span> <span class="n">Flag</span><span class="p">):</span> |
| <span class="n">body</span><span class="p">[</span><span class="s1">'_boundary_'</span><span class="p">]</span> <span class="o">=</span> <span class="n">boundary</span> <span class="ow">or</span> <span class="n">etype</span><span class="o">.</span><span class="n">_boundary_</span> |
| <span class="n">body</span><span class="p">[</span><span class="s1">'_flag_mask_'</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span> |
| <span class="n">body</span><span class="p">[</span><span class="s1">'_all_bits_'</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span> |
| <span class="n">body</span><span class="p">[</span><span class="s1">'_singles_mask_'</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span> |
| <span class="n">body</span><span class="p">[</span><span class="s1">'_inverted_'</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span> |
| <span class="n">body</span><span class="p">[</span><span class="s1">'__or__'</span><span class="p">]</span> <span class="o">=</span> <span class="n">Flag</span><span class="o">.</span><span class="fm">__or__</span> |
| <span class="n">body</span><span class="p">[</span><span class="s1">'__xor__'</span><span class="p">]</span> <span class="o">=</span> <span class="n">Flag</span><span class="o">.</span><span class="fm">__xor__</span> |
| <span class="n">body</span><span class="p">[</span><span class="s1">'__and__'</span><span class="p">]</span> <span class="o">=</span> <span class="n">Flag</span><span class="o">.</span><span class="fm">__and__</span> |
| <span class="n">body</span><span class="p">[</span><span class="s1">'__ror__'</span><span class="p">]</span> <span class="o">=</span> <span class="n">Flag</span><span class="o">.</span><span class="fm">__ror__</span> |
| <span class="n">body</span><span class="p">[</span><span class="s1">'__rxor__'</span><span class="p">]</span> <span class="o">=</span> <span class="n">Flag</span><span class="o">.</span><span class="fm">__rxor__</span> |
| <span class="n">body</span><span class="p">[</span><span class="s1">'__rand__'</span><span class="p">]</span> <span class="o">=</span> <span class="n">Flag</span><span class="o">.</span><span class="fm">__rand__</span> |
| <span class="n">body</span><span class="p">[</span><span class="s1">'__invert__'</span><span class="p">]</span> <span class="o">=</span> <span class="n">Flag</span><span class="o">.</span><span class="fm">__invert__</span> |
| <span class="k">for</span> <span class="n">name</span><span class="p">,</span> <span class="n">obj</span> <span class="ow">in</span> <span class="bp">cls</span><span class="o">.</span><span class="vm">__dict__</span><span class="o">.</span><span class="n">items</span><span class="p">():</span> |
| <span class="k">if</span> <span class="n">name</span> <span class="ow">in</span> <span class="p">(</span><span class="s1">'__dict__'</span><span class="p">,</span> <span class="s1">'__weakref__'</span><span class="p">):</span> |
| <span class="k">continue</span> |
| <span class="k">if</span> <span class="n">_is_dunder</span><span class="p">(</span><span class="n">name</span><span class="p">)</span> <span class="ow">or</span> <span class="n">_is_private</span><span class="p">(</span><span class="n">cls_name</span><span class="p">,</span> <span class="n">name</span><span class="p">)</span> <span class="ow">or</span> <span class="n">_is_sunder</span><span class="p">(</span><span class="n">name</span><span class="p">)</span> <span class="ow">or</span> <span class="n">_is_descriptor</span><span class="p">(</span><span class="n">obj</span><span class="p">):</span> |
| <span class="n">body</span><span class="p">[</span><span class="n">name</span><span class="p">]</span> <span class="o">=</span> <span class="n">obj</span> |
| <span class="k">else</span><span class="p">:</span> |
| <span class="n">attrs</span><span class="p">[</span><span class="n">name</span><span class="p">]</span> <span class="o">=</span> <span class="n">obj</span> |
| <span class="k">if</span> <span class="bp">cls</span><span class="o">.</span><span class="vm">__dict__</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s1">'__doc__'</span><span class="p">)</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span> |
| <span class="n">body</span><span class="p">[</span><span class="s1">'__doc__'</span><span class="p">]</span> <span class="o">=</span> <span class="s1">'An enumeration.'</span> |
| <span class="c1">#</span> |
| <span class="c1"># double check that repr and friends are not the mixin's or various</span> |
| <span class="c1"># things break (such as pickle)</span> |
| <span class="c1"># however, if the method is defined in the Enum itself, don't replace</span> |
| <span class="c1"># it</span> |
| <span class="n">enum_class</span> <span class="o">=</span> <span class="nb">type</span><span class="p">(</span><span class="n">cls_name</span><span class="p">,</span> <span class="p">(</span><span class="n">etype</span><span class="p">,</span> <span class="p">),</span> <span class="n">body</span><span class="p">,</span> <span class="n">boundary</span><span class="o">=</span><span class="n">boundary</span><span class="p">,</span> <span class="n">_simple</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span> |
| <span class="k">for</span> <span class="n">name</span> <span class="ow">in</span> <span class="p">(</span><span class="s1">'__repr__'</span><span class="p">,</span> <span class="s1">'__str__'</span><span class="p">,</span> <span class="s1">'__format__'</span><span class="p">,</span> <span class="s1">'__reduce_ex__'</span><span class="p">):</span> |
| <span class="k">if</span> <span class="n">name</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">body</span><span class="p">:</span> |
| <span class="c1"># check for mixin overrides before replacing</span> |
| <span class="n">enum_method</span> <span class="o">=</span> <span class="nb">getattr</span><span class="p">(</span><span class="n">etype</span><span class="p">,</span> <span class="n">name</span><span class="p">)</span> |
| <span class="n">found_method</span> <span class="o">=</span> <span class="nb">getattr</span><span class="p">(</span><span class="n">enum_class</span><span class="p">,</span> <span class="n">name</span><span class="p">)</span> |
| <span class="n">object_method</span> <span class="o">=</span> <span class="nb">getattr</span><span class="p">(</span><span class="nb">object</span><span class="p">,</span> <span class="n">name</span><span class="p">)</span> |
| <span class="n">data_type_method</span> <span class="o">=</span> <span class="nb">getattr</span><span class="p">(</span><span class="n">member_type</span><span class="p">,</span> <span class="n">name</span><span class="p">)</span> |
| <span class="k">if</span> <span class="n">found_method</span> <span class="ow">in</span> <span class="p">(</span><span class="n">data_type_method</span><span class="p">,</span> <span class="n">object_method</span><span class="p">):</span> |
| <span class="nb">setattr</span><span class="p">(</span><span class="n">enum_class</span><span class="p">,</span> <span class="n">name</span><span class="p">,</span> <span class="n">enum_method</span><span class="p">)</span> |
| <span class="n">gnv_last_values</span> <span class="o">=</span> <span class="p">[]</span> |
| <span class="k">if</span> <span class="nb">issubclass</span><span class="p">(</span><span class="n">enum_class</span><span class="p">,</span> <span class="n">Flag</span><span class="p">):</span> |
| <span class="c1"># Flag / IntFlag</span> |
| <span class="n">single_bits</span> <span class="o">=</span> <span class="n">multi_bits</span> <span class="o">=</span> <span class="mi">0</span> |
| <span class="k">for</span> <span class="n">name</span><span class="p">,</span> <span class="n">value</span> <span class="ow">in</span> <span class="n">attrs</span><span class="o">.</span><span class="n">items</span><span class="p">():</span> |
| <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">value</span><span class="p">,</span> <span class="n">auto</span><span class="p">)</span> <span class="ow">and</span> <span class="n">auto</span><span class="o">.</span><span class="n">value</span> <span class="ow">is</span> <span class="n">_auto_null</span><span class="p">:</span> |
| <span class="n">value</span> <span class="o">=</span> <span class="n">gnv</span><span class="p">(</span><span class="n">name</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="nb">len</span><span class="p">(</span><span class="n">member_names</span><span class="p">),</span> <span class="n">gnv_last_values</span><span class="p">)</span> |
| <span class="c1"># create basic member (possibly isolate value for alias check)</span> |
| <span class="k">if</span> <span class="n">use_args</span><span class="p">:</span> |
| <span class="k">if</span> <span class="ow">not</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">value</span><span class="p">,</span> <span class="nb">tuple</span><span class="p">):</span> |
| <span class="n">value</span> <span class="o">=</span> <span class="p">(</span><span class="n">value</span><span class="p">,</span> <span class="p">)</span> |
| <span class="n">member</span> <span class="o">=</span> <span class="n">new_member</span><span class="p">(</span><span class="n">enum_class</span><span class="p">,</span> <span class="o">*</span><span class="n">value</span><span class="p">)</span> |
| <span class="n">value</span> <span class="o">=</span> <span class="n">value</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> |
| <span class="k">else</span><span class="p">:</span> |
| <span class="n">member</span> <span class="o">=</span> <span class="n">new_member</span><span class="p">(</span><span class="n">enum_class</span><span class="p">)</span> |
| <span class="k">if</span> <span class="fm">__new__</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span> |
| <span class="n">member</span><span class="o">.</span><span class="n">_value_</span> <span class="o">=</span> <span class="n">value</span> |
| <span class="c1"># now check if alias</span> |
| <span class="k">try</span><span class="p">:</span> |
| <span class="n">contained</span> <span class="o">=</span> <span class="n">value2member_map</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="n">member</span><span class="o">.</span><span class="n">_value_</span><span class="p">)</span> |
| <span class="k">except</span> <span class="ne">TypeError</span><span class="p">:</span> |
| <span class="n">contained</span> <span class="o">=</span> <span class="kc">None</span> |
| <span class="k">if</span> <span class="n">member</span><span class="o">.</span><span class="n">_value_</span> <span class="ow">in</span> <span class="n">unhashable_values</span> <span class="ow">or</span> <span class="n">member</span><span class="o">.</span><span class="n">value</span> <span class="ow">in</span> <span class="n">hashable_values</span><span class="p">:</span> |
| <span class="k">for</span> <span class="n">m</span> <span class="ow">in</span> <span class="n">enum_class</span><span class="p">:</span> |
| <span class="k">if</span> <span class="n">m</span><span class="o">.</span><span class="n">_value_</span> <span class="o">==</span> <span class="n">member</span><span class="o">.</span><span class="n">_value_</span><span class="p">:</span> |
| <span class="n">contained</span> <span class="o">=</span> <span class="n">m</span> |
| <span class="k">break</span> |
| <span class="k">if</span> <span class="n">contained</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span> |
| <span class="c1"># an alias to an existing member</span> |
| <span class="n">contained</span><span class="o">.</span><span class="n">_add_alias_</span><span class="p">(</span><span class="n">name</span><span class="p">)</span> |
| <span class="k">else</span><span class="p">:</span> |
| <span class="c1"># finish creating member</span> |
| <span class="n">member</span><span class="o">.</span><span class="n">_name_</span> <span class="o">=</span> <span class="n">name</span> |
| <span class="n">member</span><span class="o">.</span><span class="vm">__objclass__</span> <span class="o">=</span> <span class="n">enum_class</span> |
| <span class="n">member</span><span class="o">.</span><span class="fm">__init__</span><span class="p">(</span><span class="n">value</span><span class="p">)</span> |
| <span class="n">member</span><span class="o">.</span><span class="n">_sort_order_</span> <span class="o">=</span> <span class="nb">len</span><span class="p">(</span><span class="n">member_names</span><span class="p">)</span> |
| <span class="k">if</span> <span class="n">name</span> <span class="ow">not</span> <span class="ow">in</span> <span class="p">(</span><span class="s1">'name'</span><span class="p">,</span> <span class="s1">'value'</span><span class="p">):</span> |
| <span class="nb">setattr</span><span class="p">(</span><span class="n">enum_class</span><span class="p">,</span> <span class="n">name</span><span class="p">,</span> <span class="n">member</span><span class="p">)</span> |
| <span class="n">member_map</span><span class="p">[</span><span class="n">name</span><span class="p">]</span> <span class="o">=</span> <span class="n">member</span> |
| <span class="k">else</span><span class="p">:</span> |
| <span class="n">enum_class</span><span class="o">.</span><span class="n">_add_member_</span><span class="p">(</span><span class="n">name</span><span class="p">,</span> <span class="n">member</span><span class="p">)</span> |
| <span class="n">value2member_map</span><span class="p">[</span><span class="n">value</span><span class="p">]</span> <span class="o">=</span> <span class="n">member</span> |
| <span class="n">hashable_values</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">value</span><span class="p">)</span> |
| <span class="k">if</span> <span class="n">_is_single_bit</span><span class="p">(</span><span class="n">value</span><span class="p">):</span> |
| <span class="c1"># not a multi-bit alias, record in _member_names_ and _flag_mask_</span> |
| <span class="n">member_names</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">name</span><span class="p">)</span> |
| <span class="n">single_bits</span> <span class="o">|=</span> <span class="n">value</span> |
| <span class="k">else</span><span class="p">:</span> |
| <span class="n">multi_bits</span> <span class="o">|=</span> <span class="n">value</span> |
| <span class="n">gnv_last_values</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">value</span><span class="p">)</span> |
| <span class="n">enum_class</span><span class="o">.</span><span class="n">_flag_mask_</span> <span class="o">=</span> <span class="n">single_bits</span> <span class="o">|</span> <span class="n">multi_bits</span> |
| <span class="n">enum_class</span><span class="o">.</span><span class="n">_singles_mask_</span> <span class="o">=</span> <span class="n">single_bits</span> |
| <span class="n">enum_class</span><span class="o">.</span><span class="n">_all_bits_</span> <span class="o">=</span> <span class="mi">2</span> <span class="o">**</span> <span class="p">((</span><span class="n">single_bits</span><span class="o">|</span><span class="n">multi_bits</span><span class="p">)</span><span class="o">.</span><span class="n">bit_length</span><span class="p">())</span> <span class="o">-</span> <span class="mi">1</span> |
| <span class="c1"># set correct __iter__</span> |
| <span class="n">member_list</span> <span class="o">=</span> <span class="p">[</span><span class="n">m</span><span class="o">.</span><span class="n">_value_</span> <span class="k">for</span> <span class="n">m</span> <span class="ow">in</span> <span class="n">enum_class</span><span class="p">]</span> |
| <span class="k">if</span> <span class="n">member_list</span> <span class="o">!=</span> <span class="nb">sorted</span><span class="p">(</span><span class="n">member_list</span><span class="p">):</span> |
| <span class="n">enum_class</span><span class="o">.</span><span class="n">_iter_member_</span> <span class="o">=</span> <span class="n">enum_class</span><span class="o">.</span><span class="n">_iter_member_by_def_</span> |
| <span class="k">else</span><span class="p">:</span> |
| <span class="c1"># Enum / IntEnum / StrEnum</span> |
| <span class="k">for</span> <span class="n">name</span><span class="p">,</span> <span class="n">value</span> <span class="ow">in</span> <span class="n">attrs</span><span class="o">.</span><span class="n">items</span><span class="p">():</span> |
| <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">value</span><span class="p">,</span> <span class="n">auto</span><span class="p">):</span> |
| <span class="k">if</span> <span class="n">value</span><span class="o">.</span><span class="n">value</span> <span class="ow">is</span> <span class="n">_auto_null</span><span class="p">:</span> |
| <span class="n">value</span><span class="o">.</span><span class="n">value</span> <span class="o">=</span> <span class="n">gnv</span><span class="p">(</span><span class="n">name</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="nb">len</span><span class="p">(</span><span class="n">member_names</span><span class="p">),</span> <span class="n">gnv_last_values</span><span class="p">)</span> |
| <span class="n">value</span> <span class="o">=</span> <span class="n">value</span><span class="o">.</span><span class="n">value</span> |
| <span class="c1"># create basic member (possibly isolate value for alias check)</span> |
| <span class="k">if</span> <span class="n">use_args</span><span class="p">:</span> |
| <span class="k">if</span> <span class="ow">not</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">value</span><span class="p">,</span> <span class="nb">tuple</span><span class="p">):</span> |
| <span class="n">value</span> <span class="o">=</span> <span class="p">(</span><span class="n">value</span><span class="p">,</span> <span class="p">)</span> |
| <span class="n">member</span> <span class="o">=</span> <span class="n">new_member</span><span class="p">(</span><span class="n">enum_class</span><span class="p">,</span> <span class="o">*</span><span class="n">value</span><span class="p">)</span> |
| <span class="n">value</span> <span class="o">=</span> <span class="n">value</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> |
| <span class="k">else</span><span class="p">:</span> |
| <span class="n">member</span> <span class="o">=</span> <span class="n">new_member</span><span class="p">(</span><span class="n">enum_class</span><span class="p">)</span> |
| <span class="k">if</span> <span class="fm">__new__</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span> |
| <span class="n">member</span><span class="o">.</span><span class="n">_value_</span> <span class="o">=</span> <span class="n">value</span> |
| <span class="c1"># now check if alias</span> |
| <span class="k">try</span><span class="p">:</span> |
| <span class="n">contained</span> <span class="o">=</span> <span class="n">value2member_map</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="n">member</span><span class="o">.</span><span class="n">_value_</span><span class="p">)</span> |
| <span class="k">except</span> <span class="ne">TypeError</span><span class="p">:</span> |
| <span class="n">contained</span> <span class="o">=</span> <span class="kc">None</span> |
| <span class="k">if</span> <span class="n">member</span><span class="o">.</span><span class="n">_value_</span> <span class="ow">in</span> <span class="n">unhashable_values</span> <span class="ow">or</span> <span class="n">member</span><span class="o">.</span><span class="n">_value_</span> <span class="ow">in</span> <span class="n">hashable_values</span><span class="p">:</span> |
| <span class="k">for</span> <span class="n">m</span> <span class="ow">in</span> <span class="n">enum_class</span><span class="p">:</span> |
| <span class="k">if</span> <span class="n">m</span><span class="o">.</span><span class="n">_value_</span> <span class="o">==</span> <span class="n">member</span><span class="o">.</span><span class="n">_value_</span><span class="p">:</span> |
| <span class="n">contained</span> <span class="o">=</span> <span class="n">m</span> |
| <span class="k">break</span> |
| <span class="k">if</span> <span class="n">contained</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span> |
| <span class="c1"># an alias to an existing member</span> |
| <span class="n">contained</span><span class="o">.</span><span class="n">_add_alias_</span><span class="p">(</span><span class="n">name</span><span class="p">)</span> |
| <span class="k">else</span><span class="p">:</span> |
| <span class="c1"># finish creating member</span> |
| <span class="n">member</span><span class="o">.</span><span class="n">_name_</span> <span class="o">=</span> <span class="n">name</span> |
| <span class="n">member</span><span class="o">.</span><span class="vm">__objclass__</span> <span class="o">=</span> <span class="n">enum_class</span> |
| <span class="n">member</span><span class="o">.</span><span class="fm">__init__</span><span class="p">(</span><span class="n">value</span><span class="p">)</span> |
| <span class="n">member</span><span class="o">.</span><span class="n">_sort_order_</span> <span class="o">=</span> <span class="nb">len</span><span class="p">(</span><span class="n">member_names</span><span class="p">)</span> |
| <span class="k">if</span> <span class="n">name</span> <span class="ow">not</span> <span class="ow">in</span> <span class="p">(</span><span class="s1">'name'</span><span class="p">,</span> <span class="s1">'value'</span><span class="p">):</span> |
| <span class="nb">setattr</span><span class="p">(</span><span class="n">enum_class</span><span class="p">,</span> <span class="n">name</span><span class="p">,</span> <span class="n">member</span><span class="p">)</span> |
| <span class="n">member_map</span><span class="p">[</span><span class="n">name</span><span class="p">]</span> <span class="o">=</span> <span class="n">member</span> |
| <span class="k">else</span><span class="p">:</span> |
| <span class="n">enum_class</span><span class="o">.</span><span class="n">_add_member_</span><span class="p">(</span><span class="n">name</span><span class="p">,</span> <span class="n">member</span><span class="p">)</span> |
| <span class="n">member_names</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">name</span><span class="p">)</span> |
| <span class="n">gnv_last_values</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">value</span><span class="p">)</span> |
| <span class="k">try</span><span class="p">:</span> |
| <span class="c1"># This may fail if value is not hashable. We can't add the value</span> |
| <span class="c1"># to the map, and by-value lookups for this value will be</span> |
| <span class="c1"># linear.</span> |
| <span class="n">enum_class</span><span class="o">.</span><span class="n">_value2member_map_</span><span class="o">.</span><span class="n">setdefault</span><span class="p">(</span><span class="n">value</span><span class="p">,</span> <span class="n">member</span><span class="p">)</span> |
| <span class="k">if</span> <span class="n">value</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">hashable_values</span><span class="p">:</span> |
| <span class="n">hashable_values</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">value</span><span class="p">)</span> |
| <span class="k">except</span> <span class="ne">TypeError</span><span class="p">:</span> |
| <span class="c1"># keep track of the value in a list so containment checks are quick</span> |
| <span class="n">enum_class</span><span class="o">.</span><span class="n">_unhashable_values_</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">value</span><span class="p">)</span> |
| <span class="n">enum_class</span><span class="o">.</span><span class="n">_unhashable_values_map_</span><span class="o">.</span><span class="n">setdefault</span><span class="p">(</span><span class="n">name</span><span class="p">,</span> <span class="p">[])</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">value</span><span class="p">)</span> |
| <span class="k">if</span> <span class="s1">'__new__'</span> <span class="ow">in</span> <span class="n">body</span><span class="p">:</span> |
| <span class="n">enum_class</span><span class="o">.</span><span class="n">__new_member__</span> <span class="o">=</span> <span class="n">enum_class</span><span class="o">.</span><span class="fm">__new__</span> |
| <span class="n">enum_class</span><span class="o">.</span><span class="fm">__new__</span> <span class="o">=</span> <span class="n">Enum</span><span class="o">.</span><span class="fm">__new__</span> |
| <span class="k">return</span> <span class="n">enum_class</span> |
| <span class="k">return</span> <span class="n">convert_class</span> |
| |
| <span class="nd">@_simple_enum</span><span class="p">(</span><span class="n">StrEnum</span><span class="p">)</span> |
| <span class="k">class</span><span class="w"> </span><span class="nc">EnumCheck</span><span class="p">:</span> |
| <span class="w"> </span><span class="sd">"""</span> |
| <span class="sd"> various conditions to check an enumeration for</span> |
| <span class="sd"> """</span> |
| <span class="n">CONTINUOUS</span> <span class="o">=</span> <span class="s2">"no skipped integer values"</span> |
| <span class="n">NAMED_FLAGS</span> <span class="o">=</span> <span class="s2">"multi-flag aliases may not contain unnamed flags"</span> |
| <span class="n">UNIQUE</span> <span class="o">=</span> <span class="s2">"one name per value"</span> |
| <span class="n">CONTINUOUS</span><span class="p">,</span> <span class="n">NAMED_FLAGS</span><span class="p">,</span> <span class="n">UNIQUE</span> <span class="o">=</span> <span class="n">EnumCheck</span> |
| |
| |
| <span class="k">class</span><span class="w"> </span><span class="nc">verify</span><span class="p">:</span> |
| <span class="w"> </span><span class="sd">"""</span> |
| <span class="sd"> Check an enumeration for various constraints. (see EnumCheck)</span> |
| <span class="sd"> """</span> |
| <span class="k">def</span><span class="w"> </span><span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="o">*</span><span class="n">checks</span><span class="p">):</span> |
| <span class="bp">self</span><span class="o">.</span><span class="n">checks</span> <span class="o">=</span> <span class="n">checks</span> |
| <span class="k">def</span><span class="w"> </span><span class="fm">__call__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">enumeration</span><span class="p">):</span> |
| <span class="n">checks</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">checks</span> |
| <span class="n">cls_name</span> <span class="o">=</span> <span class="n">enumeration</span><span class="o">.</span><span class="vm">__name__</span> |
| <span class="k">if</span> <span class="n">Flag</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span> <span class="ow">and</span> <span class="nb">issubclass</span><span class="p">(</span><span class="n">enumeration</span><span class="p">,</span> <span class="n">Flag</span><span class="p">):</span> |
| <span class="n">enum_type</span> <span class="o">=</span> <span class="s1">'flag'</span> |
| <span class="k">elif</span> <span class="nb">issubclass</span><span class="p">(</span><span class="n">enumeration</span><span class="p">,</span> <span class="n">Enum</span><span class="p">):</span> |
| <span class="n">enum_type</span> <span class="o">=</span> <span class="s1">'enum'</span> |
| <span class="k">else</span><span class="p">:</span> |
| <span class="k">raise</span> <span class="ne">TypeError</span><span class="p">(</span><span class="s2">"the 'verify' decorator only works with Enum and Flag"</span><span class="p">)</span> |
| <span class="k">for</span> <span class="n">check</span> <span class="ow">in</span> <span class="n">checks</span><span class="p">:</span> |
| <span class="k">if</span> <span class="n">check</span> <span class="ow">is</span> <span class="n">UNIQUE</span><span class="p">:</span> |
| <span class="c1"># check for duplicate names</span> |
| <span class="n">duplicates</span> <span class="o">=</span> <span class="p">[]</span> |
| <span class="k">for</span> <span class="n">name</span><span class="p">,</span> <span class="n">member</span> <span class="ow">in</span> <span class="n">enumeration</span><span class="o">.</span><span class="n">__members__</span><span class="o">.</span><span class="n">items</span><span class="p">():</span> |
| <span class="k">if</span> <span class="n">name</span> <span class="o">!=</span> <span class="n">member</span><span class="o">.</span><span class="n">name</span><span class="p">:</span> |
| <span class="n">duplicates</span><span class="o">.</span><span class="n">append</span><span class="p">((</span><span class="n">name</span><span class="p">,</span> <span class="n">member</span><span class="o">.</span><span class="n">name</span><span class="p">))</span> |
| <span class="k">if</span> <span class="n">duplicates</span><span class="p">:</span> |
| <span class="n">alias_details</span> <span class="o">=</span> <span class="s1">', '</span><span class="o">.</span><span class="n">join</span><span class="p">(</span> |
| <span class="p">[</span><span class="s2">"</span><span class="si">%s</span><span class="s2"> -> </span><span class="si">%s</span><span class="s2">"</span> <span class="o">%</span> <span class="p">(</span><span class="n">alias</span><span class="p">,</span> <span class="n">name</span><span class="p">)</span> <span class="k">for</span> <span class="p">(</span><span class="n">alias</span><span class="p">,</span> <span class="n">name</span><span class="p">)</span> <span class="ow">in</span> <span class="n">duplicates</span><span class="p">])</span> |
| <span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="s1">'aliases found in </span><span class="si">%r</span><span class="s1">: </span><span class="si">%s</span><span class="s1">'</span> <span class="o">%</span> |
| <span class="p">(</span><span class="n">enumeration</span><span class="p">,</span> <span class="n">alias_details</span><span class="p">))</span> |
| <span class="k">elif</span> <span class="n">check</span> <span class="ow">is</span> <span class="n">CONTINUOUS</span><span class="p">:</span> |
| <span class="n">values</span> <span class="o">=</span> <span class="nb">set</span><span class="p">(</span><span class="n">e</span><span class="o">.</span><span class="n">value</span> <span class="k">for</span> <span class="n">e</span> <span class="ow">in</span> <span class="n">enumeration</span><span class="p">)</span> |
| <span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">values</span><span class="p">)</span> <span class="o"><</span> <span class="mi">2</span><span class="p">:</span> |
| <span class="k">continue</span> |
| <span class="n">low</span><span class="p">,</span> <span class="n">high</span> <span class="o">=</span> <span class="nb">min</span><span class="p">(</span><span class="n">values</span><span class="p">),</span> <span class="nb">max</span><span class="p">(</span><span class="n">values</span><span class="p">)</span> |
| <span class="n">missing</span> <span class="o">=</span> <span class="p">[]</span> |
| <span class="k">if</span> <span class="n">enum_type</span> <span class="o">==</span> <span class="s1">'flag'</span><span class="p">:</span> |
| <span class="c1"># check for powers of two</span> |
| <span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="n">_high_bit</span><span class="p">(</span><span class="n">low</span><span class="p">)</span><span class="o">+</span><span class="mi">1</span><span class="p">,</span> <span class="n">_high_bit</span><span class="p">(</span><span class="n">high</span><span class="p">)):</span> |
| <span class="k">if</span> <span class="mi">2</span><span class="o">**</span><span class="n">i</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">values</span><span class="p">:</span> |
| <span class="n">missing</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="mi">2</span><span class="o">**</span><span class="n">i</span><span class="p">)</span> |
| <span class="k">elif</span> <span class="n">enum_type</span> <span class="o">==</span> <span class="s1">'enum'</span><span class="p">:</span> |
| <span class="c1"># check for powers of one</span> |
| <span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="n">low</span><span class="o">+</span><span class="mi">1</span><span class="p">,</span> <span class="n">high</span><span class="p">):</span> |
| <span class="k">if</span> <span class="n">i</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">values</span><span class="p">:</span> |
| <span class="n">missing</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">i</span><span class="p">)</span> |
| <span class="k">else</span><span class="p">:</span> |
| <span class="k">raise</span> <span class="ne">Exception</span><span class="p">(</span><span class="s1">'verify: unknown type </span><span class="si">%r</span><span class="s1">'</span> <span class="o">%</span> <span class="n">enum_type</span><span class="p">)</span> |
| <span class="k">if</span> <span class="n">missing</span><span class="p">:</span> |
| <span class="k">raise</span> <span class="ne">ValueError</span><span class="p">((</span><span class="s1">'invalid </span><span class="si">%s</span><span class="s1"> </span><span class="si">%r</span><span class="s1">: missing values </span><span class="si">%s</span><span class="s1">'</span> <span class="o">%</span> <span class="p">(</span> |
| <span class="n">enum_type</span><span class="p">,</span> <span class="n">cls_name</span><span class="p">,</span> <span class="s1">', '</span><span class="o">.</span><span class="n">join</span><span class="p">((</span><span class="nb">str</span><span class="p">(</span><span class="n">m</span><span class="p">)</span> <span class="k">for</span> <span class="n">m</span> <span class="ow">in</span> <span class="n">missing</span><span class="p">)))</span> |
| <span class="p">)[:</span><span class="mi">256</span><span class="p">])</span> |
| <span class="c1"># limit max length to protect against DOS attacks</span> |
| <span class="k">elif</span> <span class="n">check</span> <span class="ow">is</span> <span class="n">NAMED_FLAGS</span><span class="p">:</span> |
| <span class="c1"># examine each alias and check for unnamed flags</span> |
| <span class="n">member_names</span> <span class="o">=</span> <span class="n">enumeration</span><span class="o">.</span><span class="n">_member_names_</span> |
| <span class="n">member_values</span> <span class="o">=</span> <span class="p">[</span><span class="n">m</span><span class="o">.</span><span class="n">value</span> <span class="k">for</span> <span class="n">m</span> <span class="ow">in</span> <span class="n">enumeration</span><span class="p">]</span> |
| <span class="n">missing_names</span> <span class="o">=</span> <span class="p">[]</span> |
| <span class="n">missing_value</span> <span class="o">=</span> <span class="mi">0</span> |
| <span class="k">for</span> <span class="n">name</span><span class="p">,</span> <span class="n">alias</span> <span class="ow">in</span> <span class="n">enumeration</span><span class="o">.</span><span class="n">_member_map_</span><span class="o">.</span><span class="n">items</span><span class="p">():</span> |
| <span class="k">if</span> <span class="n">name</span> <span class="ow">in</span> <span class="n">member_names</span><span class="p">:</span> |
| <span class="c1"># not an alias</span> |
| <span class="k">continue</span> |
| <span class="k">if</span> <span class="n">alias</span><span class="o">.</span><span class="n">value</span> <span class="o"><</span> <span class="mi">0</span><span class="p">:</span> |
| <span class="c1"># negative numbers are not checked</span> |
| <span class="k">continue</span> |
| <span class="n">values</span> <span class="o">=</span> <span class="nb">list</span><span class="p">(</span><span class="n">_iter_bits_lsb</span><span class="p">(</span><span class="n">alias</span><span class="o">.</span><span class="n">value</span><span class="p">))</span> |
| <span class="n">missed</span> <span class="o">=</span> <span class="p">[</span><span class="n">v</span> <span class="k">for</span> <span class="n">v</span> <span class="ow">in</span> <span class="n">values</span> <span class="k">if</span> <span class="n">v</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">member_values</span><span class="p">]</span> |
| <span class="k">if</span> <span class="n">missed</span><span class="p">:</span> |
| <span class="n">missing_names</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">name</span><span class="p">)</span> |
| <span class="k">for</span> <span class="n">val</span> <span class="ow">in</span> <span class="n">missed</span><span class="p">:</span> |
| <span class="n">missing_value</span> <span class="o">|=</span> <span class="n">val</span> |
| <span class="k">if</span> <span class="n">missing_names</span><span class="p">:</span> |
| <span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">missing_names</span><span class="p">)</span> <span class="o">==</span> <span class="mi">1</span><span class="p">:</span> |
| <span class="n">alias</span> <span class="o">=</span> <span class="s1">'alias </span><span class="si">%s</span><span class="s1"> is missing'</span> <span class="o">%</span> <span class="n">missing_names</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> |
| <span class="k">else</span><span class="p">:</span> |
| <span class="n">alias</span> <span class="o">=</span> <span class="s1">'aliases </span><span class="si">%s</span><span class="s1"> and </span><span class="si">%s</span><span class="s1"> are missing'</span> <span class="o">%</span> <span class="p">(</span> |
| <span class="s1">', '</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">missing_names</span><span class="p">[:</span><span class="o">-</span><span class="mi">1</span><span class="p">]),</span> <span class="n">missing_names</span><span class="p">[</span><span class="o">-</span><span class="mi">1</span><span class="p">]</span> |
| <span class="p">)</span> |
| <span class="k">if</span> <span class="n">_is_single_bit</span><span class="p">(</span><span class="n">missing_value</span><span class="p">):</span> |
| <span class="n">value</span> <span class="o">=</span> <span class="s1">'value 0x</span><span class="si">%x</span><span class="s1">'</span> <span class="o">%</span> <span class="n">missing_value</span> |
| <span class="k">else</span><span class="p">:</span> |
| <span class="n">value</span> <span class="o">=</span> <span class="s1">'combined values of 0x</span><span class="si">%x</span><span class="s1">'</span> <span class="o">%</span> <span class="n">missing_value</span> |
| <span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span> |
| <span class="s1">'invalid Flag </span><span class="si">%r</span><span class="s1">: </span><span class="si">%s</span><span class="s1"> </span><span class="si">%s</span><span class="s1"> [use enum.show_flag_values(value) for details]'</span> |
| <span class="o">%</span> <span class="p">(</span><span class="n">cls_name</span><span class="p">,</span> <span class="n">alias</span><span class="p">,</span> <span class="n">value</span><span class="p">)</span> |
| <span class="p">)</span> |
| <span class="k">return</span> <span class="n">enumeration</span> |
| |
| <span class="k">def</span><span class="w"> </span><span class="nf">_test_simple_enum</span><span class="p">(</span><span class="n">checked_enum</span><span class="p">,</span> <span class="n">simple_enum</span><span class="p">):</span> |
| <span class="w"> </span><span class="sd">"""</span> |
| <span class="sd"> A function that can be used to test an enum created with :func:`_simple_enum`</span> |
| <span class="sd"> against the version created by subclassing :class:`Enum`::</span> |
| |
| <span class="sd"> >>> from enum import Enum, _simple_enum, _test_simple_enum</span> |
| <span class="sd"> >>> @_simple_enum(Enum)</span> |
| <span class="sd"> ... class Color:</span> |
| <span class="sd"> ... RED = auto()</span> |
| <span class="sd"> ... GREEN = auto()</span> |
| <span class="sd"> ... BLUE = auto()</span> |
| <span class="sd"> >>> class CheckedColor(Enum):</span> |
| <span class="sd"> ... RED = auto()</span> |
| <span class="sd"> ... GREEN = auto()</span> |
| <span class="sd"> ... BLUE = auto()</span> |
| <span class="sd"> >>> _test_simple_enum(CheckedColor, Color)</span> |
| |
| <span class="sd"> If differences are found, a :exc:`TypeError` is raised.</span> |
| <span class="sd"> """</span> |
| <span class="n">failed</span> <span class="o">=</span> <span class="p">[]</span> |
| <span class="k">if</span> <span class="n">checked_enum</span><span class="o">.</span><span class="vm">__dict__</span> <span class="o">!=</span> <span class="n">simple_enum</span><span class="o">.</span><span class="vm">__dict__</span><span class="p">:</span> |
| <span class="n">checked_dict</span> <span class="o">=</span> <span class="n">checked_enum</span><span class="o">.</span><span class="vm">__dict__</span> |
| <span class="n">checked_keys</span> <span class="o">=</span> <span class="nb">list</span><span class="p">(</span><span class="n">checked_dict</span><span class="o">.</span><span class="n">keys</span><span class="p">())</span> |
| <span class="n">simple_dict</span> <span class="o">=</span> <span class="n">simple_enum</span><span class="o">.</span><span class="vm">__dict__</span> |
| <span class="n">simple_keys</span> <span class="o">=</span> <span class="nb">list</span><span class="p">(</span><span class="n">simple_dict</span><span class="o">.</span><span class="n">keys</span><span class="p">())</span> |
| <span class="n">member_names</span> <span class="o">=</span> <span class="nb">set</span><span class="p">(</span> |
| <span class="nb">list</span><span class="p">(</span><span class="n">checked_enum</span><span class="o">.</span><span class="n">_member_map_</span><span class="o">.</span><span class="n">keys</span><span class="p">())</span> |
| <span class="o">+</span> <span class="nb">list</span><span class="p">(</span><span class="n">simple_enum</span><span class="o">.</span><span class="n">_member_map_</span><span class="o">.</span><span class="n">keys</span><span class="p">())</span> |
| <span class="p">)</span> |
| <span class="k">for</span> <span class="n">key</span> <span class="ow">in</span> <span class="nb">set</span><span class="p">(</span><span class="n">checked_keys</span> <span class="o">+</span> <span class="n">simple_keys</span><span class="p">):</span> |
| <span class="k">if</span> <span class="n">key</span> <span class="ow">in</span> <span class="p">(</span><span class="s1">'__module__'</span><span class="p">,</span> <span class="s1">'_member_map_'</span><span class="p">,</span> <span class="s1">'_value2member_map_'</span><span class="p">,</span> <span class="s1">'__doc__'</span><span class="p">,</span> |
| <span class="s1">'__static_attributes__'</span><span class="p">,</span> <span class="s1">'__firstlineno__'</span><span class="p">):</span> |
| <span class="c1"># keys known to be different, or very long</span> |
| <span class="k">continue</span> |
| <span class="k">elif</span> <span class="n">key</span> <span class="ow">in</span> <span class="n">member_names</span><span class="p">:</span> |
| <span class="c1"># members are checked below</span> |
| <span class="k">continue</span> |
| <span class="k">elif</span> <span class="n">key</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">simple_keys</span><span class="p">:</span> |
| <span class="n">failed</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="s2">"missing key: </span><span class="si">%r</span><span class="s2">"</span> <span class="o">%</span> <span class="p">(</span><span class="n">key</span><span class="p">,</span> <span class="p">))</span> |
| <span class="k">elif</span> <span class="n">key</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">checked_keys</span><span class="p">:</span> |
| <span class="n">failed</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="s2">"extra key: </span><span class="si">%r</span><span class="s2">"</span> <span class="o">%</span> <span class="p">(</span><span class="n">key</span><span class="p">,</span> <span class="p">))</span> |
| <span class="k">else</span><span class="p">:</span> |
| <span class="n">checked_value</span> <span class="o">=</span> <span class="n">checked_dict</span><span class="p">[</span><span class="n">key</span><span class="p">]</span> |
| <span class="n">simple_value</span> <span class="o">=</span> <span class="n">simple_dict</span><span class="p">[</span><span class="n">key</span><span class="p">]</span> |
| <span class="k">if</span> <span class="nb">callable</span><span class="p">(</span><span class="n">checked_value</span><span class="p">)</span> <span class="ow">or</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">checked_value</span><span class="p">,</span> <span class="n">bltns</span><span class="o">.</span><span class="n">property</span><span class="p">):</span> |
| <span class="k">continue</span> |
| <span class="k">if</span> <span class="n">key</span> <span class="o">==</span> <span class="s1">'__doc__'</span><span class="p">:</span> |
| <span class="c1"># remove all spaces/tabs</span> |
| <span class="n">compressed_checked_value</span> <span class="o">=</span> <span class="n">checked_value</span><span class="o">.</span><span class="n">replace</span><span class="p">(</span><span class="s1">' '</span><span class="p">,</span><span class="s1">''</span><span class="p">)</span><span class="o">.</span><span class="n">replace</span><span class="p">(</span><span class="s1">'</span><span class="se">\t</span><span class="s1">'</span><span class="p">,</span><span class="s1">''</span><span class="p">)</span> |
| <span class="n">compressed_simple_value</span> <span class="o">=</span> <span class="n">simple_value</span><span class="o">.</span><span class="n">replace</span><span class="p">(</span><span class="s1">' '</span><span class="p">,</span><span class="s1">''</span><span class="p">)</span><span class="o">.</span><span class="n">replace</span><span class="p">(</span><span class="s1">'</span><span class="se">\t</span><span class="s1">'</span><span class="p">,</span><span class="s1">''</span><span class="p">)</span> |
| <span class="k">if</span> <span class="n">compressed_checked_value</span> <span class="o">!=</span> <span class="n">compressed_simple_value</span><span class="p">:</span> |
| <span class="n">failed</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="s2">"</span><span class="si">%r</span><span class="s2">:</span><span class="se">\n</span><span class="s2"> </span><span class="si">%s</span><span class="se">\n</span><span class="s2"> </span><span class="si">%s</span><span class="s2">"</span> <span class="o">%</span> <span class="p">(</span> |
| <span class="n">key</span><span class="p">,</span> |
| <span class="s2">"checked -> </span><span class="si">%r</span><span class="s2">"</span> <span class="o">%</span> <span class="p">(</span><span class="n">checked_value</span><span class="p">,</span> <span class="p">),</span> |
| <span class="s2">"simple -> </span><span class="si">%r</span><span class="s2">"</span> <span class="o">%</span> <span class="p">(</span><span class="n">simple_value</span><span class="p">,</span> <span class="p">),</span> |
| <span class="p">))</span> |
| <span class="k">elif</span> <span class="n">checked_value</span> <span class="o">!=</span> <span class="n">simple_value</span><span class="p">:</span> |
| <span class="n">failed</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="s2">"</span><span class="si">%r</span><span class="s2">:</span><span class="se">\n</span><span class="s2"> </span><span class="si">%s</span><span class="se">\n</span><span class="s2"> </span><span class="si">%s</span><span class="s2">"</span> <span class="o">%</span> <span class="p">(</span> |
| <span class="n">key</span><span class="p">,</span> |
| <span class="s2">"checked -> </span><span class="si">%r</span><span class="s2">"</span> <span class="o">%</span> <span class="p">(</span><span class="n">checked_value</span><span class="p">,</span> <span class="p">),</span> |
| <span class="s2">"simple -> </span><span class="si">%r</span><span class="s2">"</span> <span class="o">%</span> <span class="p">(</span><span class="n">simple_value</span><span class="p">,</span> <span class="p">),</span> |
| <span class="p">))</span> |
| <span class="n">failed</span><span class="o">.</span><span class="n">sort</span><span class="p">()</span> |
| <span class="k">for</span> <span class="n">name</span> <span class="ow">in</span> <span class="n">member_names</span><span class="p">:</span> |
| <span class="n">failed_member</span> <span class="o">=</span> <span class="p">[]</span> |
| <span class="k">if</span> <span class="n">name</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">simple_keys</span><span class="p">:</span> |
| <span class="n">failed</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="s1">'missing member from simple enum: </span><span class="si">%r</span><span class="s1">'</span> <span class="o">%</span> <span class="n">name</span><span class="p">)</span> |
| <span class="k">elif</span> <span class="n">name</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">checked_keys</span><span class="p">:</span> |
| <span class="n">failed</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="s1">'extra member in simple enum: </span><span class="si">%r</span><span class="s1">'</span> <span class="o">%</span> <span class="n">name</span><span class="p">)</span> |
| <span class="k">else</span><span class="p">:</span> |
| <span class="n">checked_member_dict</span> <span class="o">=</span> <span class="n">checked_enum</span><span class="p">[</span><span class="n">name</span><span class="p">]</span><span class="o">.</span><span class="vm">__dict__</span> |
| <span class="n">checked_member_keys</span> <span class="o">=</span> <span class="nb">list</span><span class="p">(</span><span class="n">checked_member_dict</span><span class="o">.</span><span class="n">keys</span><span class="p">())</span> |
| <span class="n">simple_member_dict</span> <span class="o">=</span> <span class="n">simple_enum</span><span class="p">[</span><span class="n">name</span><span class="p">]</span><span class="o">.</span><span class="vm">__dict__</span> |
| <span class="n">simple_member_keys</span> <span class="o">=</span> <span class="nb">list</span><span class="p">(</span><span class="n">simple_member_dict</span><span class="o">.</span><span class="n">keys</span><span class="p">())</span> |
| <span class="k">for</span> <span class="n">key</span> <span class="ow">in</span> <span class="nb">set</span><span class="p">(</span><span class="n">checked_member_keys</span> <span class="o">+</span> <span class="n">simple_member_keys</span><span class="p">):</span> |
| <span class="k">if</span> <span class="n">key</span> <span class="ow">in</span> <span class="p">(</span><span class="s1">'__module__'</span><span class="p">,</span> <span class="s1">'__objclass__'</span><span class="p">,</span> <span class="s1">'_inverted_'</span><span class="p">):</span> |
| <span class="c1"># keys known to be different or absent</span> |
| <span class="k">continue</span> |
| <span class="k">elif</span> <span class="n">key</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">simple_member_keys</span><span class="p">:</span> |
| <span class="n">failed_member</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="s2">"missing key </span><span class="si">%r</span><span class="s2"> not in the simple enum member </span><span class="si">%r</span><span class="s2">"</span> <span class="o">%</span> <span class="p">(</span><span class="n">key</span><span class="p">,</span> <span class="n">name</span><span class="p">))</span> |
| <span class="k">elif</span> <span class="n">key</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">checked_member_keys</span><span class="p">:</span> |
| <span class="n">failed_member</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="s2">"extra key </span><span class="si">%r</span><span class="s2"> in simple enum member </span><span class="si">%r</span><span class="s2">"</span> <span class="o">%</span> <span class="p">(</span><span class="n">key</span><span class="p">,</span> <span class="n">name</span><span class="p">))</span> |
| <span class="k">else</span><span class="p">:</span> |
| <span class="n">checked_value</span> <span class="o">=</span> <span class="n">checked_member_dict</span><span class="p">[</span><span class="n">key</span><span class="p">]</span> |
| <span class="n">simple_value</span> <span class="o">=</span> <span class="n">simple_member_dict</span><span class="p">[</span><span class="n">key</span><span class="p">]</span> |
| <span class="k">if</span> <span class="n">checked_value</span> <span class="o">!=</span> <span class="n">simple_value</span><span class="p">:</span> |
| <span class="n">failed_member</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="s2">"</span><span class="si">%r</span><span class="s2">:</span><span class="se">\n</span><span class="s2"> </span><span class="si">%s</span><span class="se">\n</span><span class="s2"> </span><span class="si">%s</span><span class="s2">"</span> <span class="o">%</span> <span class="p">(</span> |
| <span class="n">key</span><span class="p">,</span> |
| <span class="s2">"checked member -> </span><span class="si">%r</span><span class="s2">"</span> <span class="o">%</span> <span class="p">(</span><span class="n">checked_value</span><span class="p">,</span> <span class="p">),</span> |
| <span class="s2">"simple member -> </span><span class="si">%r</span><span class="s2">"</span> <span class="o">%</span> <span class="p">(</span><span class="n">simple_value</span><span class="p">,</span> <span class="p">),</span> |
| <span class="p">))</span> |
| <span class="k">if</span> <span class="n">failed_member</span><span class="p">:</span> |
| <span class="n">failed</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="s1">'</span><span class="si">%r</span><span class="s1"> member mismatch:</span><span class="se">\n</span><span class="s1"> </span><span class="si">%s</span><span class="s1">'</span> <span class="o">%</span> <span class="p">(</span> |
| <span class="n">name</span><span class="p">,</span> <span class="s1">'</span><span class="se">\n</span><span class="s1"> '</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">failed_member</span><span class="p">),</span> |
| <span class="p">))</span> |
| <span class="k">for</span> <span class="n">method</span> <span class="ow">in</span> <span class="p">(</span> |
| <span class="s1">'__str__'</span><span class="p">,</span> <span class="s1">'__repr__'</span><span class="p">,</span> <span class="s1">'__reduce_ex__'</span><span class="p">,</span> <span class="s1">'__format__'</span><span class="p">,</span> |
| <span class="s1">'__getnewargs_ex__'</span><span class="p">,</span> <span class="s1">'__getnewargs__'</span><span class="p">,</span> <span class="s1">'__reduce_ex__'</span><span class="p">,</span> <span class="s1">'__reduce__'</span> |
| <span class="p">):</span> |
| <span class="k">if</span> <span class="n">method</span> <span class="ow">in</span> <span class="n">simple_keys</span> <span class="ow">and</span> <span class="n">method</span> <span class="ow">in</span> <span class="n">checked_keys</span><span class="p">:</span> |
| <span class="c1"># cannot compare functions, and it exists in both, so we're good</span> |
| <span class="k">continue</span> |
| <span class="k">elif</span> <span class="n">method</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">simple_keys</span> <span class="ow">and</span> <span class="n">method</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">checked_keys</span><span class="p">:</span> |
| <span class="c1"># method is inherited -- check it out</span> |
| <span class="n">checked_method</span> <span class="o">=</span> <span class="nb">getattr</span><span class="p">(</span><span class="n">checked_enum</span><span class="p">,</span> <span class="n">method</span><span class="p">,</span> <span class="kc">None</span><span class="p">)</span> |
| <span class="n">simple_method</span> <span class="o">=</span> <span class="nb">getattr</span><span class="p">(</span><span class="n">simple_enum</span><span class="p">,</span> <span class="n">method</span><span class="p">,</span> <span class="kc">None</span><span class="p">)</span> |
| <span class="k">if</span> <span class="nb">hasattr</span><span class="p">(</span><span class="n">checked_method</span><span class="p">,</span> <span class="s1">'__func__'</span><span class="p">):</span> |
| <span class="n">checked_method</span> <span class="o">=</span> <span class="n">checked_method</span><span class="o">.</span><span class="vm">__func__</span> |
| <span class="n">simple_method</span> <span class="o">=</span> <span class="n">simple_method</span><span class="o">.</span><span class="vm">__func__</span> |
| <span class="k">if</span> <span class="n">checked_method</span> <span class="o">!=</span> <span class="n">simple_method</span><span class="p">:</span> |
| <span class="n">failed</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="s2">"</span><span class="si">%r</span><span class="s2">: </span><span class="si">%-30s</span><span class="s2"> </span><span class="si">%s</span><span class="s2">"</span> <span class="o">%</span> <span class="p">(</span> |
| <span class="n">method</span><span class="p">,</span> |
| <span class="s2">"checked -> </span><span class="si">%r</span><span class="s2">"</span> <span class="o">%</span> <span class="p">(</span><span class="n">checked_method</span><span class="p">,</span> <span class="p">),</span> |
| <span class="s2">"simple -> </span><span class="si">%r</span><span class="s2">"</span> <span class="o">%</span> <span class="p">(</span><span class="n">simple_method</span><span class="p">,</span> <span class="p">),</span> |
| <span class="p">))</span> |
| <span class="k">else</span><span class="p">:</span> |
| <span class="c1"># if the method existed in only one of the enums, it will have been caught</span> |
| <span class="c1"># in the first checks above</span> |
| <span class="k">pass</span> |
| <span class="k">if</span> <span class="n">failed</span><span class="p">:</span> |
| <span class="k">raise</span> <span class="ne">TypeError</span><span class="p">(</span><span class="s1">'enum mismatch:</span><span class="se">\n</span><span class="s1"> </span><span class="si">%s</span><span class="s1">'</span> <span class="o">%</span> <span class="s1">'</span><span class="se">\n</span><span class="s1"> '</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">failed</span><span class="p">))</span> |
| |
| <span class="k">def</span><span class="w"> </span><span class="nf">_old_convert_</span><span class="p">(</span><span class="n">etype</span><span class="p">,</span> <span class="n">name</span><span class="p">,</span> <span class="n">module</span><span class="p">,</span> <span class="nb">filter</span><span class="p">,</span> <span class="n">source</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="o">*</span><span class="p">,</span> <span class="n">boundary</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span> |
| <span class="w"> </span><span class="sd">"""</span> |
| <span class="sd"> Create a new Enum subclass that replaces a collection of global constants</span> |
| <span class="sd"> """</span> |
| <span class="c1"># convert all constants from source (or module) that pass filter() to</span> |
| <span class="c1"># a new Enum called name, and export the enum and its members back to</span> |
| <span class="c1"># module;</span> |
| <span class="c1"># also, replace the __reduce_ex__ method so unpickling works in</span> |
| <span class="c1"># previous Python versions</span> |
| <span class="n">module_globals</span> <span class="o">=</span> <span class="n">sys</span><span class="o">.</span><span class="n">modules</span><span class="p">[</span><span class="n">module</span><span class="p">]</span><span class="o">.</span><span class="vm">__dict__</span> |
| <span class="k">if</span> <span class="n">source</span><span class="p">:</span> |
| <span class="n">source</span> <span class="o">=</span> <span class="n">source</span><span class="o">.</span><span class="vm">__dict__</span> |
| <span class="k">else</span><span class="p">:</span> |
| <span class="n">source</span> <span class="o">=</span> <span class="n">module_globals</span> |
| <span class="c1"># _value2member_map_ is populated in the same order every time</span> |
| <span class="c1"># for a consistent reverse mapping of number to name when there</span> |
| <span class="c1"># are multiple names for the same number.</span> |
| <span class="n">members</span> <span class="o">=</span> <span class="p">[</span> |
| <span class="p">(</span><span class="n">name</span><span class="p">,</span> <span class="n">value</span><span class="p">)</span> |
| <span class="k">for</span> <span class="n">name</span><span class="p">,</span> <span class="n">value</span> <span class="ow">in</span> <span class="n">source</span><span class="o">.</span><span class="n">items</span><span class="p">()</span> |
| <span class="k">if</span> <span class="nb">filter</span><span class="p">(</span><span class="n">name</span><span class="p">)]</span> |
| <span class="k">try</span><span class="p">:</span> |
| <span class="c1"># sort by value</span> |
| <span class="n">members</span><span class="o">.</span><span class="n">sort</span><span class="p">(</span><span class="n">key</span><span class="o">=</span><span class="k">lambda</span> <span class="n">t</span><span class="p">:</span> <span class="p">(</span><span class="n">t</span><span class="p">[</span><span class="mi">1</span><span class="p">],</span> <span class="n">t</span><span class="p">[</span><span class="mi">0</span><span class="p">]))</span> |
| <span class="k">except</span> <span class="ne">TypeError</span><span class="p">:</span> |
| <span class="c1"># unless some values aren't comparable, in which case sort by name</span> |
| <span class="n">members</span><span class="o">.</span><span class="n">sort</span><span class="p">(</span><span class="n">key</span><span class="o">=</span><span class="k">lambda</span> <span class="n">t</span><span class="p">:</span> <span class="n">t</span><span class="p">[</span><span class="mi">0</span><span class="p">])</span> |
| <span class="bp">cls</span> <span class="o">=</span> <span class="n">etype</span><span class="p">(</span><span class="n">name</span><span class="p">,</span> <span class="n">members</span><span class="p">,</span> <span class="n">module</span><span class="o">=</span><span class="n">module</span><span class="p">,</span> <span class="n">boundary</span><span class="o">=</span><span class="n">boundary</span> <span class="ow">or</span> <span class="n">KEEP</span><span class="p">)</span> |
| <span class="k">return</span> <span class="bp">cls</span> |
| |
| <span class="n">_stdlib_enums</span> <span class="o">=</span> <span class="n">IntEnum</span><span class="p">,</span> <span class="n">StrEnum</span><span class="p">,</span> <span class="n">IntFlag</span> |
| </pre></div> |
| |
| </article> |
| |
| |
| |
| |
| |
| <footer class="prev-next-footer d-print-none"> |
| |
| <div class="prev-next-area"> |
| </div> |
| </footer> |
| |
| </div> |
| |
| |
| |
| |
| </div> |
| <footer class="bd-footer-content"> |
| |
| </footer> |
| |
| </main> |
| </div> |
| </div> |
| |
| <!-- Scripts loaded after <body> so the DOM is not blocked --> |
| <script defer src="../_static/scripts/bootstrap.js?digest=8878045cc6db502f8baf"></script> |
| <script defer src="../_static/scripts/pydata-sphinx-theme.js?digest=8878045cc6db502f8baf"></script> |
| |
| <footer class="bd-footer"> |
| <div class="bd-footer__inner bd-page-width"> |
| |
| <div class="footer-items__start"> |
| |
| <div class="footer-item"> |
| |
| <p class="copyright"> |
| |
| © Copyright 2016-2026 Apache Software Foundation. |
| Apache Arrow, Arrow, Apache, the Apache logo, and the Apache Arrow project logo are either registered trademarks or trademarks of The Apache Software Foundation in the United States and other countries. |
| <br/> |
| |
| </p> |
| </div> |
| |
| <div class="footer-item"> |
| |
| <p class="sphinx-version"> |
| Created using <a href="https://www.sphinx-doc.org/">Sphinx</a> 9.1.0. |
| <br/> |
| </p> |
| </div> |
| |
| </div> |
| |
| |
| |
| <div class="footer-items__end"> |
| |
| <div class="footer-item"> |
| <p class="theme-version"> |
| <!-- # L10n: Setting the PST URL as an argument as this does not need to be localized --> |
| Built with the <a href="https://pydata-sphinx-theme.readthedocs.io/en/stable/index.html">PyData Sphinx Theme</a> 0.16.1. |
| </p></div> |
| |
| </div> |
| |
| </div> |
| |
| </footer> |
| </body> |
| </html> |