diff --git a/circup/shared.py b/circup/shared.py index 0b37a23..eb45430 100644 --- a/circup/shared.py +++ b/circup/shared.py @@ -62,6 +62,7 @@ def _get_modules_file(path, logger): def extract_metadata(path, logger): + # pylint: disable=too-many-locals,too-many-branches """ Given a file path, return a dictionary containing metadata extracted from dunder attributes found therein. Works with both .py and .mpy files. @@ -79,7 +80,6 @@ def extract_metadata(path, logger): :param str path: The path to the file containing the metadata. :return: The dunder based metadata found in the file, as a dictionary. """ - # pylint: disable=too-many-locals result = {} logger.info("%s", path) if path.endswith(".py"): @@ -90,7 +90,10 @@ def extract_metadata(path, logger): dunder_key_val = r"""(__\w+__)(?:\s*:\s*\w+)?\s*=\s*(?:['"]|\(\s)(.+)['"]""" for match in re.findall(dunder_key_val, content): result[match[0]] = str(match[1]) + if result: + logger.info("Extracted metadata: %s", result) elif path.endswith(".mpy"): + find_by_regexp_match = False result["mpy"] = True with open(path, "rb") as mpy_file: content = mpy_file.read() @@ -104,10 +107,20 @@ def extract_metadata(path, logger): loc = content.find(b"__version__") - 1 compatibility = (None, "7.0.0-alpha.1") elif mpy_version == b"C\x05": - # Two bytes in mpy version 5 + # Two bytes for the length of "__version__" in mpy version 5 loc = content.find(b"__version__") - 2 - compatibility = ("7.0.0-alpha.1", None) - if loc > -1: + compatibility = ("7.0.0-alpha.1", "8.99.99") + elif mpy_version == b"C\x06": + # Two bytes in mpy version 6 + find_by_regexp_match = True + compatibility = ("9.0.0-alpha.1", None) + if find_by_regexp_match: + # Too hard to find the version positionally. + # Find the first thing that looks like an x.y.z version number. + match = re.search(rb"([\d]+\.[\d]+\.[\d]+)\x00", content) + if match: + result["__version__"] = match.group(1).decode("utf-8") + elif loc > -1: # Backtrack until a byte value of the offset is reached. offset = 1 while offset < loc: @@ -128,7 +141,4 @@ def extract_metadata(path, logger): else: # not a valid MPY file result["__version__"] = BAD_FILE_FORMAT - - if result: - logger.info("Extracted metadata: %s", result) return result