mirror of
https://github.com/pyscript/pyscript.git
synced 2025-12-19 18:27:29 -05:00
Remove all but 2 eslint-disable pragmas (#1335)
Turns off: - no-explicit-any (we need to handle any return values from runPython) - no-unsafe-assignment (noisy and pointless) And resolves all but two remaining ones. The last two lints regard access to private Pyodide variables and so: - they are not easy to work around without an upstream Pyodide patch - they should trigger linter and require explicit override
This commit is contained in:
@@ -21,9 +21,11 @@ module.exports = {
|
||||
// ts-ignore is already an explicit override, no need to have a second lint
|
||||
'@typescript-eslint/ban-ts-comment': 'off',
|
||||
|
||||
// any related lints
|
||||
'@typescript-eslint/no-explicit-any': 'error',
|
||||
'@typescript-eslint/no-unsafe-assignment': 'error',
|
||||
// any-related lints
|
||||
// These two come up a lot, so they probably aren't worth it
|
||||
'@typescript-eslint/no-explicit-any': 'off',
|
||||
'@typescript-eslint/no-unsafe-assignment': 'off',
|
||||
// encourage people to cast "any" to a more specific type before using it
|
||||
'@typescript-eslint/no-unsafe-call': 'error',
|
||||
'@typescript-eslint/no-unsafe-member-access': 'error',
|
||||
'@typescript-eslint/no-unsafe-argument': 'error',
|
||||
@@ -35,5 +37,6 @@ module.exports = {
|
||||
'@typescript-eslint/no-floating-promises': 'error',
|
||||
'@typescript-eslint/restrict-plus-operands': 'error',
|
||||
'@typescript-eslint/no-empty-function': 'error',
|
||||
'@typescript-eslint/restrict-template-expressions': ['error', { allowBoolean: true }],
|
||||
},
|
||||
};
|
||||
|
||||
@@ -7,10 +7,8 @@ function createCustomElements(interpreter: InterpreterClient, app: PyScriptApp)
|
||||
const PyWidget = make_PyWidget(interpreter);
|
||||
const PyRepl = make_PyRepl(interpreter, app);
|
||||
|
||||
/* eslint-disable @typescript-eslint/no-unused-vars */
|
||||
const xPyRepl = customElements.define('py-repl', PyRepl);
|
||||
const xPyWidget = customElements.define('py-register-widget', PyWidget);
|
||||
/* eslint-enable @typescript-eslint/no-unused-vars */
|
||||
customElements.define('py-repl', PyRepl);
|
||||
customElements.define('py-register-widget', PyWidget);
|
||||
}
|
||||
|
||||
export { createCustomElements };
|
||||
|
||||
@@ -133,14 +133,13 @@ export function make_PyRepl(interpreter: InterpreterClient, app: PyScriptApp) {
|
||||
|
||||
// execute the python code
|
||||
await app.plugins.beforePyReplExec({ interpreter: interpreter, src: pySrc, outEl: outEl, pyReplTag: this });
|
||||
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
|
||||
const { result } = await pyExec(interpreter, pySrc, outEl);
|
||||
await app.plugins.afterPyReplExec({
|
||||
interpreter: interpreter,
|
||||
src: pySrc,
|
||||
outEl: outEl,
|
||||
pyReplTag: this,
|
||||
result, // eslint-disable-line @typescript-eslint/no-unsafe-assignment
|
||||
result,
|
||||
});
|
||||
|
||||
this.autogenerateMaybe();
|
||||
|
||||
@@ -36,7 +36,6 @@ export function make_PyScript(interpreter: InterpreterClient, app: PyScriptApp)
|
||||
this.innerHTML = '';
|
||||
|
||||
await app.plugins.beforePyScriptExec({ interpreter: interpreter, src: pySrc, pyScriptTag: this });
|
||||
/* eslint-disable @typescript-eslint/no-unsafe-assignment */
|
||||
const result = (await pyExec(interpreter, pySrc, this)).result;
|
||||
await app.plugins.afterPyScriptExec({
|
||||
interpreter: interpreter,
|
||||
@@ -44,7 +43,6 @@ export function make_PyScript(interpreter: InterpreterClient, app: PyScriptApp)
|
||||
pyScriptTag: this,
|
||||
result: result,
|
||||
});
|
||||
/* eslint-enable @typescript-eslint/no-unsafe-assignment */
|
||||
} finally {
|
||||
releaseLock();
|
||||
app.decrementPendingTags();
|
||||
|
||||
@@ -40,8 +40,7 @@ function createWidget(interpreter: InterpreterClient, name: string, code: string
|
||||
await interpreter.globals.set(this.id, this.proxy);
|
||||
}
|
||||
}
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
const xPyWidget = customElements.define(name, CustomWidget);
|
||||
customElements.define(name, CustomWidget);
|
||||
}
|
||||
|
||||
export function make_PyWidget(interpreter: InterpreterClient) {
|
||||
|
||||
@@ -69,7 +69,6 @@ export function _createAlertBanner(
|
||||
messageType: MessageType = 'text',
|
||||
logMessage = true,
|
||||
) {
|
||||
// eslint-disable-next-line @typescript-eslint/restrict-template-expressions
|
||||
switch (`log-${level}-${logMessage}`) {
|
||||
case 'log-error-true':
|
||||
console.error(message);
|
||||
|
||||
@@ -59,7 +59,6 @@ export class InterpreterClient extends Object {
|
||||
* 2. a Synclink Proxy wrapping an object of this if the result is not
|
||||
* serializable.
|
||||
*/
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
async run(code: string, id?: string): Promise<{ result: any }> {
|
||||
return this._remote.pyscript_py._run_pyscript(code, id);
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@ import { loadConfigFromElement } from './pyconfig';
|
||||
import type { AppConfig } from './pyconfig';
|
||||
import { InterpreterClient } from './interpreter_client';
|
||||
import { version } from './version';
|
||||
import { PluginManager, define_custom_element, Plugin } from './plugin';
|
||||
import { PluginManager, define_custom_element, Plugin, PythonPlugin } from './plugin';
|
||||
import { make_PyScript, initHandlers, mountElements } from './components/pyscript';
|
||||
import { getLogger } from './logger';
|
||||
import { showWarning, globalExport, createLock } from './utils';
|
||||
@@ -16,7 +16,6 @@ import { PyTerminalPlugin } from './plugins/pyterminal';
|
||||
import { SplashscreenPlugin } from './plugins/splashscreen';
|
||||
import { ImportmapPlugin } from './plugins/importmap';
|
||||
import { StdioDirector as StdioDirector } from './plugins/stdiodirector';
|
||||
import type { PyProxy } from 'pyodide';
|
||||
import { RemoteInterpreter } from './remote_interpreter';
|
||||
import { robustFetch } from './fetch';
|
||||
import * as Synclink from 'synclink';
|
||||
@@ -131,7 +130,6 @@ export class PyScriptApp {
|
||||
}
|
||||
}
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
async _handleUserErrorMaybe(error: any) {
|
||||
const e = error as UserError;
|
||||
if (e && e.$$isUserError) {
|
||||
@@ -399,7 +397,7 @@ export class PyScriptApp {
|
||||
// eventually replace with interpreter.pyimport(modulename);
|
||||
const module = interpreter._unwrapped_remote.pyimport(modulename);
|
||||
if (typeof (await module.plugin) !== 'undefined') {
|
||||
const py_plugin = module.plugin as PyProxy & { init(app: PyScriptApp): void };
|
||||
const py_plugin = module.plugin as PythonPlugin;
|
||||
py_plugin.init(this);
|
||||
this.plugins.addPythonPlugin(py_plugin);
|
||||
} else {
|
||||
|
||||
@@ -1,8 +1,4 @@
|
||||
/* eslint-disable @typescript-eslint/no-unsafe-member-access,
|
||||
@typescript-eslint/no-unsafe-call,
|
||||
@typescript-eslint/no-explicit-any,
|
||||
@typescript-eslint/no-unsafe-assignment */
|
||||
|
||||
import type { PyScriptApp } from './main';
|
||||
import type { AppConfig } from './pyconfig';
|
||||
import type { UserError } from './exceptions';
|
||||
import { getLogger } from './logger';
|
||||
@@ -125,9 +121,21 @@ export class Plugin {
|
||||
}
|
||||
}
|
||||
|
||||
export type PythonPlugin = {
|
||||
init(app: PyScriptApp): void;
|
||||
configure?: (config: AppConfig) => Promise<void>;
|
||||
afterSetup?: (interpreter: InterpreterClient) => Promise<void>;
|
||||
afterStartup?: (interpreter: InterpreterClient) => Promise<void>;
|
||||
beforePyScriptExec?: { callKwargs: (options: any) => Promise<void> };
|
||||
afterPyScriptExec?: { callKwargs: (options: any) => Promise<void> };
|
||||
beforePyReplExec?: { callKwargs: (options: any) => Promise<void> };
|
||||
afterPyReplExec?: { callKwargs: (options: any) => Promise<void> };
|
||||
onUserError?: (error: UserError) => Promise<void>;
|
||||
};
|
||||
|
||||
export class PluginManager {
|
||||
_plugins: Plugin[];
|
||||
_pythonPlugins: any[];
|
||||
_pythonPlugins: PythonPlugin[];
|
||||
|
||||
constructor() {
|
||||
this._plugins = [];
|
||||
@@ -138,7 +146,7 @@ export class PluginManager {
|
||||
for (const p of plugins) this._plugins.push(p);
|
||||
}
|
||||
|
||||
addPythonPlugin(plugin: any) {
|
||||
addPythonPlugin(plugin: PythonPlugin) {
|
||||
this._pythonPlugins.push(plugin);
|
||||
}
|
||||
|
||||
@@ -179,8 +187,7 @@ export class PluginManager {
|
||||
async beforePyScriptExec(options: { interpreter: InterpreterClient; src: string; pyScriptTag: PyScriptTag }) {
|
||||
for (const p of this._plugins) p.beforePyScriptExec?.(options);
|
||||
|
||||
for (const p of this._pythonPlugins)
|
||||
await p.beforePyScriptExec(options.interpreter, options.src, options.pyScriptTag);
|
||||
for (const p of this._pythonPlugins) await p.beforePyScriptExec.callKwargs(options);
|
||||
}
|
||||
|
||||
async afterPyScriptExec(options: {
|
||||
@@ -191,8 +198,7 @@ export class PluginManager {
|
||||
}) {
|
||||
for (const p of this._plugins) p.afterPyScriptExec?.(options);
|
||||
|
||||
for (const p of this._pythonPlugins)
|
||||
await p.afterPyScriptExec(options.interpreter, options.src, options.pyScriptTag, options.result);
|
||||
for (const p of this._pythonPlugins) await p.afterPyScriptExec.callKwargs(options);
|
||||
}
|
||||
|
||||
async beforePyReplExec(options: {
|
||||
@@ -203,21 +209,13 @@ export class PluginManager {
|
||||
}) {
|
||||
for (const p of this._plugins) p.beforePyReplExec?.(options);
|
||||
|
||||
for (const p of this._pythonPlugins)
|
||||
await p.beforePyReplExec?.(options.interpreter, options.src, options.outEl, options.pyReplTag);
|
||||
for (const p of this._pythonPlugins) await p.beforePyReplExec?.callKwargs(options);
|
||||
}
|
||||
|
||||
async afterPyReplExec(options: { interpreter: InterpreterClient; src: string; outEl; pyReplTag; result }) {
|
||||
for (const p of this._plugins) p.afterPyReplExec?.(options);
|
||||
|
||||
for (const p of this._pythonPlugins)
|
||||
await p.afterPyReplExec?.(
|
||||
options.interpreter,
|
||||
options.src,
|
||||
options.outEl,
|
||||
options.pyReplTag,
|
||||
options.result,
|
||||
);
|
||||
for (const p of this._pythonPlugins) await p.afterPyReplExec?.callKwargs(options);
|
||||
}
|
||||
|
||||
async onUserError(error: UserError) {
|
||||
@@ -227,6 +225,9 @@ export class PluginManager {
|
||||
}
|
||||
}
|
||||
|
||||
type PyElementInstance = { connect(): void };
|
||||
type PyElementClass = (htmlElement: HTMLElement) => PyElementInstance;
|
||||
|
||||
/**
|
||||
* Defines a new CustomElement (via customElement.defines) with `tag`,
|
||||
* where the new CustomElement is a proxy that delegates the logic to
|
||||
@@ -238,12 +239,12 @@ export class PluginManager {
|
||||
* received by the newly created CustomElement will be
|
||||
* delegated to that instance.
|
||||
*/
|
||||
export function define_custom_element(tag: string, pyPluginClass: any): any {
|
||||
export function define_custom_element(tag: string, pyElementClass: PyElementClass): any {
|
||||
logger.info(`creating plugin: ${tag}`);
|
||||
class ProxyCustomElement extends HTMLElement {
|
||||
shadow: ShadowRoot;
|
||||
wrapper: HTMLElement;
|
||||
pyPluginInstance: any;
|
||||
pyElementInstance: PyElementInstance;
|
||||
originalInnerHTML: string;
|
||||
|
||||
constructor() {
|
||||
@@ -254,11 +255,11 @@ export function define_custom_element(tag: string, pyPluginClass: any): any {
|
||||
this.wrapper = document.createElement('slot');
|
||||
this.shadow.appendChild(this.wrapper);
|
||||
this.originalInnerHTML = this.innerHTML;
|
||||
this.pyPluginInstance = pyPluginClass(this);
|
||||
this.pyElementInstance = pyElementClass(this);
|
||||
}
|
||||
|
||||
connectedCallback() {
|
||||
const innerHTML = this.pyPluginInstance.connect();
|
||||
const innerHTML = this.pyElementInstance.connect();
|
||||
if (typeof innerHTML === 'string') this.innerHTML = innerHTML;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -50,7 +50,7 @@ export class StdioDirector extends Plugin {
|
||||
interpreter: InterpreterClient;
|
||||
src: string;
|
||||
pyScriptTag: PyScriptTag;
|
||||
result: any; // eslint-disable-line @typescript-eslint/no-explicit-any
|
||||
result: any;
|
||||
}): void {
|
||||
if (options.pyScriptTag.stdout_manager != null) {
|
||||
this._stdioMultiplexer.removeListener(options.pyScriptTag.stdout_manager);
|
||||
@@ -99,7 +99,7 @@ export class StdioDirector extends Plugin {
|
||||
src: string;
|
||||
outEl: HTMLElement;
|
||||
pyReplTag: InstanceType<ReturnType<typeof make_PyRepl>>;
|
||||
result: any; // eslint-disable-line @typescript-eslint/no-explicit-any
|
||||
result: any;
|
||||
}): Promise<void> {
|
||||
// display the value of the last-evaluated expression in the REPL
|
||||
if (options.result !== undefined) {
|
||||
|
||||
@@ -6,7 +6,6 @@ import { UserError, ErrorCode } from './exceptions';
|
||||
|
||||
const logger = getLogger('py-config');
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
export interface AppConfig extends Record<string, any> {
|
||||
name?: string;
|
||||
description?: string;
|
||||
@@ -107,7 +106,6 @@ function fillUserData(inputConfig: AppConfig, resultConfig: AppConfig): AppConfi
|
||||
for (const key in inputConfig) {
|
||||
// fill in all extra keys ignored by the validator
|
||||
if (!(key in defaultConfig)) {
|
||||
// eslint-disable-next-line
|
||||
resultConfig[key] = inputConfig[key];
|
||||
}
|
||||
}
|
||||
@@ -127,11 +125,9 @@ function mergeConfig(inlineConfig: AppConfig, externalConfig: AppConfig): AppCon
|
||||
for (const [keyType, keys] of allKeys) {
|
||||
keys.forEach(function (item: string) {
|
||||
if (keyType === 'boolean') {
|
||||
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
|
||||
merged[item] =
|
||||
typeof inlineConfig[item] !== 'undefined' ? inlineConfig[item] : externalConfig[item];
|
||||
} else {
|
||||
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
|
||||
merged[item] = inlineConfig[item] || externalConfig[item];
|
||||
}
|
||||
});
|
||||
@@ -200,7 +196,6 @@ function validateConfig(configText: string, configType = 'toml') {
|
||||
const interpreterConfig: InterpreterConfig = {};
|
||||
for (const eachInterpreterParam in eachInterpreter) {
|
||||
if (validateParamInConfig(eachInterpreterParam, 'string', eachInterpreter)) {
|
||||
// eslint-disable-next-line
|
||||
interpreterConfig[eachInterpreterParam] = eachInterpreter[eachInterpreterParam];
|
||||
}
|
||||
}
|
||||
@@ -224,7 +219,6 @@ function validateConfig(configText: string, configType = 'toml') {
|
||||
const interpreterConfig: InterpreterConfig = {};
|
||||
for (const eachInterpreterParam in eachInterpreter) {
|
||||
if (validateParamInConfig(eachInterpreterParam, 'string', eachInterpreter)) {
|
||||
// eslint-disable-next-line
|
||||
interpreterConfig[eachInterpreterParam] = eachInterpreter[eachInterpreterParam];
|
||||
}
|
||||
}
|
||||
@@ -238,14 +232,12 @@ function validateConfig(configText: string, configType = 'toml') {
|
||||
for (const eachFetchConfigParam in eachFetch) {
|
||||
const targetType = eachFetchConfigParam === 'files' ? 'array' : 'string';
|
||||
if (validateParamInConfig(eachFetchConfigParam, targetType, eachFetch)) {
|
||||
// eslint-disable-next-line
|
||||
eachFetchConfig[eachFetchConfigParam] = eachFetch[eachFetchConfigParam];
|
||||
}
|
||||
}
|
||||
finalConfig[item].push(eachFetchConfig);
|
||||
});
|
||||
} else {
|
||||
// eslint-disable-next-line
|
||||
finalConfig[item] = config[item];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,7 +10,6 @@ export async function pyExec(
|
||||
interpreter: InterpreterClient,
|
||||
pysrc: string,
|
||||
outElem: HTMLElement,
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
): Promise<{ result: any }> {
|
||||
ensureUniqueId(outElem);
|
||||
if (await interpreter._remote.pyscript_py.uses_top_level_await(pysrc)) {
|
||||
@@ -46,7 +45,6 @@ export async function pyExec(
|
||||
* pyDisplay(interpreter, obj);
|
||||
* pyDisplay(interpreter, obj, { target: targetID });
|
||||
*/
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
export async function pyDisplay(interpreter: InterpreterClient, obj: any, kwargs: { [k: string]: any } = {}) {
|
||||
const display = (await interpreter.globals.get('display')) as PyProxyCallable;
|
||||
try {
|
||||
|
||||
@@ -106,11 +106,10 @@ export class RemoteInterpreter extends Object {
|
||||
fullStdLib: false,
|
||||
}),
|
||||
);
|
||||
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
|
||||
this.FS = this.interface.FS;
|
||||
// eslint-disable-next-line
|
||||
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
|
||||
this.PATH = (this.interface as any)._module.PATH;
|
||||
// eslint-disable-next-line
|
||||
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
|
||||
this.PATH_FS = (this.interface as any)._module.PATH_FS;
|
||||
|
||||
// TODO: Remove this once `runtimes` is removed!
|
||||
@@ -270,10 +269,8 @@ export class RemoteInterpreter extends Object {
|
||||
return Synclink.proxy(this.interface.pyimport(mod_name));
|
||||
}
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
setHandler(func_name: string, handler: any): void {
|
||||
const pyscript_module = this.interface.pyimport('pyscript');
|
||||
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
|
||||
pyscript_module[func_name] = handler;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user