Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 28 additions & 0 deletions docs/yaml/elementary/str.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The python documentation lists more algorithms that are always present.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

image It looks like there is no more :(

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wrong section of the docs. That section specifically uses the language "such as these", indicating it isn't complete. Elsewhere on that page, it says:

Constructors for hash algorithms that are always present in this module are sha1(), sha224(), sha256(), sha384(), sha512(), sha3_224(), sha3_256(), sha3_384(), sha3_512(), shake_128(), shake_256(), blake2b(), and blake2s(). md5() is normally available as well, though it may be missing or blocked if you are using a rare “FIPS compliant” build of Python. These correspond to algorithms_guaranteed.

Additional algorithms may also be available if your Python distribution’s hashlib was linked against a build of OpenSSL that provides others. Others are not guaranteed available on all installations and will only be accessible by name via new(). See algorithms_available.

type: str

# str.replace(old, new)
- name: replace
description: Search all occurrences of `old` and replace it with `new`
Expand Down
15 changes: 15 additions & 0 deletions mesonbuild/interpreter/primitives/string.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
noPosargs,
typed_pos_args,
InvalidArguments,
InterpreterException,
FeatureBroken,
stringifyUserArguments,
)
Expand Down Expand Up @@ -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')
Expand Down
11 changes: 11 additions & 0 deletions test cases/common/35 string operations/meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -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')

Expand Down
Loading