From 090ac0d411254acc89f2e615a1bb72b9f63cefff Mon Sep 17 00:00:00 2001 From: vidhyavijayan3 Date: Tue, 27 May 2025 17:24:01 +0530 Subject: [PATCH 1/2] Fix #13881: Add plugin to disallow bytearray as filename in compile() --- mypy.ini | 2 ++ plugins/__init__.py | 0 plugins/compile_filename/__init__.py | 0 plugins/compile_filename/plugin.py | 33 ++++++++++++++++++++++++++++ 4 files changed, 35 insertions(+) create mode 100644 mypy.ini create mode 100644 plugins/__init__.py create mode 100644 plugins/compile_filename/__init__.py create mode 100644 plugins/compile_filename/plugin.py diff --git a/mypy.ini b/mypy.ini new file mode 100644 index 000000000000..13deb9e234fb --- /dev/null +++ b/mypy.ini @@ -0,0 +1,2 @@ +[mypy] +plugins = compile_filename.plugin diff --git a/plugins/__init__.py b/plugins/__init__.py new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/plugins/compile_filename/__init__.py b/plugins/compile_filename/__init__.py new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/plugins/compile_filename/plugin.py b/plugins/compile_filename/plugin.py new file mode 100644 index 000000000000..352b5c3c57ee --- /dev/null +++ b/plugins/compile_filename/plugin.py @@ -0,0 +1,33 @@ +from typing import Optional +from mypy.plugin import Plugin, FunctionContext +from mypy.types import Type, Instance +from mypy.nodes import ARG_POS + +class CompileFilenamePlugin(Plugin): + def get_function_hook(self, fullname: str): + # Hook only the built-in compile function + if fullname == "builtins.compile": + return compile_hook + return None + +def compile_hook(ctx: FunctionContext) -> Type: + # Arguments to compile: source, filename, mode, ... + # filename is arg index 1 (zero-based) + if len(ctx.arg_types) > 1 and ctx.arg_types[1]: + filename_type = ctx.arg_types[1][0] # first argument passed for filename param + if is_bytearray_type(filename_type): + ctx.api.fail( + "Passing 'bytearray' as filename to 'compile()' is not allowed", + ctx.args[1][0] + ) + return ctx.default_return_type + +def is_bytearray_type(typ: Type) -> bool: + # Check if the type is exactly bytearray + if isinstance(typ, Instance): + # The full name for builtins.bytearray is 'builtins.bytearray' + return typ.type.fullname == "builtins.bytearray" + return False + +def plugin(version: str): + return CompileFilenamePlugin From 44d2f90936909284ee3e7b1a0ce6971294c7f69c Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Tue, 27 May 2025 12:00:10 +0000 Subject: [PATCH 2/2] [pre-commit.ci] auto fixes from pre-commit.com hooks --- plugins/compile_filename/plugin.py | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/plugins/compile_filename/plugin.py b/plugins/compile_filename/plugin.py index 352b5c3c57ee..ea780202355b 100644 --- a/plugins/compile_filename/plugin.py +++ b/plugins/compile_filename/plugin.py @@ -1,7 +1,6 @@ -from typing import Optional -from mypy.plugin import Plugin, FunctionContext -from mypy.types import Type, Instance -from mypy.nodes import ARG_POS +from mypy.plugin import FunctionContext, Plugin +from mypy.types import Instance, Type + class CompileFilenamePlugin(Plugin): def get_function_hook(self, fullname: str): @@ -10,18 +9,17 @@ def get_function_hook(self, fullname: str): return compile_hook return None + def compile_hook(ctx: FunctionContext) -> Type: # Arguments to compile: source, filename, mode, ... # filename is arg index 1 (zero-based) if len(ctx.arg_types) > 1 and ctx.arg_types[1]: filename_type = ctx.arg_types[1][0] # first argument passed for filename param if is_bytearray_type(filename_type): - ctx.api.fail( - "Passing 'bytearray' as filename to 'compile()' is not allowed", - ctx.args[1][0] - ) + ctx.api.fail("Passing 'bytearray' as filename to 'compile()' is not allowed", ctx.args[1][0]) return ctx.default_return_type + def is_bytearray_type(typ: Type) -> bool: # Check if the type is exactly bytearray if isinstance(typ, Instance): @@ -29,5 +27,6 @@ def is_bytearray_type(typ: Type) -> bool: return typ.type.fullname == "builtins.bytearray" return False + def plugin(version: str): return CompileFilenamePlugin