Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
def test_pep_572_version_detection(self) -> None:
source, _ = read_data("pep_572")
root = black.lib2to3_parse(source)
features = black.get_features_used(root)
self.assertIn(black.Feature.ASSIGNMENT_EXPRESSIONS, features)
versions = black.detect_target_versions(root)
self.assertIn(black.TargetVersion.PY38, versions)
black.lib2to3_parse(straddling, {TargetVersion.PY27, TargetVersion.PY36})
py2_only = "print x"
black.lib2to3_parse(py2_only)
black.lib2to3_parse(py2_only, {TargetVersion.PY27})
with self.assertRaises(black.InvalidInput):
black.lib2to3_parse(py2_only, {TargetVersion.PY36})
with self.assertRaises(black.InvalidInput):
black.lib2to3_parse(py2_only, {TargetVersion.PY27, TargetVersion.PY36})
py3_only = "exec(x, end=y)"
black.lib2to3_parse(py3_only)
with self.assertRaises(black.InvalidInput):
black.lib2to3_parse(py3_only, {TargetVersion.PY27})
black.lib2to3_parse(py3_only, {TargetVersion.PY36})
black.lib2to3_parse(py3_only, {TargetVersion.PY27, TargetVersion.PY36})
class TargetVersion(Enum):
PY27 = 2
PY33 = 3
PY34 = 4
PY35 = 5
PY36 = 6
PY37 = 7
PY38 = 8
def is_python2(self) -> bool:
return self is TargetVersion.PY27
PY36_VERSIONS = {TargetVersion.PY36, TargetVersion.PY37, TargetVersion.PY38}
class Feature(Enum):
# All string literals are unicode
UNICODE_LITERALS = 1
F_STRINGS = 2
NUMERIC_UNDERSCORES = 3
TRAILING_COMMA_IN_CALL = 4
TRAILING_COMMA_IN_DEF = 5
# The following two feature-flags are mutually exclusive, and exactly one should be
# set for every version of python.
ASYNC_IDENTIFIERS = 6
ASYNC_KEYWORDS = 7
VERSION_TO_FEATURES: Dict[TargetVersion, Set[Feature]] = {
type=lambda v: black.TargetVersion[v.upper()],
default=[],
Feature.UNICODE_LITERALS,
Feature.F_STRINGS,
Feature.NUMERIC_UNDERSCORES,
Feature.TRAILING_COMMA_IN_CALL,
Feature.TRAILING_COMMA_IN_DEF,
Feature.ASYNC_IDENTIFIERS,
},
TargetVersion.PY37: {
Feature.UNICODE_LITERALS,
Feature.F_STRINGS,
Feature.NUMERIC_UNDERSCORES,
Feature.TRAILING_COMMA_IN_CALL,
Feature.TRAILING_COMMA_IN_DEF,
Feature.ASYNC_KEYWORDS,
},
TargetVersion.PY38: {
Feature.UNICODE_LITERALS,
Feature.F_STRINGS,
Feature.NUMERIC_UNDERSCORES,
Feature.TRAILING_COMMA_IN_CALL,
Feature.TRAILING_COMMA_IN_DEF,
Feature.ASYNC_KEYWORDS,
},
}
@dataclass
class FileMode:
target_versions: Set[TargetVersion] = Factory(set)
line_length: int = DEFAULT_LINE_LENGTH
string_normalization: bool = True
is_pyi: bool = False
# The following two feature-flags are mutually exclusive, and exactly one should be
# set for every version of python.
ASYNC_IDENTIFIERS = 6
ASYNC_KEYWORDS = 7
VERSION_TO_FEATURES: Dict[TargetVersion, Set[Feature]] = {
TargetVersion.PY27: {Feature.ASYNC_IDENTIFIERS},
TargetVersion.PY33: {Feature.UNICODE_LITERALS, Feature.ASYNC_IDENTIFIERS},
TargetVersion.PY34: {Feature.UNICODE_LITERALS, Feature.ASYNC_IDENTIFIERS},
TargetVersion.PY35: {
Feature.UNICODE_LITERALS,
Feature.TRAILING_COMMA_IN_CALL,
Feature.ASYNC_IDENTIFIERS,
},
TargetVersion.PY36: {
Feature.UNICODE_LITERALS,
Feature.F_STRINGS,
Feature.NUMERIC_UNDERSCORES,
Feature.TRAILING_COMMA_IN_CALL,
Feature.TRAILING_COMMA_IN_DEF,
Feature.ASYNC_IDENTIFIERS,
},
TargetVersion.PY37: {
Feature.UNICODE_LITERALS,
Feature.F_STRINGS,
Feature.NUMERIC_UNDERSCORES,
Feature.TRAILING_COMMA_IN_CALL,
Feature.TRAILING_COMMA_IN_DEF,
Feature.ASYNC_KEYWORDS,
},
TargetVersion.PY38: {
which is documented at https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/cfn-resource-specification-format.html
"""
import json
import logging
import os.path
import black
import click
import inflection
from jinja2 import FileSystemLoader, Environment
LOGGER = logging.getLogger(os.path.splitext(os.path.basename(__file__))[0])
BLACK_SETTINGS = black.FileMode(
target_versions={black.TargetVersion.PY36, black.TargetVersion.PY37}
)
#: Lookup table of documentation URL's for AWS services. This information does
#: not appear to be in the specification, and does not have a deterministic URL.
AWS_SERVICE_DOCUMENTATION_URLS = {
"AccessAnalyzer": "https://aws.amazon.com/iam/features/analyze-access/",
"AmazonMQ": "https://docs.aws.amazon.com/amazon-mq/latest/developer-guide/welcome.html",
"Amplify": "https://docs.aws.amazon.com/amplify/latest/userguide/getting-started.html",
"ApiGateway": "https://docs.aws.amazon.com/apigateway/latest/developerguide/index.html",
"ApiGatewayV2": "https://docs.aws.amazon.com/apigateway/latest/developerguide/index.html",
"ApplicationAutoScaling": "https://docs.aws.amazon.com/autoscaling/application/APIReference/Welcome.html",
"AppMesh": "https://docs.aws.amazon.com/app-mesh/?id=docs_gateway",
"AppStream": "https://docs.aws.amazon.com/appstream2/latest/developerguide/index.html",
"AppSync": "https://docs.aws.amazon.com/appsync/latest/devguide/welcome.html",
"Athena": "https://docs.aws.amazon.com/athena/latest/ug/what-is.html",
"AutoScaling": "http://docs.aws.amazon.com/autoscaling/latest/userguide/WhatIsAutoScaling.html",
string_normalization=True,
)
LOG.info("flake8-black: loading black settings from %s", toml_filename)
try:
pyproject_toml = toml.load(str(toml_filename))
except toml.decoder.TomlDecodeError:
LOG.info("flake8-black: invalid TOML file %s", toml_filename)
raise BadBlackConfig(path.relpath(toml_filename))
config = pyproject_toml.get("tool", {}).get("black", {})
black_config = {k.replace("--", "").replace("-", "_"): v for k, v in config.items()}
# Extract the fields we care about:
return black.FileMode(
target_versions={
black.TargetVersion[val.upper()]
for val in black_config.get("target_version", [])
},
line_length=black_config.get("line_length", black.DEFAULT_LINE_LENGTH),
string_normalization=not black_config.get("skip_string_normalization", False),
)
def detect_target_versions(node: Node) -> Set[TargetVersion]:
"""Detect the version to target based on the nodes used."""
features = get_features_used(node)
return {
version for version in TargetVersion if features <= VERSION_TO_FEATURES[version]
}
class Feature(Enum):
# All string literals are unicode
UNICODE_LITERALS = 1
F_STRINGS = 2
NUMERIC_UNDERSCORES = 3
TRAILING_COMMA_IN_CALL = 4
TRAILING_COMMA_IN_DEF = 5
# The following two feature-flags are mutually exclusive, and exactly one should be
# set for every version of python.
ASYNC_IDENTIFIERS = 6
ASYNC_KEYWORDS = 7
VERSION_TO_FEATURES: Dict[TargetVersion, Set[Feature]] = {
TargetVersion.PY27: {Feature.ASYNC_IDENTIFIERS},
TargetVersion.PY33: {Feature.UNICODE_LITERALS, Feature.ASYNC_IDENTIFIERS},
TargetVersion.PY34: {Feature.UNICODE_LITERALS, Feature.ASYNC_IDENTIFIERS},
TargetVersion.PY35: {
Feature.UNICODE_LITERALS,
Feature.TRAILING_COMMA_IN_CALL,
Feature.ASYNC_IDENTIFIERS,
},
TargetVersion.PY36: {
Feature.UNICODE_LITERALS,
Feature.F_STRINGS,
Feature.NUMERIC_UNDERSCORES,
Feature.TRAILING_COMMA_IN_CALL,
Feature.TRAILING_COMMA_IN_DEF,
Feature.ASYNC_IDENTIFIERS,
},
TargetVersion.PY37: {