Index: third_party/google-endpoints/libpasteurize/fixes/fix_features.py |
diff --git a/third_party/google-endpoints/libpasteurize/fixes/fix_features.py b/third_party/google-endpoints/libpasteurize/fixes/fix_features.py |
new file mode 100644 |
index 0000000000000000000000000000000000000000..7e5f545affca1bb50e252706a29c756dfb7409a4 |
--- /dev/null |
+++ b/third_party/google-endpoints/libpasteurize/fixes/fix_features.py |
@@ -0,0 +1,86 @@ |
+u""" |
+Warn about features that are not present in Python 2.5, giving a message that |
+points to the earliest version of Python 2.x (or 3.x, if none) that supports it |
+""" |
+ |
+from .feature_base import Feature, Features |
+from lib2to3 import fixer_base |
+ |
+FEATURES = [ |
+ #(FeatureName, |
+ # FeaturePattern, |
+ # FeatureMinVersion, |
+ #), |
+ (u"memoryview", |
+ u"power < 'memoryview' trailer < '(' any* ')' > any* >", |
+ u"2.7", |
+ ), |
+ (u"numbers", |
+ u"""import_from< 'from' 'numbers' 'import' any* > | |
+ import_name< 'import' ('numbers' dotted_as_names< any* 'numbers' any* >) >""", |
+ u"2.6", |
+ ), |
+ (u"abc", |
+ u"""import_name< 'import' ('abc' dotted_as_names< any* 'abc' any* >) > | |
+ import_from< 'from' 'abc' 'import' any* >""", |
+ u"2.6", |
+ ), |
+ (u"io", |
+ u"""import_name< 'import' ('io' dotted_as_names< any* 'io' any* >) > | |
+ import_from< 'from' 'io' 'import' any* >""", |
+ u"2.6", |
+ ), |
+ (u"bin", |
+ u"power< 'bin' trailer< '(' any* ')' > any* >", |
+ u"2.6", |
+ ), |
+ (u"formatting", |
+ u"power< any trailer< '.' 'format' > trailer< '(' any* ')' > >", |
+ u"2.6", |
+ ), |
+ (u"nonlocal", |
+ u"global_stmt< 'nonlocal' any* >", |
+ u"3.0", |
+ ), |
+ (u"with_traceback", |
+ u"trailer< '.' 'with_traceback' >", |
+ u"3.0", |
+ ), |
+] |
+ |
+class FixFeatures(fixer_base.BaseFix): |
+ |
+ run_order = 9 # Wait until all other fixers have run to check for these |
+ |
+ # To avoid spamming, we only want to warn for each feature once. |
+ features_warned = set() |
+ |
+ # Build features from the list above |
+ features = Features([Feature(name, pattern, version) for \ |
+ name, pattern, version in FEATURES]) |
+ |
+ PATTERN = features.PATTERN |
+ |
+ def match(self, node): |
+ to_ret = super(FixFeatures, self).match(node) |
+ # We want the mapping only to tell us the node's specific information. |
+ try: |
+ del to_ret[u'node'] |
+ except Exception: |
+ # We want it to delete the 'node' from the results |
+ # if it's there, so we don't care if it fails for normal reasons. |
+ pass |
+ return to_ret |
+ |
+ def transform(self, node, results): |
+ for feature_name in results: |
+ if feature_name in self.features_warned: |
+ continue |
+ else: |
+ curr_feature = self.features[feature_name] |
+ if curr_feature.version >= u"3": |
+ fail = self.cannot_convert |
+ else: |
+ fail = self.warning |
+ fail(node, reason=curr_feature.message_text()) |
+ self.features_warned.add(feature_name) |