• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

pantsbuild / pants / 18517631058

15 Oct 2025 04:18AM UTC coverage: 69.207% (-11.1%) from 80.267%
18517631058

Pull #22745

github

web-flow
Merge 642a76ca1 into 99919310e
Pull Request #22745: [windows] Add windows support in the stdio crate.

53815 of 77759 relevant lines covered (69.21%)

2.42 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

33.33
/src/python/pants/util/cstutil.py
1
# Copyright 2024 Pants project contributors (see CONTRIBUTORS.md).
2
# Licensed under the Apache License, Version 2.0 (see LICENSE).
3

4
from __future__ import annotations
7✔
5

6
import importlib.util
7✔
7
import logging
7✔
8

9
import libcst as cst
7✔
10
import libcst.matchers as m
7✔
11

12
logger = logging.getLogger(__name__)
7✔
13

14

15
def make_importfrom(module: str, func: str) -> cst.ImportFrom:
7✔
16
    """Generates a cst.ImportFrom from a module and function string."""
17
    return cst.ImportFrom(
×
18
        module=make_importfrom_attr(module), names=[cst.ImportAlias(cst.Name(func))]
19
    )
20

21

22
def make_importfrom_attr(module: str) -> cst.Attribute | cst.Name:
7✔
23
    """Generates a cst.Attribute or cst.Name from a module string."""
24
    parts = module.split(".")
×
25
    if len(parts) == 1:
×
26
        return cst.Name(parts[0])
×
27

28
    partial_module = ".".join(parts[:-1])
×
29
    return cst.Attribute(value=make_importfrom_attr(partial_module), attr=cst.Name(parts[-1]))
×
30

31

32
def make_importfrom_attr_matcher(module: str) -> m.Attribute | m.Name:
7✔
33
    """Generates a cst matcher.Attribute or matcher.Name from a module string."""
34
    parts = module.split(".")
×
35
    if len(parts) == 1:
×
36
        return m.Name(parts[0])
×
37

38
    partial_module = ".".join(parts[:-1])
×
39
    return m.Attribute(value=make_importfrom_attr_matcher(partial_module), attr=m.Name(parts[-1]))
×
40

41

42
def extract_functiondef_from_module(module: str, func: str) -> cst.FunctionDef | None:
7✔
43
    """Parse the file associated with the module return `func` as a FunctionDef."""
44
    if not (spec := importlib.util.find_spec(module)):
×
45
        logger.warning(f"Failed to find module {module}")
×
46
        return None
×
47

48
    assert spec.origin is not None
×
49
    with open(spec.origin) as f:
×
50
        source_code = f.read()
×
51
        tree = cst.parse_module(source_code)
×
52
        results = m.findall(
×
53
            tree, matcher=m.FunctionDef(m.Name(func), asynchronous=m.Asynchronous())
54
        )
55
        return cst.ensure_type(results[0], cst.FunctionDef) if results else None
×
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc