diff --git a/mathics/builtin/files.py b/mathics/builtin/files.py index 434e3937ea..7d1e537f1a 100644 --- a/mathics/builtin/files.py +++ b/mathics/builtin/files.py @@ -3812,6 +3812,8 @@ class FileHash(Builtin):
'FileHash[$file$, $type$]'
returns an integer hash of the specified $type$ for the given $file$.
The types supported are "MD5", "Adler32", "CRC32", "SHA", "SHA224", "SHA256", "SHA384", and "SHA512".
+
'FileHash[$file$, $type$, $format$]' +
gives a hash code in the specified format.
>> FileHash["ExampleData/sunflowers.jpg"] @@ -3840,19 +3842,20 @@ class FileHash(Builtin): #> FileHash["ExampleData/sunflowers.jpg", xyzsymbol] = FileHash[ExampleData/sunflowers.jpg, xyzsymbol] #> FileHash["ExampleData/sunflowers.jpg", "xyzstr"] - = FileHash[ExampleData/sunflowers.jpg, xyzstr] + = FileHash[ExampleData/sunflowers.jpg, xyzstr, Integer] #> FileHash[xyzsymbol] = FileHash[xyzsymbol] """ rules = { - "FileHash[filename_String]": 'FileHash[filename, "MD5"]', + "FileHash[filename_String]": 'FileHash[filename, "MD5", "Integer"]', + "FileHash[filename_String, hashtype_String]": 'FileHash[filename, hashtype, "Integer"]', } attributes = ("Protected", "ReadProtected") - def apply(self, filename, hashtype, evaluation): - "FileHash[filename_String, hashtype_String]" + def apply(self, filename, hashtype, format, evaluation): + "FileHash[filename_String, hashtype_String, format_String]" py_filename = filename.get_string_value() try: @@ -3865,7 +3868,7 @@ def apply(self, filename, hashtype, evaluation): e.message(evaluation) return - return Hash.compute(lambda update: update(dump), hashtype.get_string_value()) + return Hash.compute(lambda update: update(dump), hashtype.get_string_value(), format.get_string_value()) class FileDate(Builtin): @@ -4803,6 +4806,7 @@ def apply(self, pathname, evaluation): return SymbolTrue return SymbolFalse + class Needs(Builtin): """
@@ -4922,7 +4926,6 @@ def apply(self, context, evaluation): curr_ctxt = evaluation.definitions.get_current_context() contextstr = curr_ctxt + contextstr[1:] context = String(contextstr) - if not valid_context_name(contextstr): evaluation.message('Needs', 'ctx', Expression( 'Needs', context), 1, '`') @@ -4932,15 +4935,6 @@ def apply(self, context, evaluation): if test_loaded.is_true(): # Already loaded return SymbolNull - - # TODO: Figure out why this raises the message: - # "Select::normal: Nonatomic expression expected." - already_loaded = Expression('MemberQ', - Symbol('System`$Packages'), context) - already_loaded = already_loaded.evaluate(evaluation).is_true() - if already_loaded: - return SymbolNull - result = Expression('Get', context).evaluate(evaluation) if result == SymbolFailed: @@ -4948,3 +4942,4 @@ def apply(self, context, evaluation): return SymbolFailed return SymbolNull + diff --git a/mathics/builtin/numeric.py b/mathics/builtin/numeric.py index 7724f06a85..99e639bb36 100644 --- a/mathics/builtin/numeric.py +++ b/mathics/builtin/numeric.py @@ -1340,6 +1340,8 @@ class Hash(Builtin):
'Hash[$expr$, $type$]'
returns an integer hash of the specified $type$ for the given $expr$.
The types supported are "MD5", "Adler32", "CRC32", "SHA", "SHA224", "SHA256", "SHA384", and "SHA512".
+
'Hash[$expr$, $type$, $format$]' +
Returns the hash in the especified format.
> Hash["The Adventures of Huckleberry Finn"] @@ -1358,11 +1360,12 @@ class Hash(Builtin): = 58042316473471877315442015469706095084 >> Hash[{a, b, c}, "xyzstr"] - = Hash[{a, b, c}, xyzstr] + = Hash[{a, b, c}, xyzstr, Integer] """ rules = { - "Hash[expr_]": 'Hash[expr, "MD5"]', + "Hash[expr_]": 'Hash[expr, "MD5", "Integer"]', + "Hash[expr_, type_String]": 'Hash[expr, type, "Integer"]', } attributes = ("Protected", "ReadProtected") @@ -1380,17 +1383,30 @@ class Hash(Builtin): } @staticmethod - def compute(user_hash, py_hashtype): + def compute(user_hash, py_hashtype, py_format): hash_func = Hash._supported_hashes.get(py_hashtype) if hash_func is None: # unknown hash function? return # in order to return original Expression h = hash_func() user_hash(h.update) - return from_python(int(h.hexdigest(), 16)) - - def apply(self, expr, hashtype, evaluation): - "Hash[expr_, hashtype_String]" - return Hash.compute(expr.user_hash, hashtype.get_string_value()) + res = h.hexdigest() + if py_format in ('HexString', "HexStringLittleEndian") : + return from_python(res) + res = int(res, 16) + if py_format == "DecimalString": + return from_python(str(res)) + elif py_format == "ByteArray": + print("Not implemented. Return a string") + return from_python(str(res)) + # Default: Integer + return from_python(res) + + + def apply(self, expr, hashtype, outformat, evaluation): + "Hash[expr_, hashtype_String, outformat_String]" + return Hash.compute(expr.user_hash, + hashtype.get_string_value(), + outformat.get_string_value()) class TypeEscalation(Exception):