diff --git a/python/src/com/jetbrains/python/inspections/PyStringFormatInspection.java b/python/src/com/jetbrains/python/inspections/PyStringFormatInspection.java
index 5e13ae5c6f45..dcb1565cfdc2 100644
--- a/python/src/com/jetbrains/python/inspections/PyStringFormatInspection.java
+++ b/python/src/com/jetbrains/python/inspections/PyStringFormatInspection.java
@@ -83,6 +83,7 @@ public class PyStringFormatInspection extends PyInspection {
.put('G', "float")
.put('c', "str")
.put('r', "str")
+ .put('a', "str")
.put('s', "str")
.put('b', "bytes")
.build();
@@ -402,7 +403,8 @@ public class PyStringFormatInspection extends PyInspection {
return;
}
}
- if (PERCENT_FORMAT_CONVERSIONS.containsKey(conversionType)) {
+ final LanguageLevel languageLevel = LanguageLevel.forElement(formatExpression);
+ if (PERCENT_FORMAT_CONVERSIONS.containsKey(conversionType) && !(!languageLevel.isPy3K() && conversionType == 'a')) {
myFormatSpec.put(mappingKey, PERCENT_FORMAT_CONVERSIONS.get(conversionType));
continue;
}
diff --git a/python/src/com/jetbrains/python/inspections/PyStringFormatParser.java b/python/src/com/jetbrains/python/inspections/PyStringFormatParser.java
index 19ae0a6834fc..e074960f0f52 100644
--- a/python/src/com/jetbrains/python/inspections/PyStringFormatParser.java
+++ b/python/src/com/jetbrains/python/inspections/PyStringFormatParser.java
@@ -271,7 +271,7 @@ public class PyStringFormatParser {
private static final String CONVERSION_FLAGS = "#0- +";
private static final String DIGITS = "0123456789";
private static final String LENGTH_MODIFIERS = "hlL";
- private static final String VALID_CONVERSION_TYPES = "diouxXeEfFgGcrsb";
+ private static final String VALID_CONVERSION_TYPES = "diouxXeEfFgGcrsba";
// new style strings
private static final String ALIGN_SYMBOLS = "<>=^";
diff --git a/python/testData/inspections/PyStringFormatInspection/Py3kAsciiFormatSpecifier.py b/python/testData/inspections/PyStringFormatInspection/Py3kAsciiFormatSpecifier.py
new file mode 100644
index 000000000000..c1f2cd29e697
--- /dev/null
+++ b/python/testData/inspections/PyStringFormatInspection/Py3kAsciiFormatSpecifier.py
@@ -0,0 +1,2 @@
+"foo %a" % "foo"
+"foo %q" % "foo"
\ No newline at end of file
diff --git a/python/testSrc/com/jetbrains/python/PyStringFormatParserTest.java b/python/testSrc/com/jetbrains/python/PyStringFormatParserTest.java
index 681221fa23a7..44bb3a790a90 100644
--- a/python/testSrc/com/jetbrains/python/PyStringFormatParserTest.java
+++ b/python/testSrc/com/jetbrains/python/PyStringFormatParserTest.java
@@ -552,4 +552,11 @@ public class PyStringFormatParserTest extends TestCase {
assertEquals("a", chunk.getMappingKeyElementIndex());
assertEquals('d', chunk.getConversionType());
}
+
+ public void testAsciiFormatSpecifierOldStyleFormat() {
+ final List chunks = parsePercentFormat("%a");
+ assertEquals(1, chunks.size());
+ final PercentSubstitutionChunk chunk = (PercentSubstitutionChunk)chunks.get(0);
+ assertEquals('a', chunk.getConversionType());
+ }
}
diff --git a/python/testSrc/com/jetbrains/python/inspections/PyStringFormatInspectionTest.java b/python/testSrc/com/jetbrains/python/inspections/PyStringFormatInspectionTest.java
index 9f3406e69e6e..7fbd033f61ac 100644
--- a/python/testSrc/com/jetbrains/python/inspections/PyStringFormatInspectionTest.java
+++ b/python/testSrc/com/jetbrains/python/inspections/PyStringFormatInspectionTest.java
@@ -16,6 +16,7 @@
package com.jetbrains.python.inspections;
import com.jetbrains.python.fixtures.PyTestCase;
+import com.jetbrains.python.psi.LanguageLevel;
/**
* @author vlan
@@ -188,6 +189,16 @@ public class PyStringFormatInspectionTest extends PyTestCase {
doTest();
}
+ // PY-20599
+ public void testPy3kAsciiFormatSpecifier() {
+ runWithLanguageLevel(LanguageLevel.PYTHON35, new Runnable() {
+ @Override
+ public void run() {
+ doTest();
+ }
+ });
+ }
+
private void doTest() {
myFixture.configureByFile(TEST_DIRECTORY + getTestName(false) + ".py");
myFixture.enableInspections(PyStringFormatInspection.class);