Repository: psf/black
File: src/black/__init__.py (Python)

Code before:


def get_features_used(node: Node) -> Set[Feature]:  # noqa: C901
    """Return a set of (relatively) new Python features used in this file.

    Currently looking for:
    - f-strings;
    - underscores in numeric literals;
    - trailing commas after * or ** in function signatures and calls;
    - positional only arguments in function signatures and lambdas;
    - assignment expression;
    - relaxed decorator syntax;
    - print / exec statements;
    """
    features: Set[Feature] = set()
    for n in node.pre_order():
        if n.type == token.STRING:
            value_head = n.value[:2]  # type: ignore
            if value_head in {'f"', 'F"', "f'", "F'", "rf", "fr", "RF", "FR"}:
                features.add(Feature.F_STRINGS)

        elif n.type == token.NUMBER:
            assert isinstance(n, Leaf)
            if "_" in n.value:
                features.add(Feature.NUMERIC_UNDERSCORES)
            elif n.value.endswith("L"):
                # Python 2: 10L
                features.add(Feature.LONG_INT_LITERAL)

        elif n.type == token.SLASH:
            if n.parent and n.parent.type in {
                syms.typedargslist,
                syms.arglist,
                syms.varargslist,
            }:
                features.add(Feature.POS_ONLY_ARGUMENTS)

        elif n.type == token.COLONEQUAL:
            features.add(Feature.ASSIGNMENT_EXPRESSIONS)

        elif n.type == syms.decorator:
            if len(n.children) > 1 and not is_simple_decorator_expression(
                n.children[1]
            ):
                features.add(Feature.RELAXED_DECORATORS)

        elif (
            n.type in {syms.typedargslist, syms.arglist}
            and n.children
            and n.children[-1].type == token.COMMA
        ):

Review comment (suggestion):
```suggestion
            elif n.value.endswith(("l", "L")):
```
It can be lowercase too.

Also, we could look for `010` (old octal syntax), which doesn't work in 3.0 any more. This is in https://docs.python.org/3/whatsnew/3.0.html#integers and PEP 3127. We could check that the first char is 0 and the second is a digit.

Code after:


def get_features_used(node: Node) -> Set[Feature]:  # noqa: C901
    """Return a set of (relatively) new Python features used in this file.

    Currently looking for:
    - f-strings;
    - underscores in numeric literals;
    - trailing commas after * or ** in function signatures and calls;
    - positional only arguments in function signatures and lambdas;
    - assignment expression;
    - relaxed decorator syntax;
    - print / exec statements;
    """
    features: Set[Feature] = set()
    for n in node.pre_order():
        if n.type == token.STRING:
            value_head = n.value[:2]  # type: ignore
            if value_head in {'f"', 'F"', "f'", "F'", "rf", "fr", "RF", "FR"}:
                features.add(Feature.F_STRINGS)

        elif n.type == token.NUMBER:
            assert isinstance(n, Leaf)
            if "_" in n.value:
                features.add(Feature.NUMERIC_UNDERSCORES)
            elif n.value.endswith(("L", "l")):
                # Python 2: 10L
                features.add(Feature.LONG_INT_LITERAL)
            elif len(n.value) >= 2 and n.value[0] == "0" and n.value[1].isdigit():
                # Python 2: 0123; 00123; ...
                if not all(char == "0" for char in n.value):
                    # although we don't want to match 0000 or similar
                    features.add(Feature.OCTAL_INT_LITERAL)

        elif n.type == token.SLASH:
            if n.parent and n.parent.type in {
                syms.typedargslist,
                syms.arglist,
                syms.varargslist,
            }:
                features.add(Feature.POS_ONLY_ARGUMENTS)

        elif n.type == token.COLONEQUAL:
            features.add(Feature.ASSIGNMENT_EXPRESSIONS)

        elif n.type == syms.decorator:
            if len(n.children) > 1 and not is_simple_decorator_expression(
                n.children[1]
            ):
                features.add(Feature.RELAXED_DECORATORS)