+++ /dev/null
-"""Fixer for operator functions.\r
-\r
-operator.isCallable(obj) -> hasattr(obj, '__call__')\r
-operator.sequenceIncludes(obj) -> operator.contains(obj)\r
-operator.isSequenceType(obj) -> isinstance(obj, collections.Sequence)\r
-operator.isMappingType(obj) -> isinstance(obj, collections.Mapping)\r
-operator.isNumberType(obj) -> isinstance(obj, numbers.Number)\r
-operator.repeat(obj, n) -> operator.mul(obj, n)\r
-operator.irepeat(obj, n) -> operator.imul(obj, n)\r
-"""\r
-\r
-# Local imports\r
-from lib2to3 import fixer_base\r
-from lib2to3.fixer_util import Call, Name, String, touch_import\r
-\r
-\r
-def invocation(s):\r
- def dec(f):\r
- f.invocation = s\r
- return f\r
- return dec\r
-\r
-\r
-class FixOperator(fixer_base.BaseFix):\r
- BM_compatible = True\r
- order = "pre"\r
-\r
- methods = """\r
- method=('isCallable'|'sequenceIncludes'\r
- |'isSequenceType'|'isMappingType'|'isNumberType'\r
- |'repeat'|'irepeat')\r
- """\r
- obj = "'(' obj=any ')'"\r
- PATTERN = """\r
- power< module='operator'\r
- trailer< '.' %(methods)s > trailer< %(obj)s > >\r
- |\r
- power< %(methods)s trailer< %(obj)s > >\r
- """ % dict(methods=methods, obj=obj)\r
-\r
- def transform(self, node, results):\r
- method = self._check_method(node, results)\r
- if method is not None:\r
- return method(node, results)\r
-\r
- @invocation("operator.contains(%s)")\r
- def _sequenceIncludes(self, node, results):\r
- return self._handle_rename(node, results, u"contains")\r
-\r
- @invocation("hasattr(%s, '__call__')")\r
- def _isCallable(self, node, results):\r
- obj = results["obj"]\r
- args = [obj.clone(), String(u", "), String(u"'__call__'")]\r
- return Call(Name(u"hasattr"), args, prefix=node.prefix)\r
-\r
- @invocation("operator.mul(%s)")\r
- def _repeat(self, node, results):\r
- return self._handle_rename(node, results, u"mul")\r
-\r
- @invocation("operator.imul(%s)")\r
- def _irepeat(self, node, results):\r
- return self._handle_rename(node, results, u"imul")\r
-\r
- @invocation("isinstance(%s, collections.Sequence)")\r
- def _isSequenceType(self, node, results):\r
- return self._handle_type2abc(node, results, u"collections", u"Sequence")\r
-\r
- @invocation("isinstance(%s, collections.Mapping)")\r
- def _isMappingType(self, node, results):\r
- return self._handle_type2abc(node, results, u"collections", u"Mapping")\r
-\r
- @invocation("isinstance(%s, numbers.Number)")\r
- def _isNumberType(self, node, results):\r
- return self._handle_type2abc(node, results, u"numbers", u"Number")\r
-\r
- def _handle_rename(self, node, results, name):\r
- method = results["method"][0]\r
- method.value = name\r
- method.changed()\r
-\r
- def _handle_type2abc(self, node, results, module, abc):\r
- touch_import(None, module, node)\r
- obj = results["obj"]\r
- args = [obj.clone(), String(u", " + u".".join([module, abc]))]\r
- return Call(Name(u"isinstance"), args, prefix=node.prefix)\r
-\r
- def _check_method(self, node, results):\r
- method = getattr(self, "_" + results["method"][0].value.encode("ascii"))\r
- if callable(method):\r
- if "module" in results:\r
- return method\r
- else:\r
- sub = (unicode(results["obj"]),)\r
- invocation_str = unicode(method.invocation) % sub\r
- self.warning(node, u"You should use '%s' here." % invocation_str)\r
- return None\r