From 2ac236c912d10fcfefae321d0017e5c8ca56c4e9 Mon Sep 17 00:00:00 2001 From: James Roy Date: Sun, 19 Oct 2025 13:19:24 +0800 Subject: [PATCH] Add a hash method for strings Hash constants are widely used in signatures, so I suggest adding a hash method for strings to obtain the hash constant of a string. For its usage example: ```meson hash_str = 'foobar'.hash('sha1') # return a sha1 constant # some process --- docs/yaml/elementary/str.yml | 28 +++++++++++++++++++ mesonbuild/interpreter/primitives/string.py | 15 ++++++++++ .../common/35 string operations/meson.build | 11 ++++++++ 3 files changed, 54 insertions(+) diff --git a/docs/yaml/elementary/str.yml b/docs/yaml/elementary/str.yml index c70a4f5dc183..33a4e495831a 100644 --- a/docs/yaml/elementary/str.yml +++ b/docs/yaml/elementary/str.yml @@ -41,6 +41,34 @@ methods: description: The values to replace the @number@ placeholders in the format string. type: int | bool | str +# str.hash(algorithm) +- name: hash + description: Run the specified `algorithm` on the string and return the hash in hexadecimal + returns: str + example: | + ```meson + message('foobar'.hash('md5')) # => '3858f62230ac3c915f300c664312c63f' + message('foobar'.hash('sha1')) # => '8843d7f92416211de9ebb963ff4ce28125932878' + message('foobar'.hash('sha256')) # => 'c3ab8ff13720e8ad9047dd39466b3c8974e592c2fa383d4a3960714caef0c4f2' + ... + ``` + + posargs: + algorithm: + description: | + It supports the following algorithms: + - md5 + - sha1 + - sha224 + - sha256 + - sha384 + - sha512 + - sha3_224 + - sha3_256 + - sha3_384 + - sha3_512 + type: str + # str.replace(old, new) - name: replace description: Search all occurrences of `old` and replace it with `new` diff --git a/mesonbuild/interpreter/primitives/string.py b/mesonbuild/interpreter/primitives/string.py index 49dd71660157..3cb00f6c824a 100644 --- a/mesonbuild/interpreter/primitives/string.py +++ b/mesonbuild/interpreter/primitives/string.py @@ -19,6 +19,7 @@ noPosargs, typed_pos_args, InvalidArguments, + InterpreterException, FeatureBroken, stringifyUserArguments, ) @@ -83,6 +84,20 @@ def arg_replace(match: T.Match[str]) -> str: return re.sub(r'@(\d+)@', arg_replace, self.held_object) + @noKwargs + @typed_pos_args('str.hash', str) + @InterpreterObject.method('hash') + def hash_method(self, args: T.Tuple[T.List[TYPE_var]], kwargs: TYPE_kwargs) -> str: + from hashlib import new + try: + # For supported algorithms + # see https://docs.python.org/3/library/hashlib.html#hash-objects + hash_obj = new(args[0]) # algorithm = args[0] + hash_obj.update(self.held_object.encode()) + return hash_obj.hexdigest() + except ValueError as e: + raise InterpreterException(e) + @noKwargs @noPosargs @FeatureNew('str.splitlines', '1.2.0') diff --git a/test cases/common/35 string operations/meson.build b/test cases/common/35 string operations/meson.build index ab77b4947c56..9150e1054bb7 100644 --- a/test cases/common/35 string operations/meson.build +++ b/test cases/common/35 string operations/meson.build @@ -19,6 +19,17 @@ long = 'abcde' prefix = 'abc' suffix = 'cde' +testcase expect_error('''unsupported hash type invalid-method''') + long.hash('invalid-method') +endtestcase + +assert(long.hash('md5') == 'ab56b4d92b40713acc5af89985d4b786') +assert(long.hash('sha1') == '03de6c570bfe24bfc328ccd7ca46b76eadaf4334') +assert(long.hash('sha224') == 'bdd03d560993e675516ba5a50638b6531ac2ac3d5847c61916cfced6') +assert(long.hash('sha256') == '36bbe50ed96841d10443bcb670d6554f0a34b761be67ec9c4a8ad2c0c44ca42c') +assert(long.hash('sha3_224') == '6acfaab70afd8439cea3616b41088bd81c939b272548f6409cf30e57') +assert(long.hash('sha3_256') == 'd716ec61e18904a8f58679b71cb065d4d5db72e0e0c3f155a4feff7add0e58eb') + assert(long[0] == 'a') assert(long[2] == 'c')