Skip to content

Instantly share code, notes, and snippets.

@mallamanis
Last active April 30, 2020 17:24
Show Gist options
  • Save mallamanis/6b83d3aa4ae36c3f3f7699348396f5fa to your computer and use it in GitHub Desktop.
Save mallamanis/6b83d3aa4ae36c3f3f7699348396f5fa to your computer and use it in GitHub Desktop.
Use generator expression instead of list comprehension
/**
* @name Prefer Generator to List Comprehension
* @description List comprehensions can be avoided in favor of
* @kind problem
* @tags reliability
* maintainability
* @problem.severity recommendation
* @sub-severity low
* @precision medium
* @id py/no-list-comprh
*/
import python
predicate accepts_iterable(Call call, ListComp lstcomp) {
(
call.getFunc().pointsTo().toString() = "Method(builtin method extend, List)" or
call.getFunc().pointsTo().toString() = "Method(builtin method update, set())" or
call.getFunc().(Attribute).getName() = "join" or // str.join
call.getFunc().pointsTo(Value::named("max")) or
call.getFunc().pointsTo(Value::named("min")) or
call.getFunc().pointsTo(Value::named("sum")) or
call.getFunc().pointsTo(Value::named("any")) or
call.getFunc().pointsTo(Value::named("all")) or
call.getFunc().pointsTo(Value::named("enumerate")) or
call.getFunc().pointsTo(Value::named("list")) or
call.getFunc().pointsTo(Value::named("set")) or
call.getFunc().pointsTo(Value::named("frozenset"))
) and
call.getAPositionalArg() = lstcomp
}
predicate loop_with_list_comp(For loop, ListComp lstcomp) {
loop.getIter() = lstcomp
}
from AstNode node
where
exists(ListComp lstcomp |
loop_with_list_comp(node.(For), lstcomp) or
accepts_iterable(node.(Call), lstcomp))
select node, "List comprehension can be replaced with a generator."
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment