Ejemplo n.º 1
0
def _pick_compatible_python_version(version: Optional[str] = None) -> PythonVersionInfo:
    max_version = parse_version_string(version)
    for v in KNOWN_PYTHON_VERSION_STRINGS[::-1]:
        tmp = parse_version_string(v)
        if tmp <= max_version:
            return tmp

    raise ValueError(
        f"No version found older than {version} ({max_version}) while "
        + f"running on {sys.version_info}"
    )
Ejemplo n.º 2
0
    def __post_init__(self) -> None:
        raw_python_version = self.python_version

        if isinstance(raw_python_version, AutoConfig):
            # If unspecified, we'll try to pick the same as the running
            # interpreter.  There will always be at least one entry.
            parsed_python_version = _pick_compatible_python_version()
        else:
            # If the caller specified a version, we require that to be a known
            # version (because we don't want to encourage doing duplicate work
            # when there weren't syntax changes).

            # `parse_version_string` will raise a ValueError if the version is
            # invalid.
            parsed_python_version = parse_version_string(raw_python_version)

        if not any(
            parsed_python_version == parse_version_string(v)
            for v in KNOWN_PYTHON_VERSION_STRINGS
        ):
            comma_versions = ", ".join(KNOWN_PYTHON_VERSION_STRINGS)
            raise ValueError(
                "LibCST can only parse code using one of the following versions of "
                + f"Python's grammar: {comma_versions}. More versions may be "
                + "supported by future releases."
            )

        # We use object.__setattr__ because the dataclass is frozen. See:
        # https://docs.python.org/3/library/dataclasses.html#frozen-instances
        # This should be safe behavior inside of `__post_init__`.
        object.__setattr__(self, "parsed_python_version", parsed_python_version)

        encoding = self.encoding
        if not isinstance(encoding, AutoConfig):
            try:
                codecs.lookup(encoding)
            except LookupError:
                raise ValueError(f"{repr(encoding)} is not a supported encoding")

        newline = self.default_newline
        if (
            not isinstance(newline, AutoConfig)
            and NEWLINE_RE.fullmatch(newline) is None
        ):
            raise ValueError(
                f"Got an invalid value for default_newline: {repr(newline)}"
            )

        indent = self.default_indent
        if not isinstance(indent, AutoConfig) and _INDENT_RE.fullmatch(indent) is None:
            raise ValueError(f"Got an invalid value for default_indent: {repr(indent)}")
Ejemplo n.º 3
0
    def __post_init__(self) -> None:
        raw_python_version = self.python_version
        # `parse_version_string` will raise a ValueError if the version is invalid.
        #
        # We use object.__setattr__ because the dataclass is frozen. See:
        # https://docs.python.org/3/library/dataclasses.html#frozen-instances
        # This should be safe behavior inside of `__post_init__`.
        parsed_python_version = parse_version_string(
            None if isinstance(raw_python_version, AutoConfig) else raw_python_version
        )

        # Once we add support for more versions of Python, we can change this to detect
        # the supported version range.
        if not any(
            parsed_python_version == parse_version_string(v)
            for v in KNOWN_PYTHON_VERSION_STRINGS
        ):
            comma_versions = ", ".join(KNOWN_PYTHON_VERSION_STRINGS)
            raise ValueError(
                "LibCST can only parse code using one of the following versions of "
                + f"Python's grammar: {comma_versions}. More versions may be "
                + "supported by future releases."
            )

        object.__setattr__(self, "parsed_python_version", parsed_python_version)

        encoding = self.encoding
        if not isinstance(encoding, AutoConfig):
            try:
                codecs.lookup(encoding)
            except LookupError:
                raise ValueError(f"{repr(encoding)} is not a supported encoding")

        newline = self.default_newline
        if (
            not isinstance(newline, AutoConfig)
            and NEWLINE_RE.fullmatch(newline) is None
        ):
            raise ValueError(
                f"Got an invalid value for default_newline: {repr(newline)}"
            )

        indent = self.default_indent
        if not isinstance(indent, AutoConfig) and _INDENT_RE.fullmatch(indent) is None:
            raise ValueError(f"Got an invalid value for default_indent: {repr(indent)}")
Ejemplo n.º 4
0
def _get_version_comparison(version: str) -> Tuple[str, PythonVersionInfo]:
    if version[:2] in (">=", "<=", "==", "!="):
        return (version[:2], parse_version_string(version[2:].strip()))
    if version[:1] in (">", "<"):
        return (version[:1], parse_version_string(version[1:].strip()))
    raise Exception(f"Invalid version comparison specifier '{version}'")
Ejemplo n.º 5
0
 def __init__(self, bnf_grammar: str) -> None:
     self._bnf_grammar: str = bnf_grammar
     self.generator = tokenize(bnf_grammar, version_info=parse_version_string("3.6"))
     self._gettoken()  # Initialize lookahead
Ejemplo n.º 6
0
def _get_token_list(string, version=None):
    # Load the current version.
    version_info = parse_version_string(version)
    return list(tokenize(string, version_info))
Ejemplo n.º 7
0
 def test_tokenize_start_pos(self, code, positions):
     tokens = list(tokenize(code, version_info=parse_version_string("3.6")))
     assert positions == [p.start_pos for p in tokens]