feat(core): Add support for Python docstrings (#2038)

* feat(core): Add support for Python docstrings

* Remove unused dependency

* Revert "Remove unused dependency"

This reverts commit 5720b2eced.

* Fix for harper-ls

* Fix handling of multiline strings

* Fix merge artifact

* Formatting fix

* Do not pass quotes for linting

---------

Co-authored-by: Elijah Potter <me@elijahpotter.dev>
This commit is contained in:
Artem Golubin 2025-10-02 00:36:39 +04:00 committed by GitHub
parent 84a52e3988
commit 041d5a0b16
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
15 changed files with 209 additions and 5 deletions

View file

@ -0,0 +1,41 @@
use harper_core::linting::{LintGroup, Linter};
use harper_core::spell::FstDictionary;
use harper_core::{Dialect, Document};
use harper_python::PythonParser;
/// Creates a unit test checking Python source code parsing.
macro_rules! create_test {
($filename:ident.$ext:ident, $correct_expected:expr) => {
paste::paste! {
#[test]
fn [<lints_$ext _ $filename _correctly>](){
let source = include_str!(
concat!(
"./test_sources/",
concat!(
stringify!($filename), ".", stringify!($ext))
)
);
let parser = PythonParser::default();
let dict = FstDictionary::curated();
let document = Document::new(&source, &parser, &dict);
let mut linter = LintGroup::new_curated(dict, Dialect::American);
let lints = linter.lint(&document);
dbg!(&lints);
assert_eq!(lints.len(), $correct_expected);
// Make sure that all generated tokens span real characters
for token in document.tokens(){
assert!(token.span.try_get_content(document.get_source()).is_some());
}
}
}
};
}
create_test!(docstrings.py, 4);
create_test!(field_docstrings.py, 2);
create_test!(comments.py, 1);

View file

@ -0,0 +1,7 @@
# This is a camment.
header = "This is a haeder."
def main():
welcome_message = "Hellom World!"

View file

@ -0,0 +1,22 @@
"""Errors should never passs silently"""
def main():
"""Beautifull is better than ugly."""
class Main:
"""Explicit is better than implicet."""
def __init__(self):
"""Flat is bettter than nested."""
pass
def multiline_docstring(action_name: str):
"""Perform the specified action.
Available actions:
- stop
- start
- pause
"""

View file

@ -0,0 +1,5 @@
class Result:
output_path: str
"""The path to the autput file."""
status: str
"""The stotus of the job."""