File size: 2,348 Bytes
be0c348
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
50
51
52
53
"""Check syntax, imported local modules, file types and public package hashes."""
import ast
import hashlib
import importlib.util
import json
from pathlib import Path

root = Path(__file__).resolve().parents[1]
allowed = {'.py', '.sh', '.json', '.md', '.yaml', '.yml', '.txt', '.cff', '.sha256'}
files = [p for p in root.rglob('*') if p.is_file() and '__pycache__' not in p.parts]
modules = {}
for path in (root / 'src').rglob('*.py'):
    parts = list(path.relative_to(root / 'src').with_suffix('').parts)
    if parts[-1] == '__init__':
        parts.pop()
    modules['.'.join(parts)] = path
errors = []
for path in files:
    rel = path.relative_to(root).as_posix()
    if path.is_symlink() or path.suffix not in allowed or path.stat().st_size > 2 * 1024 * 1024:
        errors.append(f'Unexpected file: {rel}')
        continue
    text = path.read_text(encoding='utf-8')
    if path.suffix == '.py':
        ast.parse(text, filename=rel)
    if path.suffix == '.json':
        json.loads(text)
for module, path in modules.items():
    package = module if path.name == '__init__.py' else module.rpartition('.')[0]
    for node in ast.walk(ast.parse(path.read_text())):
        targets = []
        if isinstance(node, ast.Import):
            targets = [alias.name for alias in node.names]
        elif isinstance(node, ast.ImportFrom):
            targets = [importlib.util.resolve_name('.' * node.level + (node.module or ''), package)
                       if node.level else node.module or '']
        for target in targets:
            if target.startswith('llamafactory') and target not in modules:
                errors.append(f'Missing local import: {module} -> {target}')
manifest = root / 'MANIFEST.sha256'
expected_paths = set()
for line in manifest.read_text().splitlines():
    digest, relative = line.split('  ', 1)
    expected_paths.add(relative)
    path = root / relative
    if not path.is_file() or hashlib.sha256(path.read_bytes()).hexdigest() != digest:
        errors.append(f'Checksum mismatch: {relative}')
if expected_paths != {p.relative_to(root).as_posix() for p in files if p != manifest}:
    errors.append('Checksum manifest and package file set differ')
if errors:
    raise SystemExit('\n'.join(errors))
print(f'Passed: {len(files)} package files, {len(modules)} source modules, syntax, imports and hashes.')