1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
use {anyhow::Result, lazy_static::lazy_static};
lazy_static! {
static ref RE_CODING: regex::bytes::Regex =
regex::bytes::Regex::new(r"^[ \t\f]*#.*?coding[:=][ \t]*([-_.a-zA-Z0-9]+)").unwrap();
}
pub fn python_source_encoding(source: &[u8]) -> Vec<u8> {
let lines = source.split(|v| v == &b'\n');
for (i, line) in lines.enumerate() {
if i > 1 {
break;
}
if let Some(m) = RE_CODING.find(line) {
return m.as_bytes().to_vec();
}
}
b"utf-8".to_vec()
}
pub fn has_dunder_file(source: &[u8]) -> Result<bool> {
let encoding = python_source_encoding(source);
let encoder = match encoding_rs::Encoding::for_label(&encoding) {
Some(encoder) => encoder,
None => encoding_rs::UTF_8,
};
let (source, ..) = encoder.decode(source);
Ok(source.contains("__file__"))
}