Overview
Comment: | lots pylint fixes, add documentation |
---|---|
Downloads: | Tarball | ZIP archive | SQL archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA3-256: |
9c3d29591697ade05c37e33579ba5418 |
User & Date: | mario on 2022-10-27 05:34:24 |
Other Links: | manifest | tags |
Context
2022-10-27
| ||
07:44 | pylint fixes for pluginconf.depends check-in: 3be9f23c57 user: mario tags: trunk | |
05:34 | lots pylint fixes, add documentation check-in: 9c3d295916 user: mario tags: trunk | |
2022-10-26
| ||
16:50 | support for #console-scripts: in setup+flit check-in: b5dc7df53f user: mario tags: trunk | |
Changes
Added html/depends.html version [20c4a76bca].
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 | <!doctype html> <html lang="en"> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1" /> <meta name="generator" content="pdoc 0.10.0" /> <title>pluginconf.depends API documentation</title> <meta name="description" content="Dependency validation and consistency checker for updates" /> <link rel="preload stylesheet" as="style" href="https://cdnjs.cloudflare.com/ajax/libs/10up-sanitize.css/11.0.1/sanitize.min.css" integrity="sha256-PK9q560IAAa6WVRRh76LtCaI8pjTJ2z11v0miyNNjrs=" crossorigin> <link rel="preload stylesheet" as="style" href="https://cdnjs.cloudflare.com/ajax/libs/10up-sanitize.css/11.0.1/typography.min.css" integrity="sha256-7l/o7C8jubJiy74VsKTidCy1yBkRtiUGbVkYBylBqUg=" crossorigin> <link rel="stylesheet preload" as="style" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/10.1.1/styles/github.min.css" crossorigin> <style>:root{--highlight-color:#fe9}.flex{display:flex !important}body{line-height:1.5em}#content{padding:20px}#sidebar{padding:30px;overflow:hidden}#sidebar > *:last-child{margin-bottom:2cm}.http-server-breadcrumbs{font-size:130%;margin:0 0 15px 0}#footer{font-size:.75em;padding:5px 30px;border-top:1px solid #ddd;text-align:right}#footer p{margin:0 0 0 1em;display:inline-block}#footer p:last-child{margin-right:30px}h1,h2,h3,h4,h5{font-weight:300}h1{font-size:2.5em;line-height:1.1em}h2{font-size:1.75em;margin:1em 0 .50em 0}h3{font-size:1.4em;margin:25px 0 10px 0}h4{margin:0;font-size:105%}h1:target,h2:target,h3:target,h4:target,h5:target,h6:target{background:var(--highlight-color);padding:.2em 0}a{color:#058;text-decoration:none;transition:color .3s ease-in-out}a:hover{color:#e82}.title code{font-weight:bold}h2[id^="header-"]{margin-top:2em}.ident{color:#900}pre code{background:#f8f8f8;font-size:.8em;line-height:1.4em}code{background:#f2f2f1;padding:1px 4px;overflow-wrap:break-word}h1 code{background:transparent}pre{background:#f8f8f8;border:0;border-top:1px solid #ccc;border-bottom:1px solid #ccc;margin:1em 0;padding:1ex}#http-server-module-list{display:flex;flex-flow:column}#http-server-module-list div{display:flex}#http-server-module-list dt{min-width:10%}#http-server-module-list p{margin-top:0}.toc ul,#index{list-style-type:none;margin:0;padding:0}#index code{background:transparent}#index h3{border-bottom:1px solid #ddd}#index ul{padding:0}#index h4{margin-top:.6em;font-weight:bold}@media (min-width:200ex){#index .two-column{column-count:2}}@media (min-width:300ex){#index .two-column{column-count:3}}dl{margin-bottom:2em}dl dl:last-child{margin-bottom:4em}dd{margin:0 0 1em 3em}#header-classes + dl > dd{margin-bottom:3em}dd dd{margin-left:2em}dd p{margin:10px 0}.name{background:#eee;font-weight:bold;font-size:.85em;padding:5px 10px;display:inline-block;min-width:40%}.name:hover{background:#e0e0e0}dt:target .name{background:var(--highlight-color)}.name > span:first-child{white-space:nowrap}.name.class > span:nth-child(2){margin-left:.4em}.inherited{color:#999;border-left:5px solid #eee;padding-left:1em}.inheritance em{font-style:normal;font-weight:bold}.desc h2{font-weight:400;font-size:1.25em}.desc h3{font-size:1em}.desc dt code{background:inherit}.source summary,.git-link-div{color:#666;text-align:right;font-weight:400;font-size:.8em;text-transform:uppercase}.source summary > *{white-space:nowrap;cursor:pointer}.git-link{color:inherit;margin-left:1em}.source pre{max-height:500px;overflow:auto;margin:0}.source pre code{font-size:12px;overflow:visible}.hlist{list-style:none}.hlist li{display:inline}.hlist li:after{content:',\2002'}.hlist li:last-child:after{content:none}.hlist .hlist{display:inline;padding-left:1em}img{max-width:100%}td{padding:0 .5em}.admonition{padding:.1em .5em;margin-bottom:1em}.admonition-title{font-weight:bold}.admonition.note,.admonition.info,.admonition.important{background:#aef}.admonition.todo,.admonition.versionadded,.admonition.tip,.admonition.hint{background:#dfd}.admonition.warning,.admonition.versionchanged,.admonition.deprecated{background:#fd4}.admonition.error,.admonition.danger,.admonition.caution{background:lightpink}</style> <style media="screen and (min-width: 700px)">@media screen and (min-width:700px){#sidebar{width:30%;height:100vh;overflow:auto;position:sticky;top:0}#content{width:70%;max-width:100ch;padding:3em 4em;border-left:1px solid #ddd}pre code{font-size:1em}.item .name{font-size:1em}main{display:flex;flex-direction:row-reverse;justify-content:flex-end}.toc ul ul,#index ul{padding-left:1.5em}.toc > ul > li{margin-top:.5em}}</style> <style media="print">@media print{#sidebar h1{page-break-before:always}.source{display:none}}@media print{*{background:transparent !important;color:#000 !important;box-shadow:none !important;text-shadow:none !important}a[href]:after{content:" (" attr(href) ")";font-size:90%}a[href][title]:after{content:none}abbr[title]:after{content:" (" attr(title) ")"}.ir a:after,a[href^="javascript:"]:after,a[href^="#"]:after{content:""}pre,blockquote{border:1px solid #999;page-break-inside:avoid}thead{display:table-header-group}tr,img{page-break-inside:avoid}img{max-width:100% !important}@page{margin:0.5cm}p,h2,h3{orphans:3;widows:3}h1,h2,h3,h4,h5,h6{page-break-after:avoid}}</style> <script defer src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/10.1.1/highlight.min.js" integrity="sha256-Uv3H6lx7dJmRfRvH8TH6kJD1TSK1aFcwgx+mdg3epi8=" crossorigin></script> <script>window.addEventListener('DOMContentLoaded', () => hljs.initHighlighting())</script> </head> <body> <main> <article id="content"> <header> <h1 class="title">Module <code>pluginconf.depends</code></h1> </header> <section id="section-intro"> <p>Dependency validation and consistency checker for updates</p> </section> <section> </section> <section> </section> <section> </section> <section> <h2 class="section-title" id="header-classes">Classes</h2> <dl> <dt id="pluginconf.depends.DependencyValidation"><code class="flex name class"> <span>class <span class="ident">DependencyValidation</span></span> <span>(</span><span>add={}, core=['st2', 'uikit', 'config', 'action'])</span> </code></dt> <dd> <div class="desc"><p>Now this definitely requires customization. Each plugin can carry a list of (soft-) dependency names.</p> <p># depends: config, appcore >= 2.0, bin:wkhtmltoimage, python < 3.5</p> <p>Here only in-application modules are honored, system references ignored. Unknown plugin names are also skipped. A real install helper might want to auto-tick them on, etc. This example is just meant for probing downloadable plugins.</p> <p>The .valid() helper only asserts the api: string, or skips existing modules, and if they're more recent. While .depends() compares minimum versions against existing modules.</p> <p>In practice there's little need for full-blown dependency resolving for application-level modules.</p> <h2 id="attributes">Attributes</h2> <dl> <dt><strong><code>api</code></strong> : <code>list</code></dt> <dd>allowed api: identifiers for .valid() stream checks</dd> <dt><strong><code>log</code></strong> : <code>logging</code></dt> <dd>warning handler</dd> <dt><strong><code>have</code></strong> : <code>dict</code></dt> <dd>accumulated list of existing/virtual plugins</dd> </dl> <h2 id="parameters">Parameters</h2> <dl> <dt><strong><code>add</code></strong> : <code>dict</code></dt> <dd>name to pmd list of existing/core/virtual plugins (can define versions or own dependencies)</dd> <dt><strong><code>core</code></strong> : <code>list</code></dt> <dd>name list of virtual plugins</dd> </dl></div> <h3>Class variables</h3> <dl> <dt id="pluginconf.depends.DependencyValidation.api"><code class="name">var <span class="ident">api</span></code></dt> <dd> <div class="desc"><p>debugging</p></div> </dd> <dt id="pluginconf.depends.DependencyValidation.log"><code class="name">var <span class="ident">log</span></code></dt> <dd> <div class="desc"></div> </dd> </dl> <h3>Methods</h3> <dl> <dt id="pluginconf.depends.DependencyValidation.and_or"><code class="name flex"> <span>def <span class="ident">and_or</span></span>(<span>self, deps, have, r=True)</span> </code></dt> <dd> <div class="desc"></div> </dd> <dt id="pluginconf.depends.DependencyValidation.cmp"><code class="name flex"> <span>def <span class="ident">cmp</span></span>(<span>self, d, have, absent=True)</span> </code></dt> <dd> <div class="desc"></div> </dd> <dt id="pluginconf.depends.DependencyValidation.depends"><code class="name flex"> <span>def <span class="ident">depends</span></span>(<span>self, plugin)</span> </code></dt> <dd> <div class="desc"><p>test depends: and breaks:</p></div> </dd> <dt id="pluginconf.depends.DependencyValidation.module_test"><code class="name flex"> <span>def <span class="ident">module_test</span></span>(<span>self, type, name)</span> </code></dt> <dd> <div class="desc"></div> </dd> <dt id="pluginconf.depends.DependencyValidation.neither"><code class="name flex"> <span>def <span class="ident">neither</span></span>(<span>self, deps, have)</span> </code></dt> <dd> <div class="desc"></div> </dd> <dt id="pluginconf.depends.DependencyValidation.split"><code class="name flex"> <span>def <span class="ident">split</span></span>(<span>self, dep_str)</span> </code></dt> <dd> <div class="desc"></div> </dd> <dt id="pluginconf.depends.DependencyValidation.valid"><code class="name flex"> <span>def <span class="ident">valid</span></span>(<span>self, new_plugin)</span> </code></dt> <dd> <div class="desc"><p>check plugin info from repository stream (fields there $name, $file, $dist, api, id, depends, etc)</p></div> </dd> </dl> </dd> </dl> </section> </article> <nav id="sidebar"> <h1>Index</h1> <div class="toc"> <ul></ul> </div> <ul id="index"> <li><h3>Super-module</h3> <ul> <li><code><a title="pluginconf" href="index.html">pluginconf</a></code></li> </ul> </li> <li><h3><a href="#header-classes">Classes</a></h3> <ul> <li> <h4><code><a title="pluginconf.depends.DependencyValidation" href="#pluginconf.depends.DependencyValidation">DependencyValidation</a></code></h4> <ul class="two-column"> <li><code><a title="pluginconf.depends.DependencyValidation.and_or" href="#pluginconf.depends.DependencyValidation.and_or">and_or</a></code></li> <li><code><a title="pluginconf.depends.DependencyValidation.api" href="#pluginconf.depends.DependencyValidation.api">api</a></code></li> <li><code><a title="pluginconf.depends.DependencyValidation.cmp" href="#pluginconf.depends.DependencyValidation.cmp">cmp</a></code></li> <li><code><a title="pluginconf.depends.DependencyValidation.depends" href="#pluginconf.depends.DependencyValidation.depends">depends</a></code></li> <li><code><a title="pluginconf.depends.DependencyValidation.log" href="#pluginconf.depends.DependencyValidation.log">log</a></code></li> <li><code><a title="pluginconf.depends.DependencyValidation.module_test" href="#pluginconf.depends.DependencyValidation.module_test">module_test</a></code></li> <li><code><a title="pluginconf.depends.DependencyValidation.neither" href="#pluginconf.depends.DependencyValidation.neither">neither</a></code></li> <li><code><a title="pluginconf.depends.DependencyValidation.split" href="#pluginconf.depends.DependencyValidation.split">split</a></code></li> <li><code><a title="pluginconf.depends.DependencyValidation.valid" href="#pluginconf.depends.DependencyValidation.valid">valid</a></code></li> </ul> </li> </ul> </li> </ul> </nav> </main> <footer id="footer"> <p>Generated by <a href="https://pdoc3.github.io/pdoc" title="pdoc: Python API documentation generator"><cite>pdoc</cite> 0.10.0</a>.</p> </footer> </body> </html> |
Added html/flit.html version [59c947f140].
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 | <!doctype html> <html lang="en"> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1" /> <meta name="generator" content="pdoc 0.10.0" /> <title>pluginconf.flit API documentation</title> <meta name="description" content="monkeypatches flint to use pluginconf sources for packaging" /> <link rel="preload stylesheet" as="style" href="https://cdnjs.cloudflare.com/ajax/libs/10up-sanitize.css/11.0.1/sanitize.min.css" integrity="sha256-PK9q560IAAa6WVRRh76LtCaI8pjTJ2z11v0miyNNjrs=" crossorigin> <link rel="preload stylesheet" as="style" href="https://cdnjs.cloudflare.com/ajax/libs/10up-sanitize.css/11.0.1/typography.min.css" integrity="sha256-7l/o7C8jubJiy74VsKTidCy1yBkRtiUGbVkYBylBqUg=" crossorigin> <link rel="stylesheet preload" as="style" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/10.1.1/styles/github.min.css" crossorigin> <style>:root{--highlight-color:#fe9}.flex{display:flex !important}body{line-height:1.5em}#content{padding:20px}#sidebar{padding:30px;overflow:hidden}#sidebar > *:last-child{margin-bottom:2cm}.http-server-breadcrumbs{font-size:130%;margin:0 0 15px 0}#footer{font-size:.75em;padding:5px 30px;border-top:1px solid #ddd;text-align:right}#footer p{margin:0 0 0 1em;display:inline-block}#footer p:last-child{margin-right:30px}h1,h2,h3,h4,h5{font-weight:300}h1{font-size:2.5em;line-height:1.1em}h2{font-size:1.75em;margin:1em 0 .50em 0}h3{font-size:1.4em;margin:25px 0 10px 0}h4{margin:0;font-size:105%}h1:target,h2:target,h3:target,h4:target,h5:target,h6:target{background:var(--highlight-color);padding:.2em 0}a{color:#058;text-decoration:none;transition:color .3s ease-in-out}a:hover{color:#e82}.title code{font-weight:bold}h2[id^="header-"]{margin-top:2em}.ident{color:#900}pre code{background:#f8f8f8;font-size:.8em;line-height:1.4em}code{background:#f2f2f1;padding:1px 4px;overflow-wrap:break-word}h1 code{background:transparent}pre{background:#f8f8f8;border:0;border-top:1px solid #ccc;border-bottom:1px solid #ccc;margin:1em 0;padding:1ex}#http-server-module-list{display:flex;flex-flow:column}#http-server-module-list div{display:flex}#http-server-module-list dt{min-width:10%}#http-server-module-list p{margin-top:0}.toc ul,#index{list-style-type:none;margin:0;padding:0}#index code{background:transparent}#index h3{border-bottom:1px solid #ddd}#index ul{padding:0}#index h4{margin-top:.6em;font-weight:bold}@media (min-width:200ex){#index .two-column{column-count:2}}@media (min-width:300ex){#index .two-column{column-count:3}}dl{margin-bottom:2em}dl dl:last-child{margin-bottom:4em}dd{margin:0 0 1em 3em}#header-classes + dl > dd{margin-bottom:3em}dd dd{margin-left:2em}dd p{margin:10px 0}.name{background:#eee;font-weight:bold;font-size:.85em;padding:5px 10px;display:inline-block;min-width:40%}.name:hover{background:#e0e0e0}dt:target .name{background:var(--highlight-color)}.name > span:first-child{white-space:nowrap}.name.class > span:nth-child(2){margin-left:.4em}.inherited{color:#999;border-left:5px solid #eee;padding-left:1em}.inheritance em{font-style:normal;font-weight:bold}.desc h2{font-weight:400;font-size:1.25em}.desc h3{font-size:1em}.desc dt code{background:inherit}.source summary,.git-link-div{color:#666;text-align:right;font-weight:400;font-size:.8em;text-transform:uppercase}.source summary > *{white-space:nowrap;cursor:pointer}.git-link{color:inherit;margin-left:1em}.source pre{max-height:500px;overflow:auto;margin:0}.source pre code{font-size:12px;overflow:visible}.hlist{list-style:none}.hlist li{display:inline}.hlist li:after{content:',\2002'}.hlist li:last-child:after{content:none}.hlist .hlist{display:inline;padding-left:1em}img{max-width:100%}td{padding:0 .5em}.admonition{padding:.1em .5em;margin-bottom:1em}.admonition-title{font-weight:bold}.admonition.note,.admonition.info,.admonition.important{background:#aef}.admonition.todo,.admonition.versionadded,.admonition.tip,.admonition.hint{background:#dfd}.admonition.warning,.admonition.versionchanged,.admonition.deprecated{background:#fd4}.admonition.error,.admonition.danger,.admonition.caution{background:lightpink}</style> <style media="screen and (min-width: 700px)">@media screen and (min-width:700px){#sidebar{width:30%;height:100vh;overflow:auto;position:sticky;top:0}#content{width:70%;max-width:100ch;padding:3em 4em;border-left:1px solid #ddd}pre code{font-size:1em}.item .name{font-size:1em}main{display:flex;flex-direction:row-reverse;justify-content:flex-end}.toc ul ul,#index ul{padding-left:1.5em}.toc > ul > li{margin-top:.5em}}</style> <style media="print">@media print{#sidebar h1{page-break-before:always}.source{display:none}}@media print{*{background:transparent !important;color:#000 !important;box-shadow:none !important;text-shadow:none !important}a[href]:after{content:" (" attr(href) ")";font-size:90%}a[href][title]:after{content:none}abbr[title]:after{content:" (" attr(title) ")"}.ir a:after,a[href^="javascript:"]:after,a[href^="#"]:after{content:""}pre,blockquote{border:1px solid #999;page-break-inside:avoid}thead{display:table-header-group}tr,img{page-break-inside:avoid}img{max-width:100% !important}@page{margin:0.5cm}p,h2,h3{orphans:3;widows:3}h1,h2,h3,h4,h5,h6{page-break-after:avoid}}</style> <script defer src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/10.1.1/highlight.min.js" integrity="sha256-Uv3H6lx7dJmRfRvH8TH6kJD1TSK1aFcwgx+mdg3epi8=" crossorigin></script> <script>window.addEventListener('DOMContentLoaded', () => hljs.initHighlighting())</script> </head> <body> <main> <article id="content"> <header> <h1 class="title">Module <code>pluginconf.flit</code></h1> </header> <section id="section-intro"> <p>monkeypatches flint to use pluginconf sources for packaging</p> </section> <section> </section> <section> </section> <section> <h2 class="section-title" id="header-functions">Functions</h2> <dl> <dt id="pluginconf.flit.inject"><code class="name flex"> <span>def <span class="ident">inject</span></span>(<span>where)</span> </code></dt> <dd> <div class="desc"><p>monkeypatch into module</p></div> </dd> <dt id="pluginconf.flit.pmd_meta"><code class="name flex"> <span>def <span class="ident">pmd_meta</span></span>(<span>pmd, ini)</span> </code></dt> <dd> <div class="desc"><p>enjoin PMD fields with flit meta data</p></div> </dd> </dl> </section> <section> </section> </article> <nav id="sidebar"> <h1>Index</h1> <div class="toc"> <ul></ul> </div> <ul id="index"> <li><h3>Super-module</h3> <ul> <li><code><a title="pluginconf" href="index.html">pluginconf</a></code></li> </ul> </li> <li><h3><a href="#header-functions">Functions</a></h3> <ul class=""> <li><code><a title="pluginconf.flit.inject" href="#pluginconf.flit.inject">inject</a></code></li> <li><code><a title="pluginconf.flit.pmd_meta" href="#pluginconf.flit.pmd_meta">pmd_meta</a></code></li> </ul> </li> </ul> </nav> </main> <footer id="footer"> <p>Generated by <a href="https://pdoc3.github.io/pdoc" title="pdoc: Python API documentation generator"><cite>pdoc</cite> 0.10.0</a>.</p> </footer> </body> </html> |
Added html/gui.html version [4c36b56296].
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 | <!doctype html> <html lang="en"> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1" /> <meta name="generator" content="pdoc 0.10.0" /> <title>pluginconf.gui API documentation</title> <meta name="description" content="PySimpleGUI window to populate config dict via plugin options" /> <link rel="preload stylesheet" as="style" href="https://cdnjs.cloudflare.com/ajax/libs/10up-sanitize.css/11.0.1/sanitize.min.css" integrity="sha256-PK9q560IAAa6WVRRh76LtCaI8pjTJ2z11v0miyNNjrs=" crossorigin> <link rel="preload stylesheet" as="style" href="https://cdnjs.cloudflare.com/ajax/libs/10up-sanitize.css/11.0.1/typography.min.css" integrity="sha256-7l/o7C8jubJiy74VsKTidCy1yBkRtiUGbVkYBylBqUg=" crossorigin> <link rel="stylesheet preload" as="style" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/10.1.1/styles/github.min.css" crossorigin> <style>:root{--highlight-color:#fe9}.flex{display:flex !important}body{line-height:1.5em}#content{padding:20px}#sidebar{padding:30px;overflow:hidden}#sidebar > *:last-child{margin-bottom:2cm}.http-server-breadcrumbs{font-size:130%;margin:0 0 15px 0}#footer{font-size:.75em;padding:5px 30px;border-top:1px solid #ddd;text-align:right}#footer p{margin:0 0 0 1em;display:inline-block}#footer p:last-child{margin-right:30px}h1,h2,h3,h4,h5{font-weight:300}h1{font-size:2.5em;line-height:1.1em}h2{font-size:1.75em;margin:1em 0 .50em 0}h3{font-size:1.4em;margin:25px 0 10px 0}h4{margin:0;font-size:105%}h1:target,h2:target,h3:target,h4:target,h5:target,h6:target{background:var(--highlight-color);padding:.2em 0}a{color:#058;text-decoration:none;transition:color .3s ease-in-out}a:hover{color:#e82}.title code{font-weight:bold}h2[id^="header-"]{margin-top:2em}.ident{color:#900}pre code{background:#f8f8f8;font-size:.8em;line-height:1.4em}code{background:#f2f2f1;padding:1px 4px;overflow-wrap:break-word}h1 code{background:transparent}pre{background:#f8f8f8;border:0;border-top:1px solid #ccc;border-bottom:1px solid #ccc;margin:1em 0;padding:1ex}#http-server-module-list{display:flex;flex-flow:column}#http-server-module-list div{display:flex}#http-server-module-list dt{min-width:10%}#http-server-module-list p{margin-top:0}.toc ul,#index{list-style-type:none;margin:0;padding:0}#index code{background:transparent}#index h3{border-bottom:1px solid #ddd}#index ul{padding:0}#index h4{margin-top:.6em;font-weight:bold}@media (min-width:200ex){#index .two-column{column-count:2}}@media (min-width:300ex){#index .two-column{column-count:3}}dl{margin-bottom:2em}dl dl:last-child{margin-bottom:4em}dd{margin:0 0 1em 3em}#header-classes + dl > dd{margin-bottom:3em}dd dd{margin-left:2em}dd p{margin:10px 0}.name{background:#eee;font-weight:bold;font-size:.85em;padding:5px 10px;display:inline-block;min-width:40%}.name:hover{background:#e0e0e0}dt:target .name{background:var(--highlight-color)}.name > span:first-child{white-space:nowrap}.name.class > span:nth-child(2){margin-left:.4em}.inherited{color:#999;border-left:5px solid #eee;padding-left:1em}.inheritance em{font-style:normal;font-weight:bold}.desc h2{font-weight:400;font-size:1.25em}.desc h3{font-size:1em}.desc dt code{background:inherit}.source summary,.git-link-div{color:#666;text-align:right;font-weight:400;font-size:.8em;text-transform:uppercase}.source summary > *{white-space:nowrap;cursor:pointer}.git-link{color:inherit;margin-left:1em}.source pre{max-height:500px;overflow:auto;margin:0}.source pre code{font-size:12px;overflow:visible}.hlist{list-style:none}.hlist li{display:inline}.hlist li:after{content:',\2002'}.hlist li:last-child:after{content:none}.hlist .hlist{display:inline;padding-left:1em}img{max-width:100%}td{padding:0 .5em}.admonition{padding:.1em .5em;margin-bottom:1em}.admonition-title{font-weight:bold}.admonition.note,.admonition.info,.admonition.important{background:#aef}.admonition.todo,.admonition.versionadded,.admonition.tip,.admonition.hint{background:#dfd}.admonition.warning,.admonition.versionchanged,.admonition.deprecated{background:#fd4}.admonition.error,.admonition.danger,.admonition.caution{background:lightpink}</style> <style media="screen and (min-width: 700px)">@media screen and (min-width:700px){#sidebar{width:30%;height:100vh;overflow:auto;position:sticky;top:0}#content{width:70%;max-width:100ch;padding:3em 4em;border-left:1px solid #ddd}pre code{font-size:1em}.item .name{font-size:1em}main{display:flex;flex-direction:row-reverse;justify-content:flex-end}.toc ul ul,#index ul{padding-left:1.5em}.toc > ul > li{margin-top:.5em}}</style> <style media="print">@media print{#sidebar h1{page-break-before:always}.source{display:none}}@media print{*{background:transparent !important;color:#000 !important;box-shadow:none !important;text-shadow:none !important}a[href]:after{content:" (" attr(href) ")";font-size:90%}a[href][title]:after{content:none}abbr[title]:after{content:" (" attr(title) ")"}.ir a:after,a[href^="javascript:"]:after,a[href^="#"]:after{content:""}pre,blockquote{border:1px solid #999;page-break-inside:avoid}thead{display:table-header-group}tr,img{page-break-inside:avoid}img{max-width:100% !important}@page{margin:0.5cm}p,h2,h3{orphans:3;widows:3}h1,h2,h3,h4,h5,h6{page-break-after:avoid}}</style> <script defer src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/10.1.1/highlight.min.js" integrity="sha256-Uv3H6lx7dJmRfRvH8TH6kJD1TSK1aFcwgx+mdg3epi8=" crossorigin></script> <script>window.addEventListener('DOMContentLoaded', () => hljs.initHighlighting())</script> </head> <body> <main> <article id="content"> <header> <h1 class="title">Module <code>pluginconf.gui</code></h1> </header> <section id="section-intro"> <p>PySimpleGUI window to populate config dict via plugin options</p> </section> <section> </section> <section> </section> <section> <h2 class="section-title" id="header-functions">Functions</h2> <dl> <dt id="pluginconf.gui.option_entry"><code class="name flex"> <span>def <span class="ident">option_entry</span></span>(<span>o, config)</span> </code></dt> <dd> <div class="desc"></div> </dd> <dt id="pluginconf.gui.plugin_entry"><code class="name flex"> <span>def <span class="ident">plugin_entry</span></span>(<span>e, plugin_states)</span> </code></dt> <dd> <div class="desc"></div> </dd> <dt id="pluginconf.gui.plugin_layout"><code class="name flex"> <span>def <span class="ident">plugin_layout</span></span>(<span>ls, config, plugin_states, opt_label=False)</span> </code></dt> <dd> <div class="desc"></div> </dd> <dt id="pluginconf.gui.read_options"><code class="name flex"> <span>def <span class="ident">read_options</span></span>(<span>files)</span> </code></dt> <dd> <div class="desc"></div> </dd> <dt id="pluginconf.gui.window"><code class="name flex"> <span>def <span class="ident">window</span></span>(<span>config={}, plugin_states={}, files=['*/*.py'], plugins={}, opt_label=False, theme='DefaultNoMoreNagging', **kwargs)</span> </code></dt> <dd> <div class="desc"><p>Reads *.py files and crafts a settings dialog from meta data.</p> <h2 id="parameters">Parameters</h2> <dl> <dt><strong><code>config</code></strong> : <code>dict</code></dt> <dd>Config settings, updated after dialog completion</dd> <dt><strong><code>plugin_states</code></strong> : <code>dict</code></dt> <dd>Plugin activation states, also input/output</dd> <dt><strong><code>files</code></strong> : <code>list</code></dt> <dd>Glob list of *.py files to extract meta definitions from</dd> <dt><strong><code>plugins</code></strong> : <code>dict</code></dt> <dd>Alternatively to files=[] list, a preparsed list of pluginmeta+config dicts can be injected</dd> <dt><strong><code>opt_label</code></strong> : <code>bool</code></dt> <dd>Show config name= as label</dd> <dt><strong><code>**kwargs</code></strong> : <code>dict</code></dt> <dd>Other options are passed on to PySimpleGUI</dd> </dl></div> </dd> <dt id="pluginconf.gui.wrap"><code class="name flex"> <span>def <span class="ident">wrap</span></span>(<span>s, w=50)</span> </code></dt> <dd> <div class="desc"></div> </dd> </dl> </section> <section> <h2 class="section-title" id="header-classes">Classes</h2> <dl> <dt id="pluginconf.gui.cast"><code class="flex name class"> <span>class <span class="ident">cast</span></span> </code></dt> <dd> <div class="desc"></div> <h3>Static methods</h3> <dl> <dt id="pluginconf.gui.cast.bool"><code class="name flex"> <span>def <span class="ident">bool</span></span>(<span>v)</span> </code></dt> <dd> <div class="desc"></div> </dd> <dt id="pluginconf.gui.cast.fromtype"><code class="name flex"> <span>def <span class="ident">fromtype</span></span>(<span>v, opt)</span> </code></dt> <dd> <div class="desc"></div> </dd> <dt id="pluginconf.gui.cast.int"><code class="name flex"> <span>def <span class="ident">int</span></span>(<span>v)</span> </code></dt> <dd> <div class="desc"></div> </dd> </dl> </dd> </dl> </section> </article> <nav id="sidebar"> <h1>Index</h1> <div class="toc"> <ul></ul> </div> <ul id="index"> <li><h3>Super-module</h3> <ul> <li><code><a title="pluginconf" href="index.html">pluginconf</a></code></li> </ul> </li> <li><h3><a href="#header-functions">Functions</a></h3> <ul class="two-column"> <li><code><a title="pluginconf.gui.option_entry" href="#pluginconf.gui.option_entry">option_entry</a></code></li> <li><code><a title="pluginconf.gui.plugin_entry" href="#pluginconf.gui.plugin_entry">plugin_entry</a></code></li> <li><code><a title="pluginconf.gui.plugin_layout" href="#pluginconf.gui.plugin_layout">plugin_layout</a></code></li> <li><code><a title="pluginconf.gui.read_options" href="#pluginconf.gui.read_options">read_options</a></code></li> <li><code><a title="pluginconf.gui.window" href="#pluginconf.gui.window">window</a></code></li> <li><code><a title="pluginconf.gui.wrap" href="#pluginconf.gui.wrap">wrap</a></code></li> </ul> </li> <li><h3><a href="#header-classes">Classes</a></h3> <ul> <li> <h4><code><a title="pluginconf.gui.cast" href="#pluginconf.gui.cast">cast</a></code></h4> <ul class=""> <li><code><a title="pluginconf.gui.cast.bool" href="#pluginconf.gui.cast.bool">bool</a></code></li> <li><code><a title="pluginconf.gui.cast.fromtype" href="#pluginconf.gui.cast.fromtype">fromtype</a></code></li> <li><code><a title="pluginconf.gui.cast.int" href="#pluginconf.gui.cast.int">int</a></code></li> </ul> </li> </ul> </li> </ul> </nav> </main> <footer id="footer"> <p>Generated by <a href="https://pdoc3.github.io/pdoc" title="pdoc: Python API documentation generator"><cite>pdoc</cite> 0.10.0</a>.</p> </footer> </body> </html> |
Added html/index.html version [7e4dfa2402].
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 | <!doctype html> <html lang="en"> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1" /> <meta name="generator" content="pdoc 0.10.0" /> <title>pluginconf API documentation</title> <meta name="description" content="Plugin meta extraction and module lookup" /> <link rel="preload stylesheet" as="style" href="https://cdnjs.cloudflare.com/ajax/libs/10up-sanitize.css/11.0.1/sanitize.min.css" integrity="sha256-PK9q560IAAa6WVRRh76LtCaI8pjTJ2z11v0miyNNjrs=" crossorigin> <link rel="preload stylesheet" as="style" href="https://cdnjs.cloudflare.com/ajax/libs/10up-sanitize.css/11.0.1/typography.min.css" integrity="sha256-7l/o7C8jubJiy74VsKTidCy1yBkRtiUGbVkYBylBqUg=" crossorigin> <link rel="stylesheet preload" as="style" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/10.1.1/styles/github.min.css" crossorigin> <style>:root{--highlight-color:#fe9}.flex{display:flex !important}body{line-height:1.5em}#content{padding:20px}#sidebar{padding:30px;overflow:hidden}#sidebar > *:last-child{margin-bottom:2cm}.http-server-breadcrumbs{font-size:130%;margin:0 0 15px 0}#footer{font-size:.75em;padding:5px 30px;border-top:1px solid #ddd;text-align:right}#footer p{margin:0 0 0 1em;display:inline-block}#footer p:last-child{margin-right:30px}h1,h2,h3,h4,h5{font-weight:300}h1{font-size:2.5em;line-height:1.1em}h2{font-size:1.75em;margin:1em 0 .50em 0}h3{font-size:1.4em;margin:25px 0 10px 0}h4{margin:0;font-size:105%}h1:target,h2:target,h3:target,h4:target,h5:target,h6:target{background:var(--highlight-color);padding:.2em 0}a{color:#058;text-decoration:none;transition:color .3s ease-in-out}a:hover{color:#e82}.title code{font-weight:bold}h2[id^="header-"]{margin-top:2em}.ident{color:#900}pre code{background:#f8f8f8;font-size:.8em;line-height:1.4em}code{background:#f2f2f1;padding:1px 4px;overflow-wrap:break-word}h1 code{background:transparent}pre{background:#f8f8f8;border:0;border-top:1px solid #ccc;border-bottom:1px solid #ccc;margin:1em 0;padding:1ex}#http-server-module-list{display:flex;flex-flow:column}#http-server-module-list div{display:flex}#http-server-module-list dt{min-width:10%}#http-server-module-list p{margin-top:0}.toc ul,#index{list-style-type:none;margin:0;padding:0}#index code{background:transparent}#index h3{border-bottom:1px solid #ddd}#index ul{padding:0}#index h4{margin-top:.6em;font-weight:bold}@media (min-width:200ex){#index .two-column{column-count:2}}@media (min-width:300ex){#index .two-column{column-count:3}}dl{margin-bottom:2em}dl dl:last-child{margin-bottom:4em}dd{margin:0 0 1em 3em}#header-classes + dl > dd{margin-bottom:3em}dd dd{margin-left:2em}dd p{margin:10px 0}.name{background:#eee;font-weight:bold;font-size:.85em;padding:5px 10px;display:inline-block;min-width:40%}.name:hover{background:#e0e0e0}dt:target .name{background:var(--highlight-color)}.name > span:first-child{white-space:nowrap}.name.class > span:nth-child(2){margin-left:.4em}.inherited{color:#999;border-left:5px solid #eee;padding-left:1em}.inheritance em{font-style:normal;font-weight:bold}.desc h2{font-weight:400;font-size:1.25em}.desc h3{font-size:1em}.desc dt code{background:inherit}.source summary,.git-link-div{color:#666;text-align:right;font-weight:400;font-size:.8em;text-transform:uppercase}.source summary > *{white-space:nowrap;cursor:pointer}.git-link{color:inherit;margin-left:1em}.source pre{max-height:500px;overflow:auto;margin:0}.source pre code{font-size:12px;overflow:visible}.hlist{list-style:none}.hlist li{display:inline}.hlist li:after{content:',\2002'}.hlist li:last-child:after{content:none}.hlist .hlist{display:inline;padding-left:1em}img{max-width:100%}td{padding:0 .5em}.admonition{padding:.1em .5em;margin-bottom:1em}.admonition-title{font-weight:bold}.admonition.note,.admonition.info,.admonition.important{background:#aef}.admonition.todo,.admonition.versionadded,.admonition.tip,.admonition.hint{background:#dfd}.admonition.warning,.admonition.versionchanged,.admonition.deprecated{background:#fd4}.admonition.error,.admonition.danger,.admonition.caution{background:lightpink}</style> <style media="screen and (min-width: 700px)">@media screen and (min-width:700px){#sidebar{width:30%;height:100vh;overflow:auto;position:sticky;top:0}#content{width:70%;max-width:100ch;padding:3em 4em;border-left:1px solid #ddd}pre code{font-size:1em}.item .name{font-size:1em}main{display:flex;flex-direction:row-reverse;justify-content:flex-end}.toc ul ul,#index ul{padding-left:1.5em}.toc > ul > li{margin-top:.5em}}</style> <style media="print">@media print{#sidebar h1{page-break-before:always}.source{display:none}}@media print{*{background:transparent !important;color:#000 !important;box-shadow:none !important;text-shadow:none !important}a[href]:after{content:" (" attr(href) ")";font-size:90%}a[href][title]:after{content:none}abbr[title]:after{content:" (" attr(title) ")"}.ir a:after,a[href^="javascript:"]:after,a[href^="#"]:after{content:""}pre,blockquote{border:1px solid #999;page-break-inside:avoid}thead{display:table-header-group}tr,img{page-break-inside:avoid}img{max-width:100% !important}@page{margin:0.5cm}p,h2,h3{orphans:3;widows:3}h1,h2,h3,h4,h5,h6{page-break-after:avoid}}</style> <script defer src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/10.1.1/highlight.min.js" integrity="sha256-Uv3H6lx7dJmRfRvH8TH6kJD1TSK1aFcwgx+mdg3epi8=" crossorigin></script> <script>window.addEventListener('DOMContentLoaded', () => hljs.initHighlighting())</script> </head> <body> <main> <article id="content"> <header> <h1 class="title">Package <code>pluginconf</code></h1> </header> <section id="section-intro"> <p>Plugin meta extraction and module lookup</p> </section> <section> <h2 class="section-title" id="header-submodules">Sub-modules</h2> <dl> <dt><code class="name"><a title="pluginconf.depends" href="depends.html">pluginconf.depends</a></code></dt> <dd> <div class="desc"><p>Dependency validation and consistency checker for updates</p></div> </dd> <dt><code class="name"><a title="pluginconf.flit" href="flit.html">pluginconf.flit</a></code></dt> <dd> <div class="desc"><p>monkeypatches flint to use pluginconf sources for packaging</p></div> </dd> <dt><code class="name"><a title="pluginconf.gui" href="gui.html">pluginconf.gui</a></code></dt> <dd> <div class="desc"><p>PySimpleGUI window to populate config dict via plugin options</p></div> </dd> <dt><code class="name"><a title="pluginconf.setup" href="setup.html">pluginconf.setup</a></code></dt> <dd> <div class="desc"><p>Simulates setuptools.setup()</p></div> </dd> </dl> </section> <section> </section> <section> <h2 class="section-title" id="header-functions">Functions</h2> <dl> <dt id="pluginconf.add_plugin_defaults"><code class="name flex"> <span>def <span class="ident">add_plugin_defaults</span></span>(<span>conf_options, conf_plugins, meta, module='')</span> </code></dt> <dd> <div class="desc"><p>Utility function which collect defaults from plugin meta data to a config store. Which in the case of streamtuner2 is really just a dictionary <code>conf{}</code> and a plugin list in <code>conf.plugins{}</code>.</p> <h2 id="parameters">Parameters</h2> <dl> <dt><strong><code>conf_options</code></strong> : <code>dict : input/output</code></dt> <dd>storage for amassed options</dd> <dt><strong><code>conf_plugins</code></strong> : <code>dict : input/output</code></dt> <dd>enable status based on plugin state/priority:</dd> <dt><strong><code>meta</code></strong> : <code>dict</code></dt> <dd>input plugin meta data (invoke once per plugin)</dd> <dt><strong><code>module</code></strong> : <code>str</code></dt> <dd>basename of meta: blocks plugin file</dd> </dl></div> </dd> <dt id="pluginconf.get_data"><code class="name flex"> <span>def <span class="ident">get_data</span></span>(<span>filename, decode=False, gzip=False, file_base=None)</span> </code></dt> <dd> <div class="desc"><p>Fetches file content from install path or from within PYZ archive. This is just an alias and convenience wrapper for pkgutil.get_data(). Utilizes the module_base / plugin_base as top-level reference.</p> <h2 id="parameters">Parameters</h2> <dl> <dt><strong><code>filename</code></strong> : <code> str</code></dt> <dd>filename in pyz or bundle</dd> <dt><strong><code>decode</code></strong> : <code>bool</code></dt> <dd>text file decoding utf-8</dd> <dt><strong><code>gzip</code></strong> : <code>bool</code></dt> <dd>automatic gzdecode</dd> <dt><strong><code>file_base</code></strong> : <code>list</code></dt> <dd>alternative base module reference</dd> </dl> <h2 id="returns">Returns</h2> <dl> <dt><strong><code>str</code></strong> : <code>file contents</code></dt> <dd> </dd> </dl></div> </dd> <dt id="pluginconf.module_list"><code class="name flex"> <span>def <span class="ident">module_list</span></span>(<span>extra_paths=None)</span> </code></dt> <dd> <div class="desc"><p>Search through ./plugins/ (and other configured plugin_base names → paths) and get module basenames.</p> <h2 id="parameters">Parameters</h2> <dl> <dt><strong><code>extra_paths</code></strong> : <code>list</code></dt> <dd>in addition to plugin_base list</dd> </dl> <h2 id="returns">Returns</h2> <dl> <dt><strong><code>list</code></strong> : <code>names</code> of <code>found plugins</code></dt> <dd> </dd> </dl></div> </dd> <dt id="pluginconf.plugin_meta"><code class="name flex"> <span>def <span class="ident">plugin_meta</span></span>(<span>filename=None, src=None, module=None, frame=1, **kwargs)</span> </code></dt> <dd> <div class="desc"><p>Extract plugin meta data block from different sources:</p> <h2 id="parameters">Parameters</h2> <dl> <dt><strong><code>filename</code></strong> : <code>str</code></dt> <dd>read literal files, or .pyz contents</dd> <dt><strong><code>src</code></strong> : <code>str</code></dt> <dd>from already uncovered script code</dd> <dt><strong><code>module</code></strong> : <code>str</code></dt> <dd>lookup per pkgutil, from plugin_base or top-level modules</dd> <dt><strong><code>frame</code></strong> : <code>int</code></dt> <dd>extract comment header of caller (default)</dd> <dt><strong><code>extra_base</code></strong> : <code>list</code></dt> <dd>additional search directories</dd> <dt><strong><code>max_length</code></strong> : <code>list</code></dt> <dd>maximum size to read from files</dd> </dl> <h2 id="returns">Returns</h2> <dl> <dt><strong><code>dict</code></strong> : <code>key-value pairs</code> of <code>comment fields, config: preparsed</code></dt> <dd> </dd> </dl></div> </dd> </dl> </section> <section> </section> </article> <nav id="sidebar"> <h1>Index</h1> <div class="toc"> <ul></ul> </div> <ul id="index"> <li><h3><a href="#header-submodules">Sub-modules</a></h3> <ul> <li><code><a title="pluginconf.depends" href="depends.html">pluginconf.depends</a></code></li> <li><code><a title="pluginconf.flit" href="flit.html">pluginconf.flit</a></code></li> <li><code><a title="pluginconf.gui" href="gui.html">pluginconf.gui</a></code></li> <li><code><a title="pluginconf.setup" href="setup.html">pluginconf.setup</a></code></li> </ul> </li> <li><h3><a href="#header-functions">Functions</a></h3> <ul class=""> <li><code><a title="pluginconf.add_plugin_defaults" href="#pluginconf.add_plugin_defaults">add_plugin_defaults</a></code></li> <li><code><a title="pluginconf.get_data" href="#pluginconf.get_data">get_data</a></code></li> <li><code><a title="pluginconf.module_list" href="#pluginconf.module_list">module_list</a></code></li> <li><code><a title="pluginconf.plugin_meta" href="#pluginconf.plugin_meta">plugin_meta</a></code></li> </ul> </li> </ul> </nav> </main> <footer id="footer"> <p>Generated by <a href="https://pdoc3.github.io/pdoc" title="pdoc: Python API documentation generator"><cite>pdoc</cite> 0.10.0</a>.</p> </footer> </body> </html> |
Added html/setup.html version [e58aa12886].
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 | <!doctype html> <html lang="en"> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1" /> <meta name="generator" content="pdoc 0.10.0" /> <title>pluginconf.setup API documentation</title> <meta name="description" content="Simulates setuptools.setup()" /> <link rel="preload stylesheet" as="style" href="https://cdnjs.cloudflare.com/ajax/libs/10up-sanitize.css/11.0.1/sanitize.min.css" integrity="sha256-PK9q560IAAa6WVRRh76LtCaI8pjTJ2z11v0miyNNjrs=" crossorigin> <link rel="preload stylesheet" as="style" href="https://cdnjs.cloudflare.com/ajax/libs/10up-sanitize.css/11.0.1/typography.min.css" integrity="sha256-7l/o7C8jubJiy74VsKTidCy1yBkRtiUGbVkYBylBqUg=" crossorigin> <link rel="stylesheet preload" as="style" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/10.1.1/styles/github.min.css" crossorigin> <style>:root{--highlight-color:#fe9}.flex{display:flex !important}body{line-height:1.5em}#content{padding:20px}#sidebar{padding:30px;overflow:hidden}#sidebar > *:last-child{margin-bottom:2cm}.http-server-breadcrumbs{font-size:130%;margin:0 0 15px 0}#footer{font-size:.75em;padding:5px 30px;border-top:1px solid #ddd;text-align:right}#footer p{margin:0 0 0 1em;display:inline-block}#footer p:last-child{margin-right:30px}h1,h2,h3,h4,h5{font-weight:300}h1{font-size:2.5em;line-height:1.1em}h2{font-size:1.75em;margin:1em 0 .50em 0}h3{font-size:1.4em;margin:25px 0 10px 0}h4{margin:0;font-size:105%}h1:target,h2:target,h3:target,h4:target,h5:target,h6:target{background:var(--highlight-color);padding:.2em 0}a{color:#058;text-decoration:none;transition:color .3s ease-in-out}a:hover{color:#e82}.title code{font-weight:bold}h2[id^="header-"]{margin-top:2em}.ident{color:#900}pre code{background:#f8f8f8;font-size:.8em;line-height:1.4em}code{background:#f2f2f1;padding:1px 4px;overflow-wrap:break-word}h1 code{background:transparent}pre{background:#f8f8f8;border:0;border-top:1px solid #ccc;border-bottom:1px solid #ccc;margin:1em 0;padding:1ex}#http-server-module-list{display:flex;flex-flow:column}#http-server-module-list div{display:flex}#http-server-module-list dt{min-width:10%}#http-server-module-list p{margin-top:0}.toc ul,#index{list-style-type:none;margin:0;padding:0}#index code{background:transparent}#index h3{border-bottom:1px solid #ddd}#index ul{padding:0}#index h4{margin-top:.6em;font-weight:bold}@media (min-width:200ex){#index .two-column{column-count:2}}@media (min-width:300ex){#index .two-column{column-count:3}}dl{margin-bottom:2em}dl dl:last-child{margin-bottom:4em}dd{margin:0 0 1em 3em}#header-classes + dl > dd{margin-bottom:3em}dd dd{margin-left:2em}dd p{margin:10px 0}.name{background:#eee;font-weight:bold;font-size:.85em;padding:5px 10px;display:inline-block;min-width:40%}.name:hover{background:#e0e0e0}dt:target .name{background:var(--highlight-color)}.name > span:first-child{white-space:nowrap}.name.class > span:nth-child(2){margin-left:.4em}.inherited{color:#999;border-left:5px solid #eee;padding-left:1em}.inheritance em{font-style:normal;font-weight:bold}.desc h2{font-weight:400;font-size:1.25em}.desc h3{font-size:1em}.desc dt code{background:inherit}.source summary,.git-link-div{color:#666;text-align:right;font-weight:400;font-size:.8em;text-transform:uppercase}.source summary > *{white-space:nowrap;cursor:pointer}.git-link{color:inherit;margin-left:1em}.source pre{max-height:500px;overflow:auto;margin:0}.source pre code{font-size:12px;overflow:visible}.hlist{list-style:none}.hlist li{display:inline}.hlist li:after{content:',\2002'}.hlist li:last-child:after{content:none}.hlist .hlist{display:inline;padding-left:1em}img{max-width:100%}td{padding:0 .5em}.admonition{padding:.1em .5em;margin-bottom:1em}.admonition-title{font-weight:bold}.admonition.note,.admonition.info,.admonition.important{background:#aef}.admonition.todo,.admonition.versionadded,.admonition.tip,.admonition.hint{background:#dfd}.admonition.warning,.admonition.versionchanged,.admonition.deprecated{background:#fd4}.admonition.error,.admonition.danger,.admonition.caution{background:lightpink}</style> <style media="screen and (min-width: 700px)">@media screen and (min-width:700px){#sidebar{width:30%;height:100vh;overflow:auto;position:sticky;top:0}#content{width:70%;max-width:100ch;padding:3em 4em;border-left:1px solid #ddd}pre code{font-size:1em}.item .name{font-size:1em}main{display:flex;flex-direction:row-reverse;justify-content:flex-end}.toc ul ul,#index ul{padding-left:1.5em}.toc > ul > li{margin-top:.5em}}</style> <style media="print">@media print{#sidebar h1{page-break-before:always}.source{display:none}}@media print{*{background:transparent !important;color:#000 !important;box-shadow:none !important;text-shadow:none !important}a[href]:after{content:" (" attr(href) ")";font-size:90%}a[href][title]:after{content:none}abbr[title]:after{content:" (" attr(title) ")"}.ir a:after,a[href^="javascript:"]:after,a[href^="#"]:after{content:""}pre,blockquote{border:1px solid #999;page-break-inside:avoid}thead{display:table-header-group}tr,img{page-break-inside:avoid}img{max-width:100% !important}@page{margin:0.5cm}p,h2,h3{orphans:3;widows:3}h1,h2,h3,h4,h5,h6{page-break-after:avoid}}</style> <script defer src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/10.1.1/highlight.min.js" integrity="sha256-Uv3H6lx7dJmRfRvH8TH6kJD1TSK1aFcwgx+mdg3epi8=" crossorigin></script> <script>window.addEventListener('DOMContentLoaded', () => hljs.initHighlighting())</script> </head> <body> <main> <article id="content"> <header> <h1 class="title">Module <code>pluginconf.setup</code></h1> </header> <section id="section-intro"> <p>Simulates setuptools.setup()</p> </section> <section> </section> <section> </section> <section> <h2 class="section-title" id="header-functions">Functions</h2> <dl> <dt id="pluginconf.setup.get_readme"><code class="name flex"> <span>def <span class="ident">get_readme</span></span>(<span>)</span> </code></dt> <dd> <div class="desc"><p>get README.md contents</p></div> </dd> <dt id="pluginconf.setup.name_to_fn"><code class="name flex"> <span>def <span class="ident">name_to_fn</span></span>(<span>name)</span> </code></dt> <dd> <div class="desc"><p>find primary entry point.py from package name</p></div> </dd> <dt id="pluginconf.setup.setup"><code class="name flex"> <span>def <span class="ident">setup</span></span>(<span>debug=0, **kwargs)</span> </code></dt> <dd> <div class="desc"><p>Wrapper around <code>setuptools.setup()</code> which adds some defaults and plugin meta data import, with two shortcut params:</p> <h2 id="parameters">Parameters</h2> <dl> <dt><strong><code>fn</code></strong> : <code>str</code></dt> <dd>main file "pkg/main.py"</dd> <dt><strong><code>long_description</code></strong> : <code>str</code></dt> <dd>e.g. "README.md", else comment block used</dd> </dl> <p>Other setup() params work as usual, and are passed trough. Notably entry_points= or data_files= can be used, even if they get augmented.</p></div> </dd> </dl> </section> <section> <h2 class="section-title" id="header-classes">Classes</h2> <dl> <dt id="pluginconf.setup.MetaUtils"><code class="flex name class"> <span>class <span class="ident">MetaUtils</span></span> <span>(</span><span>*args, **kwargs)</span> </code></dt> <dd> <div class="desc"><p>convenience access to PMD fields</p></div> <h3>Ancestors</h3> <ul class="hlist"> <li>builtins.dict</li> </ul> <h3>Static methods</h3> <dl> <dt id="pluginconf.setup.MetaUtils.datafiles_man"><code class="name flex"> <span>def <span class="ident">datafiles_man</span></span>(<span>)</span> </code></dt> <dd> <div class="desc"><p>data_files=</p></div> </dd> </dl> <h3>Methods</h3> <dl> <dt id="pluginconf.setup.MetaUtils.classifiers"><code class="name flex"> <span>def <span class="ident">classifiers</span></span>(<span>self)</span> </code></dt> <dd> <div class="desc"><p>classifiers: / keywords: / category:</p></div> </dd> <dt id="pluginconf.setup.MetaUtils.entry_points"><code class="name flex"> <span>def <span class="ident">entry_points</span></span>(<span>self)</span> </code></dt> <dd> <div class="desc"><p>collect console-scripts:</p></div> </dd> <dt id="pluginconf.setup.MetaUtils.extras_require"><code class="name flex"> <span>def <span class="ident">extras_require</span></span>(<span>self)</span> </code></dt> <dd> <div class="desc"><p>suggest: line</p></div> </dd> <dt id="pluginconf.setup.MetaUtils.get_keywords"><code class="name flex"> <span>def <span class="ident">get_keywords</span></span>(<span>self)</span> </code></dt> <dd> <div class="desc"><p>keywords=</p></div> </dd> <dt id="pluginconf.setup.MetaUtils.install_requires"><code class="name flex"> <span>def <span class="ident">install_requires</span></span>(<span>self)</span> </code></dt> <dd> <div class="desc"><p>depends: python:module, pip:module</p></div> </dd> <dt id="pluginconf.setup.MetaUtils.plugin_doc"><code class="name flex"> <span>def <span class="ident">plugin_doc</span></span>(<span>self)</span> </code></dt> <dd> <div class="desc"><p>use comment block</p></div> </dd> <dt id="pluginconf.setup.MetaUtils.project_urls"><code class="name flex"> <span>def <span class="ident">project_urls</span></span>(<span>self, exclude=('url', 'update'))</span> </code></dt> <dd> <div class="desc"><p>other-url: <a href="https://...">https://...</a></p></div> </dd> <dt id="pluginconf.setup.MetaUtils.python_requires"><code class="name flex"> <span>def <span class="ident">python_requires</span></span>(<span>self)</span> </code></dt> <dd> <div class="desc"><p>depends: python >= 3.5</p></div> </dd> <dt id="pluginconf.setup.MetaUtils.trove_license"><code class="name flex"> <span>def <span class="ident">trove_license</span></span>(<span>self)</span> </code></dt> <dd> <div class="desc"><p>license: to License ::</p></div> </dd> <dt id="pluginconf.setup.MetaUtils.trove_status"><code class="name flex"> <span>def <span class="ident">trove_status</span></span>(<span>self)</span> </code></dt> <dd> <div class="desc"><p>state: to DevStatus ::</p></div> </dd> </dl> </dd> </dl> </section> </article> <nav id="sidebar"> <h1>Index</h1> <div class="toc"> <ul></ul> </div> <ul id="index"> <li><h3>Super-module</h3> <ul> <li><code><a title="pluginconf" href="index.html">pluginconf</a></code></li> </ul> </li> <li><h3><a href="#header-functions">Functions</a></h3> <ul class=""> <li><code><a title="pluginconf.setup.get_readme" href="#pluginconf.setup.get_readme">get_readme</a></code></li> <li><code><a title="pluginconf.setup.name_to_fn" href="#pluginconf.setup.name_to_fn">name_to_fn</a></code></li> <li><code><a title="pluginconf.setup.setup" href="#pluginconf.setup.setup">setup</a></code></li> </ul> </li> <li><h3><a href="#header-classes">Classes</a></h3> <ul> <li> <h4><code><a title="pluginconf.setup.MetaUtils" href="#pluginconf.setup.MetaUtils">MetaUtils</a></code></h4> <ul class="two-column"> <li><code><a title="pluginconf.setup.MetaUtils.classifiers" href="#pluginconf.setup.MetaUtils.classifiers">classifiers</a></code></li> <li><code><a title="pluginconf.setup.MetaUtils.datafiles_man" href="#pluginconf.setup.MetaUtils.datafiles_man">datafiles_man</a></code></li> <li><code><a title="pluginconf.setup.MetaUtils.entry_points" href="#pluginconf.setup.MetaUtils.entry_points">entry_points</a></code></li> <li><code><a title="pluginconf.setup.MetaUtils.extras_require" href="#pluginconf.setup.MetaUtils.extras_require">extras_require</a></code></li> <li><code><a title="pluginconf.setup.MetaUtils.get_keywords" href="#pluginconf.setup.MetaUtils.get_keywords">get_keywords</a></code></li> <li><code><a title="pluginconf.setup.MetaUtils.install_requires" href="#pluginconf.setup.MetaUtils.install_requires">install_requires</a></code></li> <li><code><a title="pluginconf.setup.MetaUtils.plugin_doc" href="#pluginconf.setup.MetaUtils.plugin_doc">plugin_doc</a></code></li> <li><code><a title="pluginconf.setup.MetaUtils.project_urls" href="#pluginconf.setup.MetaUtils.project_urls">project_urls</a></code></li> <li><code><a title="pluginconf.setup.MetaUtils.python_requires" href="#pluginconf.setup.MetaUtils.python_requires">python_requires</a></code></li> <li><code><a title="pluginconf.setup.MetaUtils.trove_license" href="#pluginconf.setup.MetaUtils.trove_license">trove_license</a></code></li> <li><code><a title="pluginconf.setup.MetaUtils.trove_status" href="#pluginconf.setup.MetaUtils.trove_status">trove_status</a></code></li> </ul> </li> </ul> </li> </ul> </nav> </main> <footer id="footer"> <p>Generated by <a href="https://pdoc3.github.io/pdoc" title="pdoc: Python API documentation generator"><cite>pdoc</cite> 0.10.0</a>.</p> </footer> </body> </html> |
Modified pluginconf/__init__.py from [a0794eef80] to [874773144e].
︙ | ︙ | |||
158 159 160 161 162 163 164 | def get_data(filename, decode=False, gzip=False, file_base=None): """ Fetches file content from install path or from within PYZ archive. This is just an alias and convenience wrapper for pkgutil.get_data(). Utilizes the module_base / plugin_base as top-level reference. | > > > | > | > | > | > > > > > > > | > > > > | 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 | def get_data(filename, decode=False, gzip=False, file_base=None): """ Fetches file content from install path or from within PYZ archive. This is just an alias and convenience wrapper for pkgutil.get_data(). Utilizes the module_base / plugin_base as top-level reference. Parameters ---------- filename : str filename in pyz or bundle decode : bool text file decoding utf-8 gzip : bool automatic gzdecode file_base : list alternative base module reference Returns ------- str : file contents """ try: data = pkgutil.get_data(file_base or module_base, filename) if gzip: data = gzip_decode(data) if decode: return data.decode("utf-8", errors='ignore') return str(data) except: # log_ERR("get_data() didn't find:", fn, "in", file_base) pass # Plugin name lookup # ‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾ def module_list(extra_paths=None): """ Search through ./plugins/ (and other configured plugin_base names → paths) and get module basenames. Parameters ---------- extra_paths : list in addition to plugin_base list Returns ------- list : names of found plugins """ # Convert plugin_base package names into paths for iter_modules paths = [] for module_or_path in plugin_base: if sys.modules.get(module_or_path): paths += sys.modules[module_or_path].__path__ |
︙ | ︙ | |||
205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 | # Plugin => meta dict # ‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾ def all_plugin_meta(): """ This is a trivial wrapper to assemble a complete dictionary of available/installed plugins. It associates each plugin name with a its meta{} fields. """ return { name: plugin_meta(module=name) for name in module_list() } # Plugin meta data extraction # ‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾ @renamed_arguments({"fn": "filename"}) def plugin_meta(filename=None, src=None, module=None, frame=1, **kwargs): """ Extract plugin meta data block from different sources: | > > > > > > > | > | > | > | > | > | > > > > | 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 | # Plugin => meta dict # ‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾ def all_plugin_meta(): """ This is a trivial wrapper to assemble a complete dictionary of available/installed plugins. It associates each plugin name with a its meta{} fields. Returns ------- dict : names to meta data dict """ return { name: plugin_meta(module=name) for name in module_list() } # Plugin meta data extraction # ‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾ @renamed_arguments({"fn": "filename"}) def plugin_meta(filename=None, src=None, module=None, frame=1, **kwargs): """ Extract plugin meta data block from different sources: Parameters ---------- filename : str read literal files, or .pyz contents src : str from already uncovered script code module : str lookup per pkgutil, from plugin_base or top-level modules frame : int extract comment header of caller (default) extra_base : list additional search directories max_length : list maximum size to read from files Returns ------- dict : key-value pairs of comment fields, config: preparsed """ # Try via pkgutil first, # find any plugins.* modules, or main packages if module: filename = module for base in plugin_base + kwargs.get("extra_base", []): |
︙ | ︙ | |||
274 275 276 277 278 279 280 | @renamed_arguments({"fn": "filename"}) def plugin_meta_extract(src="", filename=None, literal=False): """ Finds the first comment block. Splits key:value header fields from comment. Turns everything into an dict, with some stub fields if absent. | > > > | > | > | | 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 | @renamed_arguments({"fn": "filename"}) def plugin_meta_extract(src="", filename=None, literal=False): """ Finds the first comment block. Splits key:value header fields from comment. Turns everything into an dict, with some stub fields if absent. Parameters ---------- src : str from existing source code filename : str set filename attribute literls : bool just split comment from doc """ # Defaults meta = { "id": os.path.splitext(os.path.basename(filename or ""))[0], "fn": filename, "api": "python", |
︙ | ︙ | |||
323 324 325 326 327 328 329 | # Unpack config: structures # ‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾ def plugin_meta_config(src): """ Further breaks up the meta['config'] descriptor. Creates an array from JSON/YAML option lists. | < < > > > > > > > > > | 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 | # Unpack config: structures # ‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾ def plugin_meta_config(src): """ Further breaks up the meta['config'] descriptor. Creates an array from JSON/YAML option lists. Stubs out name, value, type, description if absent. # config: { name: 'var1', type: text, value: "default, ..." } { name=option2, type=boolean, $value=1, etc. } Parameters ---------- src : str unprocessed config: field Returns ------- list : of option dictionaries """ config = [] for entry in rx.config.findall(src): entry = entry[0] or entry[1] opt = { "type": None, |
︙ | ︙ | |||
461 462 463 464 465 466 467 | # ‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾ def add_plugin_defaults(conf_options, conf_plugins, meta, module=""): """ Utility function which collect defaults from plugin meta data to a config store. Which in the case of streamtuner2 is really just a dictionary `conf{}` and a plugin list in `conf.plugins{}`. | > > > | > | > | > | | 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 | # ‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾ def add_plugin_defaults(conf_options, conf_plugins, meta, module=""): """ Utility function which collect defaults from plugin meta data to a config store. Which in the case of streamtuner2 is really just a dictionary `conf{}` and a plugin list in `conf.plugins{}`. Parameters ---------- conf_options : dict : input/output storage for amassed options conf_plugins : dict : input/output enable status based on plugin state/priority: meta : dict input plugin meta data (invoke once per plugin) module : str basename of meta: blocks plugin file """ # Option defaults, if not yet defined for opt in meta.get("config", []): if "name" not in opt or "value" not in opt: continue _value = opt.get("value", "") |
︙ | ︙ |
Modified pluginconf/depends.py from [1d2be7d94e] to [6e210a4c05].
︙ | ︙ | |||
17 18 19 20 21 22 23 24 25 26 27 28 29 30 | # DependencyValidation().depends()/.valid() # ‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾ # Probes a new plugins` depends: list against installed base modules. # Utilizes each version: fields and allows for virtual modules, or # alternatives and honors alias: names. # import sys import re import pluginconf try: from distutils.spawn import find_executable except ImportError: | > > | 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 | # DependencyValidation().depends()/.valid() # ‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾ # Probes a new plugins` depends: list against installed base modules. # Utilizes each version: fields and allows for virtual modules, or # alternatives and honors alias: names. # """ Dependency validation and consistency checker for updates """ import sys import re import pluginconf try: from distutils.spawn import find_executable except ImportError: |
︙ | ︙ | |||
40 41 42 43 44 45 46 | # Minimal depends: probing # ‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾ class DependencyValidation(object): """ Now this definitely requires customization. Each plugin can carry a list of (soft-) dependency names. | | > > > > > > > > > > > > > > > > > > | 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 | # Minimal depends: probing # ‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾ class DependencyValidation(object): """ Now this definitely requires customization. Each plugin can carry a list of (soft-) dependency names. \# depends: config, appcore >= 2.0, bin:wkhtmltoimage, python < 3.5 Here only in-application modules are honored, system references ignored. Unknown plugin names are also skipped. A real install helper might want to auto-tick them on, etc. This example is just meant for probing downloadable plugins. The .valid() helper only asserts the api: string, or skips existing modules, and if they're more recent. While .depends() compares minimum versions against existing modules. In practice there's little need for full-blown dependency resolving for application-level modules. Attributes ---------- api : list allowed api: identifiers for .valid() stream checks log : logging warning handler have : dict accumulated list of existing/virtual plugins """ """ supported APIs """ api = ["python", "streamtuner2"] """ debugging """ log = logging.getLogger("pluginconf.dependency") # prepare list of known plugins and versions def __init__(self, add={}, core=["st2", "uikit", "config", "action"]): """ Parameters ---------- add : dict name to pmd list of existing/core/virtual plugins (can define versions or own dependencies) core : list name list of virtual plugins """ self.have = { "python": {"version": sys.version} } # inject virtual modules for name, meta in add.items(): if isinstance(meta, bool): |
︙ | ︙ | |||
93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 | if meta.get("alias"): for alias in re.split(r"\s*[,;]\s*", meta["alias"]): self.have[alias] = self.have[name] # basic plugin pre-screening (skip __init__, filter by api:, # exclude installed & same-version plugins) def valid(self, new_plugin): if not "$name" in new_plugin: self.log.warning(".valid() checks online plugin lists, requires $name") id = new_plugin.get("$name", "__invalid") have_ver = self.have.get(id, {}).get("version", "0") if id.find("__") == 0: self.log.debug("wrong/no id") elif new_plugin.get("api") not in self.api: self.log.debug("not in allowed APIs") elif {new_plugin.get("status"), new_plugin.get("priority")} & {"obsolete", "broken"}: self.log.debug("wrong status (obsolete/broken)") elif have_ver >= new_plugin.get("version", "0.0"): self.log.debug("newer version already installed") else: return True # Verify depends: and breaks: against existing plugins/modules def depends(self, plugin): result = True if plugin.get("depends"): result &= self.and_or(self.split(plugin["depends"]), self.have) if plugin.get("breaks"): result &= self.neither(self.split(plugin["breaks"]), self.have) self.log.debug("plugin '%s' matching requirements: %i", plugin["id"], result) return result | > > | 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 | if meta.get("alias"): for alias in re.split(r"\s*[,;]\s*", meta["alias"]): self.have[alias] = self.have[name] # basic plugin pre-screening (skip __init__, filter by api:, # exclude installed & same-version plugins) def valid(self, new_plugin): """ check plugin info from repository stream (fields there $name, $file, $dist, api, id, depends, etc) """ if not "$name" in new_plugin: self.log.warning(".valid() checks online plugin lists, requires $name") id = new_plugin.get("$name", "__invalid") have_ver = self.have.get(id, {}).get("version", "0") if id.find("__") == 0: self.log.debug("wrong/no id") elif new_plugin.get("api") not in self.api: self.log.debug("not in allowed APIs") elif {new_plugin.get("status"), new_plugin.get("priority")} & {"obsolete", "broken"}: self.log.debug("wrong status (obsolete/broken)") elif have_ver >= new_plugin.get("version", "0.0"): self.log.debug("newer version already installed") else: return True # Verify depends: and breaks: against existing plugins/modules def depends(self, plugin): """ test depends: and breaks: """ result = True if plugin.get("depends"): result &= self.and_or(self.split(plugin["depends"]), self.have) if plugin.get("breaks"): result &= self.neither(self.split(plugin["breaks"]), self.have) self.log.debug("plugin '%s' matching requirements: %i", plugin["id"], result) return result |
︙ | ︙ |
Modified pluginconf/flit.py from [7b6634f0e5] to [bc5328f2e0].
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | # encoding: utf-8 # api: pep517 # title: flit backend # description: wraps flit_core.buildapi # version: 0.2 # depends: python:flit (>=3.0, <4.0) # license: BSD-3-Clause # priority: extra # src: ~/.local/lib/python3.8/site-packages/flit_core/ # # This is supposed to become an alternative to pluginconf.setup, # using flit as pep517 build backend. But adding automagic field # lookup of course. # # It can be invoked per `flit-pluginconfig build` and requires # a `pyproject.toml` like: | > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | # encoding: utf-8 # api: pep517 # title: flit backend # description: wraps flit_core.buildapi # version: 0.2 # depends: python:flit (>=3.0, <4.0) # license: BSD-3-Clause # priority: extra # src: ~/.local/lib/python3.8/site-packages/flit_core/ # pylint: disable=unused-import, wrong-import-position, wrong-import-order # # This is supposed to become an alternative to pluginconf.setup, # using flit as pep517 build backend. But adding automagic field # lookup of course. # # It can be invoked per `flit-pluginconfig build` and requires # a `pyproject.toml` like: |
︙ | ︙ | |||
24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 | # #dynamic = ["version", "description"] # # Injecting attributes between ini reading and parameter collection # turned out easier than expanding on flit_core.buildapi functions. # And lastly, this just chains to flit.main() to handle setup and # build steps. # import sys import re import functools import pluginconf import pluginconf.setup as psetup | > > > > > > < > | | | | | | | | | | | | > > > > > > | | | | | | | | | | | | | | < | < | | | | | | | | | < > > | | | | | | | | 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 | # #dynamic = ["version", "description"] # # Injecting attributes between ini reading and parameter collection # turned out easier than expanding on flit_core.buildapi functions. # And lastly, this just chains to flit.main() to handle setup and # build steps. # """ monkeypatches flint to use pluginconf sources for packaging """ import sys import re import functools import flit_core.common import flit_core.config import pluginconf import pluginconf.setup as psetup #-- patchy patch def inject(where): """ monkeypatch into module """ def wrapped(func): setattr(where, func.__name__, func) return wrapped @inject(flit_core.config) def read_flit_config(path): """ read_flit_config() with preset dynamic fields """ ini = flit_core.config.tomli.loads(path.read_text('utf-8')) # make fields dynamic if not "dynamic" in ini["project"]: ini["project"]["dynamic"] = [] for dyn in ['description', 'version']: if dyn in ini["project"]: del ini["project"][dyn] if not dyn in ini["project"]["dynamic"]: ini["project"]["dynamic"].append(dyn) print(ini) # turn it into LoadedConfig return flit_core.config.prep_toml_config(ini, path) # override make_metadata @inject(flit_core.common) def make_metadata(module, ini_info): """ different order, and obviously sources """ meta = { "name": module.name, "provides": [module.name] } meta.update(ini_info.metadata) meta.update( pmd_meta( pluginconf.plugin_meta(filename=module.file), ini_info ) ) if not meta.get("version"): meta.update( flit_core.common.get_info_from_module(module.file, ['version']) ) return flit_core.common.Metadata(meta) # map plugin meta to flit Metadata def pmd_meta(pmd, ini): """ enjoin PMD fields with flit meta data """ pmd = psetup.MetaUtils(pmd) meta = { "summary": pmd.description, "version": pmd.version, "home_page": pmd.url, "author": pmd.author, # should split this into mail and name "author_email": None, "maintainer": None, "maintainer_email": None, "license": pmd.license, # {name=…} "keywords": pmd.get_keywords(), "download_url": None, "requires_python": pmd.python_requires() or ">= 2.7", "platform": pmd.architecture, "supported_platform": (), "classifiers": list(pmd.classifiers()) + pmd.trove_license() + pmd.trove_status(), "provides": (), "requires": pmd.install_requires().get("install_requires") or (), "obsoletes": (), "project_urls": [f"{k}, {v}" for k, v in pmd.project_urls().items()], "provides_dist": (), "requires_dist": pmd.install_requires().get("install_requires") or (), "obsoletes_dist": (), "requires_external": (), "provides_extra": (), } print(meta) # comment/readme for docs in pmd.plugin_doc(), psetup.get_readme(): if docs["long_description"]: meta.update({ # with "long_" prefix cut off k[5:]: v for k, v in docs.items() }) # entry_points are in ini file for section, entries in pmd.entry_points().items(): ini.entrypoints[section] = ini.entrypoints.get(section, {}) for script in entries: ini.entrypoints[section].update( dict(re.findall("(.+)=(.+)", script)) ) print(ini.entrypoints) # strip empty entries return {k: v for k, v in meta.items() if v} #-- buildapi from flit_core.buildapi import ( # These have to be late imports; else they'll |
︙ | ︙ |
Modified pluginconf/gui.py from [9f2d3ecd14] to [a9823722c2].
︙ | ︙ | |||
15 16 17 18 19 20 21 22 23 24 25 26 27 28 | # # jsoncfg = {} # pluginconf.gui.window(jsoncfg, {}, ["plugins/*.py"]) # # Very crude, and not as many widgets as the Gtk/St2 implementation. # Supports type: str, bool, select, int, dict, text config: options. # import PySimpleGUI as sg import pluginconf import glob, json, os, re, textwrap | > > | 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | # # jsoncfg = {} # pluginconf.gui.window(jsoncfg, {}, ["plugins/*.py"]) # # Very crude, and not as many widgets as the Gtk/St2 implementation. # Supports type: str, bool, select, int, dict, text config: options. # """ PySimpleGUI window to populate config dict via plugin options """ import PySimpleGUI as sg import pluginconf import glob, json, os, re, textwrap |
︙ | ︙ |
Modified pluginconf/setup.py from [786122b150] to [9534c97f04].
1 2 | # encoding: utf-8 # api: setuptools | | > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | # encoding: utf-8 # api: setuptools ##type: functions # title: setup() wrapper # description: utilizes PMD to populate some package fields # version: 0.4 # license: PD # pylint: disable=line-too-long # # Utilizes plugin meta data to cut down setup.py incantations # to basically just: # # from pluginconf.setup import setup # setup( # fn="pluginconf/__init__.py" |
︙ | ︙ | |||
31 32 33 34 35 36 37 | # # type: classifier # # category: classifier # # keywords: tag, tag # # classifiers: tag, trove, shortcuts # # doc-format: text/markdown # # # # Long description used in lieu of README... | | > > | > > > | > | | | | | > > > > > > > > | | | | | | | | | | | | | | | | | | | | | | | | | | | < < < < > > > > | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | > | | | | | | | | | | | | | | | | | > > > | | > | > | | | | | | | | | | > | | | | | | | | | | | | | | < | | 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 | # # type: classifier # # category: classifier # # keywords: tag, tag # # classifiers: tag, trove, shortcuts # # doc-format: text/markdown # # # # Long description used in lieu of README... # # A README.* will be read if present, else PMD comment used. # Classifiers and license matching is very crude, just for # the most common cases. Type:, Category: and Classifiers: # or Keywords: are also scanned for trove classifers. # """ Simulates setuptools.setup() """ import os import re import glob import pprint import setuptools import pluginconf def name_to_fn(name): """ find primary entry point.py from package name """ for pfx in "", "src/", "src/"+name+"/": for sfx in ".py", "/__init__.py": if os.path.exists(pfx+name+sfx): return pfx+name+sfx return "" def get_readme(): """ get README.md contents """ for filename, mime in ("README.md", "text/markdown"), ("README.rst", "text/x-rst"), ("README.txt", "text/plain"): if os.path.exists(filename): with open(filename, "r") as read: return { "long_description": read.read(), "long_description_content_type": mime, } return { "long_description": "", "long_description_content_type": "text/plain", } class MetaUtils(dict): """ convenience access to PMD fields """ def __getattr__(self, name): """ dict into properties """ return self.get(name, "") def plugin_doc(self): """ use comment block """ return { "long_description": self.doc, "long_description_content_type": self.doc_format or "text/plain" } def python_requires(self): """ depends: python >= 3.5 """ deps = re.findall(r"python\s*\(?(>=?\s?[\d.]+)", self.get("depends", "")) if deps: return {"python_requires": deps[0]} return {} def install_requires(self): """ depends: python:module, pip:module """ deps = re.findall(r"(?:python|pip):([\w\-]+)\s*(\(?[<=>\s\d.\-]+)?", self.get("depends", "")) if deps: return {"install_requires": [name+re.sub(r"[^<=>\d.\-]", "", ver) for name, ver in deps]} return {} def extras_require(self): """ suggest: line """ deps = re.findall(r"(?:python|pip):([\w\-]+)\s*\(?\s*([>=<]+\s*[\d.\-]+)", self.get("suggests", "")) if deps: return dict(deps) return {} def project_urls(self, exclude=("url", "update",)): """ other-url: https://... """ urls = {} for key, url in self.items(): if isinstance(url, str) and key not in exclude and re.match(r"https?://\S+", url): urls[key.title()] = url return urls def classifiers(self): """ classifiers: / keywords: / category: """ for field in ("api", "category", "type", "keywords", "classifiers"): field = self.get(field, "") field = re.findall(r"(\w{4,})", field) regex = "|".join(field) if not regex: continue for line in TOPIC_TROVE: if re.search("::[^:]*("+regex+")[^:]*$", line, re.I): yield line def trove_license(self): """ license: to License :: """ trove_licenses = { r"MITL?": "License :: OSI Approved :: MIT License", r"\bPD\b|CC-?0|Public ?Domain|Unlicense": "License :: Public Domain", r"ASL": "License :: OSI Approved :: Apache Software License", r"art": "License :: OSI Approved :: Artistic License", r"BSDL?": "License :: OSI Approved :: BSD License", r"CPL": "License :: OSI Approved :: Common Public License", r"AGPL.*3": "License :: OSI Approved :: GNU Affero General Public License v3", r"AGPLv*3\+": "License :: OSI Approved :: GNU Affero General Public License v3 or later (AGPLv3+)", r"\bGPL": "License :: OSI Approved :: GNU General Public License (GPL)", r"\bGPL.*3": "License :: OSI Approved :: GNU General Public License v3 (GPLv3)", r"LGPL": "License :: OSI Approved :: GNU Library or Lesser General Public License (LGPL)", r"MPL": "License :: OSI Approved :: Mozilla Public License 2.0 (MPL 2.0)", r"Pyth": "License :: OSI Approved :: Python Software Foundation License" } for regex, trove in trove_licenses.items(): if re.search(regex, self.license, re.I): return [trove] return [] def trove_status(self): """ state: to DevStatus :: """ trove_status = { "pre|release|cand": "Development Status :: 2 - Pre-Alpha", "alpha": "Development Status :: 3 - Alpha", "beta": "Development Status :: 4 - Beta", "stable": "Development Status :: 5 - Production/Stable", "mature": "Development Status :: 6 - Mature" } for regex, trove in trove_status.items(): state = self.state or self.status or "alpha" if re.search(regex, state, re.I): return [trove] return [] @staticmethod def datafiles_man(): """ data_files= """ for man in glob.glob("man*/*.[12345678]"): section = man[-1] yield ("man/man"+section, [man],) def entry_points(self): """ collect console-scripts: """ params = {} for field in ["console_scripts", "gui_scripts"]: if not self.get(field): continue params[field] = params.get(field, []) + re.findall(r"(\w+[^,;\s]+=\w+[^,;\s]+)", self[field]) return params def get_keywords(self): """ keywords= """ return self.keywords or self.category or self.type def setup(debug=0, **kwargs): """ Wrapper around `setuptools.setup()` which adds some defaults and plugin meta data import, with two shortcut params: Parameters ---------- fn : str main file "pkg/main.py" long_description : str e.g. "README.md", else comment block used Other setup() params work as usual, and are passed trough. Notably entry_points= or data_files= can be used, even if they get augmented. """ # stub values stub = { "classifiers": [], "project_urls": {}, "python_requires": ">= 2.7", "install_requires": [], "extras_require": {}, #"package_dir": {"": "."}, #"package_data": {}, #"data_files": [], "entry_points": {}, "packages": setuptools.find_packages() } for key, val in stub.items(): if not key in kwargs: kwargs[key] = val # package name if "name" not in kwargs and kwargs.get("packages"): kwargs["name"] = kwargs["packages"][0] # read README if field empty or says `@README` if re.match("^$|^[@./]*README.{0,5}$", kwargs.get("long_description", "")): kwargs.update(get_readme()) # search name= package if no fn= given if kwargs.get("filename"): kwargs["fn"] = kwargs["filename"] del kwargs["filename"] if not kwargs.get("fn") and kwargs.get("name"): kwargs["fn"] = name_to_fn(kwargs["name"]) # read plugin meta data (PMD) pmd = MetaUtils( pluginconf.plugin_meta(filename=kwargs["fn"]) ) # id: if no name= still if pmd.get("id") and not kwargs.get("name"): if pmd["id"] == "__init__": pmd["id"] = re.findall(r"([\w\.\-]+)/__init__.+$", kwargs["fn"])[0] kwargs["name"] = pmd["id"] # cleanup if "fn" in kwargs: del kwargs["fn"] # version:, description:, author: for field in "version", "description", "license", "author", "url": if field in pmd and not field in kwargs: kwargs[field] = pmd[field] # other urls: kwargs["project_urls"].update(pmd.project_urls()) # depends: if "depends" in pmd: kwargs.update(pmd.python_requires()) if "depends" in pmd and not kwargs["install_requires"]: kwargs.update(pmd.install_requires()) # suggests: if "suggests" in pmd and not kwargs["extras_require"]: kwargs["extras_require"].update(pmd.extras_require()) # doc: if not kwargs.get("long_description"): kwargs.update(pmd.plugin_doc()) # keywords= if "keywords" not in kwargs: kwargs["keywords"] = pmd.get_keywords() # automatic inclusions kwargs["data_files"] = kwargs.get("data_files", []) + list(pmd.datafiles_man()) # entry points for section, entries in pmd.entry_points().items(): kwargs["entry_points"][section] = kwargs["entry_points"].get(section, []) + entries # classifiers= # license: if pmd.get("license") and not any(re.match("License ::", l) for l in kwargs["classifiers"]): kwargs["classifiers"].extend(pmd.trove_license()) # state: if pmd.get("state", pmd.get("status")) and not any(re.match("Development Status ::", l) for l in kwargs["classifiers"]): kwargs["classifiers"].extend(pmd.trove_status()) # topics:: kwargs["classifiers"].extend(list(pmd.classifiers())) # handover if debug: pprint.pprint(kwargs) setuptools.setup(**kwargs) TOPIC_TROVE = """Topic :: Adaptive Technologies Topic :: Artistic Software Topic :: Communications Topic :: Communications :: BBS Topic :: Communications :: Chat Topic :: Communications :: Chat :: ICQ Topic :: Communications :: Chat :: Internet Relay Chat Topic :: Communications :: Chat :: Unix Talk |
︙ | ︙ | |||
531 532 533 534 535 536 537 | Topic :: Text Processing :: Markup :: HTML Topic :: Text Processing :: Markup :: LaTeX Topic :: Text Processing :: Markup :: Markdown Topic :: Text Processing :: Markup :: SGML Topic :: Text Processing :: Markup :: VRML Topic :: Text Processing :: Markup :: XML Topic :: Text Processing :: Markup :: reStructuredText | | | | 552 553 554 555 556 557 558 559 560 561 562 563 564 565 | Topic :: Text Processing :: Markup :: HTML Topic :: Text Processing :: Markup :: LaTeX Topic :: Text Processing :: Markup :: Markdown Topic :: Text Processing :: Markup :: SGML Topic :: Text Processing :: Markup :: VRML Topic :: Text Processing :: Markup :: XML Topic :: Text Processing :: Markup :: reStructuredText Topic :: Utilities""".split(r"\n") try: from trove_classifiers import classifiers TOPIC_TROVE = [line for line in classifiers if re.match("Topic ::", line)] except: pass |