Use FnvHasher for unordered maps and sets (#708)

This commit is contained in:
Charlie Marsh
2022-11-12 16:09:34 -05:00
committed by GitHub
parent aa7681f9ad
commit 8cfc0e5cf5
11 changed files with 42 additions and 45 deletions

1
Cargo.lock generated
View File

@@ -2253,6 +2253,7 @@ dependencies = [
"dirs 4.0.0",
"fern",
"filetime",
"fnv",
"getrandom 0.2.8",
"glob",
"insta",

View File

@@ -23,6 +23,7 @@ common-path = { version = "1.0.0" }
dirs = { version = "4.0.0" }
fern = { version = "0.6.1" }
filetime = { version = "0.2.17" }
fnv = { version = "1.0.7" }
glob = { version = "0.3.0" }
itertools = { version = "0.10.5" }
libcst = { git = "https://github.com/charliermarsh/LibCST", rev = "a13ec97dd4eb925bde4d426c6e422582793b260c" }

View File

@@ -1,5 +1,4 @@
use std::collections::BTreeSet;
use fnv::FnvHashSet;
use once_cell::sync::Lazy;
use regex::Regex;
use rustpython_ast::{Excepthandler, ExcepthandlerKind, Expr, ExprKind, Location, StmtKind};
@@ -47,7 +46,7 @@ pub fn match_name_or_attr_from_module(
expr: &Expr,
target: &str,
module: &str,
imports: Option<&BTreeSet<&str>>,
imports: Option<&FnvHashSet<&str>>,
) -> bool {
match &expr.node {
ExprKind::Attribute { value, attr, .. } => match &value.node {

View File

@@ -1,9 +1,10 @@
//! Lint rules based on AST traversal.
use std::collections::{BTreeMap, BTreeSet};
use std::collections::BTreeMap;
use std::ops::Deref;
use std::path::Path;
use fnv::{FnvHashMap, FnvHashSet};
use log::error;
use rustpython_parser::ast::{
Arg, Arguments, Constant, Excepthandler, ExcepthandlerKind, Expr, ExprContext, ExprKind,
@@ -64,9 +65,9 @@ pub struct Checker<'a> {
definitions: Vec<(Definition<'a>, Visibility)>,
// Edit tracking.
// TODO(charlie): Instead of exposing deletions, wrap in a public API.
pub(crate) deletions: BTreeSet<usize>,
pub(crate) deletions: FnvHashSet<usize>,
// Import tracking.
pub(crate) from_imports: BTreeMap<&'a str, BTreeSet<&'a str>>,
pub(crate) from_imports: FnvHashMap<&'a str, FnvHashSet<&'a str>>,
// Retain all scopes and parent nodes, along with a stack of indexes to track which are active
// at various points in time.
pub(crate) parents: Vec<&'a Stmt>,
@@ -409,14 +410,14 @@ where
StmtKind::Return { .. } => {
if self.settings.enabled.contains(&CheckCode::F706) {
if let Some(index) = self.scope_stack.last().cloned() {
match self.scopes[index].kind {
ScopeKind::Class(_) | ScopeKind::Module => {
self.add_check(Check::new(
CheckKind::ReturnOutsideFunction,
Range::from_located(stmt),
));
}
_ => {}
if matches!(
self.scopes[index].kind,
ScopeKind::Class(_) | ScopeKind::Module
) {
self.add_check(Check::new(
CheckKind::ReturnOutsideFunction,
Range::from_located(stmt),
));
}
}
}
@@ -592,7 +593,7 @@ where
if TRACK_FROM_IMPORTS.contains(&module.as_str()) {
self.from_imports
.entry(module)
.or_insert_with(BTreeSet::new)
.or_insert_with(FnvHashSet::default)
.extend(
names
.iter()

View File

@@ -43,7 +43,7 @@ where
match &expr.node {
ExprKind::Call { func, args, .. } => {
if !is_mutable_func(func)
&& !is_immutable_func(func, &self.extend_immutable_calls)
&& !is_immutable_func(func, self.extend_immutable_calls)
&& !is_nan_or_infinity(func, args)
{
self.checks.push((

View File

@@ -1,5 +1,4 @@
use std::collections::BTreeMap;
use fnv::FnvHashMap;
use rustpython_ast::{Expr, ExprKind, Stmt};
use crate::ast::types::Range;
@@ -12,7 +11,7 @@ use crate::checks::{Check, CheckKind};
/// Identify all `ExprKind::Name` nodes in an AST.
struct NameFinder<'a> {
/// A map from identifier to defining expression.
names: BTreeMap<&'a str, &'a Expr>,
names: FnvHashMap<&'a str, &'a Expr>,
}
impl NameFinder<'_> {

View File

@@ -4,10 +4,10 @@ expression: checks
---
- kind: FunctionCallArgumentDefault
location:
row: 15
row: 16
column: 66
end_location:
row: 15
row: 16
column: 77
fix: ~

View File

@@ -1,11 +1,10 @@
use std::collections::{BTreeMap, BTreeSet};
use fnv::{FnvHashMap, FnvHashSet};
use once_cell::sync::Lazy;
use rustpython_ast::{Expr, ExprKind};
// See: https://pypi.org/project/typing-extensions/
static TYPING_EXTENSIONS: Lazy<BTreeSet<&'static str>> = Lazy::new(|| {
BTreeSet::from([
static TYPING_EXTENSIONS: Lazy<FnvHashSet<&'static str>> = Lazy::new(|| {
FnvHashSet::from_iter([
"Annotated",
"Any",
"AsyncContextManager",
@@ -64,9 +63,9 @@ pub fn in_extensions(name: &str) -> bool {
}
// See: https://docs.python.org/3/library/typing.html
static IMPORTED_SUBSCRIPTS: Lazy<BTreeMap<&'static str, BTreeSet<&'static str>>> =
static IMPORTED_SUBSCRIPTS: Lazy<FnvHashMap<&'static str, FnvHashSet<&'static str>>> =
Lazy::new(|| {
let mut import_map = BTreeMap::new();
let mut import_map = FnvHashMap::default();
for (name, module) in [
// `collections`
("ChainMap", "collections"),
@@ -183,7 +182,7 @@ static IMPORTED_SUBSCRIPTS: Lazy<BTreeMap<&'static str, BTreeSet<&'static str>>>
] {
import_map
.entry(name)
.or_insert_with(BTreeSet::new)
.or_insert_with(FnvHashSet::default)
.insert(module);
}
import_map
@@ -191,13 +190,13 @@ static IMPORTED_SUBSCRIPTS: Lazy<BTreeMap<&'static str, BTreeSet<&'static str>>>
// These are all assumed to come from the `typing` module.
// See: https://peps.python.org/pep-0585/
static PEP_585_BUILTINS_ELIGIBLE: Lazy<BTreeSet<&'static str>> =
Lazy::new(|| BTreeSet::from(["Dict", "FrozenSet", "List", "Set", "Tuple", "Type"]));
static PEP_585_BUILTINS_ELIGIBLE: Lazy<FnvHashSet<&'static str>> =
Lazy::new(|| FnvHashSet::from_iter(["Dict", "FrozenSet", "List", "Set", "Tuple", "Type"]));
// These are all assumed to come from the `typing` module.
// See: https://peps.python.org/pep-0585/
static PEP_585_BUILTINS: Lazy<BTreeSet<&'static str>> =
Lazy::new(|| BTreeSet::from(["dict", "frozenset", "list", "set", "tuple", "type"]));
static PEP_585_BUILTINS: Lazy<FnvHashSet<&'static str>> =
Lazy::new(|| FnvHashSet::from_iter(["dict", "frozenset", "list", "set", "tuple", "type"]));
fn is_pep593_annotated_subscript(name: &str) -> bool {
name == "Annotated"
@@ -210,7 +209,7 @@ pub enum SubscriptKind {
pub fn match_annotated_subscript(
expr: &Expr,
imports: &BTreeMap<&str, BTreeSet<&str>>,
imports: &FnvHashMap<&str, FnvHashSet<&str>>,
) -> Option<SubscriptKind> {
match &expr.node {
ExprKind::Attribute { attr, value, .. } => {
@@ -261,7 +260,7 @@ pub fn match_annotated_subscript(
/// Returns `true` if `Expr` represents a reference to a typing object with a
/// PEP 585 built-in. Note that none of the PEP 585 built-ins are in
/// `typing_extensions`.
pub fn is_pep585_builtin(expr: &Expr, typing_imports: Option<&BTreeSet<&str>>) -> bool {
pub fn is_pep585_builtin(expr: &Expr, typing_imports: Option<&FnvHashSet<&str>>) -> bool {
match &expr.node {
ExprKind::Attribute { attr, value, .. } => {
if let ExprKind::Name { id, .. } = &value.node {

View File

@@ -1,5 +1,4 @@
use std::collections::BTreeSet;
use fnv::FnvHashSet;
use rustpython_ast::{Constant, KeywordData};
use rustpython_parser::ast::{ArgData, Expr, ExprKind, Stmt, StmtKind};
@@ -164,7 +163,7 @@ pub fn type_of_primitive(func: &Expr, args: &[Expr], location: Range) -> Option<
pub fn unnecessary_lru_cache_params(
decorator_list: &[Expr],
target_version: PythonVersion,
imports: Option<&BTreeSet<&str>>,
imports: Option<&FnvHashSet<&str>>,
) -> Option<Check> {
for expr in decorator_list.iter() {
if let ExprKind::Call {

View File

@@ -1,5 +1,4 @@
use std::collections::BTreeMap;
use fnv::FnvHashMap;
use once_cell::sync::Lazy;
use rustpython_ast::{Expr, ExprKind};
@@ -8,8 +7,8 @@ use crate::autofix::Fix;
use crate::check_ast::Checker;
use crate::checks::{Check, CheckKind};
static DEPRECATED_ALIASES: Lazy<BTreeMap<&'static str, &'static str>> = Lazy::new(|| {
BTreeMap::from([
static DEPRECATED_ALIASES: Lazy<FnvHashMap<&'static str, &'static str>> = Lazy::new(|| {
FnvHashMap::from_iter([
("failUnlessEqual", "assertEqual"),
("assertEquals", "assertEqual"),
("failIfEqual", "assertNotEqual"),

View File

@@ -1,5 +1,4 @@
use std::collections::BTreeMap;
use fnv::FnvHashMap;
use once_cell::sync::Lazy;
use rustpython_ast::Location;
@@ -10,8 +9,8 @@ use crate::source_code_locator::SourceCodeLocator;
use crate::Check;
/// See: https://github.com/microsoft/vscode/blob/095ddabc52b82498ee7f718a34f9dd11d59099a8/src/vs/base/common/strings.ts#L1094
static CONFUSABLES: Lazy<BTreeMap<u32, u32>> = Lazy::new(|| {
BTreeMap::from([
static CONFUSABLES: Lazy<FnvHashMap<u32, u32>> = Lazy::new(|| {
FnvHashMap::from_iter([
(8232, 32),
(8233, 32),
(5760, 32),