Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Inquiry Regarding Absolute Paths in Ruff #9417

Closed
brupelo opened this issue Jan 6, 2024 · 12 comments
Closed

Inquiry Regarding Absolute Paths in Ruff #9417

brupelo opened this issue Jan 6, 2024 · 12 comments
Labels
question Asking for support or clarification

Comments

@brupelo
Copy link

brupelo commented Jan 6, 2024

Hello everyone,

I'm a new user of Ruff and I'm amazed by its capabilities. Today, while exploring the tool, I came across an aspect that I wanted to inquire about. I noticed that the current version I'm using (ruff 0.1.11) seems to output relative paths.

I observed an ongoing pull request (#8560) in the repository, but I'm uncertain if it addresses the specific issue I'm encountering. Could someone kindly confirm if the mentioned PR addresses the output of absolute paths?

The reason I'm particularly interested in the ability to dump absolute paths is due to the necessity of integrating Rust into some existing IDEs. Typically, tools utilize 'file_regex' to enable users to navigate to the file/line/column, a feature often extracted by the linter.

Previously, with tools like isort, black, flake8, and autoflake, working with absolute paths was feasible. However, upon installing Ruff, I noticed that it outputs relative paths, which can result in a lossy process when triggered from certain plugins.

I would greatly appreciate any insights or updates on this matter.

Thank you,

@charliermarsh
Copy link
Member

Thank you for the kind words!

Unfortunately we don't expose a setting to write out absolute paths everywhere. We do however use absolute paths when you run with --output-format=json, since that tends to be the recommended format for machine-readable outputs. Would that solve your problem?

@charliermarsh charliermarsh added the question Asking for support or clarification label Jan 6, 2024
@brupelo
Copy link
Author

brupelo commented Jan 7, 2024

@charliermarsh Firstly, I appreciate the swift response and the suggestion regarding --output-format=json. While it's undoubtedly helpful, it doesn't precisely align with my use case. I'm currently developing a SublimeText plugin that channels the stdout of the ruff process into a dedicated widget within Sublime Text. This widget operates behind the scenes, handling tasks like opening files, specific lines, and columns, which makes the direct use of --output-format=json less applicable for my needs.

To illustrate, here's a snippet of how this widget creation typically looks within Sublime Text:

view = window.create_output_panel(name)
view.settings().set("result_file_regex", file_regex)
view.settings().set("result_line_regex", line_regex)
view.settings().set("result_base_dir", working_dir)
view.settings().set("word_wrap", word_wrap)
view.settings().set("line_numbers", line_numbers)
view.settings().set("gutter", gutter)
view.settings().set("scroll_past_end", scroll_past_end)
view.assign_syntax(syntax)

Earlier, my approach involved using several commands, each producing absolute paths

    commands = [
        f"{isort} -q -rc -sp {isort_config_file} %(paths)s",
        f"{autoflake} --remove-all-unused-imports --ignore-init-module-imports --in-place %(paths)s",
        f"{black} --config {black_config_file} %(paths)s",
        # f"{ruff} --config={ruff_config_file} %(paths)s",
        f"{flake8} --config={flake8_config_file} %(paths)s",
    ]

As a result, I hadn't previously considered setting the working directory on the widget, which indeed allows relative paths to function seamlessly.

Considering the comprehensive abilities ruff presents, it might be beneficial to grant users more control over how ruff's output is displayed. Certain linters offer this flexibility, easing the integration of ruff with various IDEs and editors.

Now, an off-topic question: considering the commands I've been using previously, which ones might become redundant with the integration of ruff? I've noticed some discrepancies between the tools I've employed before and ruff's default behavior. I'm unsure whether it's due to settings adjustments or if I can fully replace these tools with ruff.

If it's plausible to discard other tools and solely rely on ruff, it'd be incredibly advantageous. In my experience, linting large codebases could take up to ~1 minute, whereas ruff operates significantly faster by several orders of magnitude.

I'm eager to explore ruff further and streamline my workflow. Any insights or guidance on optimizing this transition would be immensely appreciated. Thanks in advance for your help!

Best regards,


I should be opening another thread for this one but let me put you a very fast example, consider this snippet

from typing import Iterable

from typing import Iterable

from typing import Iterable

from typing import Iterable

from typing import Iterable



x = [
    1,
    2,
]


def sum_even_numbers(numbers: Iterable[int]) -> int:
    x = 10
    try:
        pass
    except Exception:
        pass

    """Given an iterable of integers, return the sum of all even numbers in the iterable."""
    return sum(num for num in numbers if num % 2 == 0)

when using ruff's default settings I'll get

ruff check --fix numbers2.py && ruff format numbers2.py
numbers2.py:3:20: F811 Redefinition of unused `Iterable` from line 1
numbers2.py:5:20: F811 Redefinition of unused `Iterable` from line 3
numbers2.py:7:20: F811 Redefinition of unused `Iterable` from line 5
numbers2.py:9:20: F811 Redefinition of unused `Iterable` from line 7
numbers2.py:20:5: F841 Local variable `x` is assigned to but never used
Found 5 errors.
No fixes available (1 hidden fix can be enabled with the `--unsafe-fixes` option).

and the output is still bad but when using the other combo of tools you'd get a cleaner output such as:

from typing import Iterable

x = [
    1,
    2,
]


def sum_even_numbers(numbers: Iterable[int]) -> int:
    x = 10
    try:
        pass
    except Exception:
        pass

    """Given an iterable of integers, return the sum of all even numbers in the iterable."""
    return sum(num for num in numbers if num % 2 == 0)

I guess the magic comes from autoflake?

=====================================d:\software\python\3.12.1-amd64\Scripts\isort======================================
d:\software\python\3.12.1-amd64\Scripts\isort -q -rc -sp D:\data\linters\.isort.cfg D:\sources\numbers2.py
===================================d:\software\python\3.12.1-amd64\Scripts\autoflake====================================
d:\software\python\3.12.1-amd64\Scripts\autoflake --remove-all-unused-imports --ignore-init-module-imports --in-place D:\sources\numbers2.py
=====================================d:\software\python\3.12.1-amd64\Scripts\black======================================
d:\software\python\3.12.1-amd64\Scripts\black --config D:\data\linters\.black D:\sources\numbers2.py
All done! \u2728 \U0001f370 \u2728
1 file left unchanged.
=====================================d:\software\python\3.12.1-amd64\Scripts\flake8=====================================
d:\software\python\3.12.1-amd64\Scripts\flake8 --config=D:\data\linters\.flake8 D:\sources\numbers2.py
D:\sources\numbers2.py:10:5: F841 local variable 'x' is assigned to but never used

Anyway, I'll check the docs... 😁

@brupelo
Copy link
Author

brupelo commented Jan 7, 2024

Forget about my last question... it seems there are several threads addressing that one... #1647 , I just need to find out how to enable it 😉 ... cool stuff!

@brupelo
Copy link
Author

brupelo commented Jan 7, 2024

Mmm, actually, I can see the whole list living here https://docs.astral.sh/ruff/rules/

and the one listed in my previous example was F811

image

i don't see the fix icon on that row... I guess that means there is no way to fix that particular one, right?

@charliermarsh
Copy link
Member

That's correct, we don't auto-fix redefined-while-unused. (We probably could in some cases.)

@charliermarsh
Copy link
Member

I added a fix for redefined-while-unused in #9419.

@brupelo
Copy link
Author

brupelo commented Jan 7, 2024

@charliermarsh I'm truly amazed by the speed and responsiveness in this repository. It's incredibly engaging and motivates me to seriously consider using this tool and contributing, even if it's by reporting bugs and providing feedback.

Before closing this conversation, I have a couple of queries:

Does your project have a Discord community?
How challenging is it to compile ruff on Windows 10? I'm keen to try out various PRs such as #9419 without waiting for official releases from master. For instance, I'd like to generate snapshots locally, similar to https://github.com/astral-sh/ruff/releases/download/v0.1.11/ruff-0.1.11-x86_64-pc-windows-msvc.zip.

Thank you for your time and for maintaining such an exciting project. Looking forward to see how it evolves!

Best regards,

@brupelo
Copy link
Author

brupelo commented Jan 7, 2024

@charliermarsh I've been thrilled by how straightforward it was to perform both debug and release builds of Ruff (in master) —merely took around 5 minutes for the release build without encountering any errors. Impressive!

However, I'm now curious about the process for creating distinct packages or snapshots to test various branches in isolation. I have a few specific queries regarding this:

When switching branches, is there a need to clean anything beforehand to ensure a clean build?
Are there specific targets I should focus on to expedite testing, or is using cargo build --release sufficient?
I've noticed multiple executables and DLLs in the release folder. Could you guide me on how to generate the final snapshot to discern the relevant content?
Your insights into these aspects would be greatly appreciated. I'm eager to explore and test different branches effectively.

Thank you for your assistance and guidance.

@charliermarsh
Copy link
Member

Thanks for all the enthusiasm! Yeah, we have a Discord here: https://discord.gg/c9MhzV8aU5. I suggest joining as it's a better medium for this kind of back-and-forth -- we try to keep the issue tracker focused on specific, actionable issues.

When switching branches, is there a need to clean anything beforehand to ensure a clean build?

No, there shouldn't be anything you need to clean.

Are there specific targets I should focus on to expedite testing, or is using cargo build --release sufficient?

cargo build --release is fine, as is cargo run -p ruff_cli -- check /path/to/file.py to test debug builds iteratively (much faster than testing release builds).

I've noticed multiple executables and DLLs in the release folder. Could you guide me on how to generate the final snapshot to discern the relevant content?

I'm not 100% sure here -- I develop on macOS and just use ./target/release/ruff.

@charliermarsh
Copy link
Member

(I'm gonna close this specific issue for now but happy to answer questions here or in Discord!)

@brupelo
Copy link
Author

brupelo commented Jan 8, 2024

@charliermarsh I wanted to extend my gratitude for the tremendous help and responsiveness provided! In my humble opinion, this aspect plays a pivotal role in garnering more traction for a GitHub project and attracting new contributors. I'll continue testing further and will be opening new issues progressively. Eventually, I plan on joining Discord once I've become more acquainted with the project.

Upon my initial interaction, I'm truly impressed by how you guys have effectively addressed a long-standing issue within the Python community regarding Quality Assurance (QA). For years, the proliferation of diverse, slow tools scattered all over the place made it nearly impossible to establish uniform code practices within PyPI. However, your creation of a singular, swift open-source tool that consolidates all existing linting rules into a single cohesive platform is remarkable. This initiative empowers users to adhere to the philosophy of "There should be one-- and preferably only one --obvious way to do it." It's a significant step forward in fostering a unified coding standard in the python community.

Once again, thank you immensely for your efforts in streamlining and enhancing the Python development landscape. I'm eager to continue exploring and contributing to this invaluable project.

Looking forward to how ruff will evolve, keep it going! 😉

@brupelo
Copy link
Author

brupelo commented Dec 14, 2024

@charliermarsh Hey Charlie, how you doing? Sorry to bring this up again, but I recently joined the Astral Discord and wasn’t sure if opening a post there was the right place... so I’ll follow up here again.

I’ve decided to go back to using ruff and uv and am trying to get adoption within my organization, although things move slowly. I also checked Python forums to see if uv will become the de facto standard, but I’m still not clear on that (though that’s a topic for another time).

Anyway, right now, I’m using Justfile to spin up ruff from any part of my codebase. Since just will recursively find the Justfile from anywhere, I have something like this:

Justfile:

lint:
    ruff check --fix
    ruff format

And I use this binding in my editor:

{
    "name": "just lint",
    "shell_cmd": "just lint",
    "file_regex": "^(.*?):([0-9]+):",
    "quiet": false
}

The issue is that since ruff doesn’t write absolute paths as you've explained before (unless writing to json, which is not what I want to inspect & fix issues manually on the output console, I can’t capture the file/line properly for navigating directly to errors in my editor.

Any ideas or suggestions on how to fix this?

Thanks in advance!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
question Asking for support or clarification
Projects
None yet
Development

No branches or pull requests

2 participants