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

Better grouping of imports #13

Open
quarl opened this issue May 17, 2019 · 8 comments · Fixed by #263
Open

Better grouping of imports #13

quarl opened this issue May 17, 2019 · 8 comments · Fixed by #263
Assignees
Labels
Harder Issue will require a lot of work to fix High Priority

Comments

@quarl
Copy link
Member

quarl commented May 17, 2019

pyflyby makes imports nice when adding to an existing import line. E.g. if "from m1 import x" exists, and "from m1 import y" needs to be added, then it merges it into "from m1 import x, y".
Pyflyby also sorts import line within one "block".
Currently it considers a blank line to separate import blocks and doesn't merge such blocks.

However, code that's carelessly maintained tends to drift into states like this:

import numpy

from pkg1.mod1 import foo
from pkg1.mod2 import bar
from pkg2 import baz
import yy

from pkg1.mod1 import foo2
from pkg1.mod3 import quux
from pkg2 import baar
import sympy
import zz

We should change the algorithm to automatically beautify this. Pyflyby has already trained people to ignore whatever's in the import stanza. So pyflyby should take greater ownership of it.

Proposal1.

  • input blank lines don't separate blocks (but comments still do)
  • when outputting import lines, group them like this:
    • consider imports from the same package to be one group (e.g. "import pkg1.blah", "from pkg1 import x", "from pkg1.mod1 import x")
    • output all the imports in lexicographic order, with a blank line between groups that have more than 1 import statement. So pkg1 gets special treatment but pkg2 doesn't.

We would get:

import numpy
import sympy

from pkg1.mod1 import foo, foo2
from pkg1.mod2 import bar
from pkg1.mod3 import quux

from pkg2 import baz, baar
import yy
import zz

Proposal2.
Some people like to have pkg1 show up after all the other imports, because they work in pkg1, or have stdlib imports show up before all the other imports.

Add support for something like this:

In ~/.pyflyby/*.py:
__import_sections__ = [ ['os','sys'], '*', 'pkg1']

These proposals are not mutual exclusive.

Proposal1 is higher priority than Proposal2.

@quarl quarl added this to the M2 milestone Aug 15, 2019
@asmeurer asmeurer added the Harder Issue will require a lot of work to fix label Jan 13, 2020
@Carreau Carreau self-assigned this Nov 9, 2022
@asmeurer
Copy link
Collaborator

@asmeurer
Copy link
Collaborator

asmeurer commented Jan 31, 2023

isort has a lot of customization (see https://pycqa.github.io/isort/docs/configuration/custom_sections_and_ordering.html and https://github.com/PyCQA/isort/blob/main/isort/settings.py#L137). The more customization we would want to adopt, the more work this will be. One must also consider that we'd have to convert the isort functions to use the pyflyby internal classes representing imports and other Python code constructs. [time estimate: 50 hrs]

@asmeurer asmeurer added the approval required This issue must be approved before work can begin label Feb 9, 2023
@peytondmurray peytondmurray assigned asmeurer and unassigned Carreau Feb 15, 2023
@quarl
Copy link
Member Author

quarl commented Feb 16, 2023

Sounds good to proceed (sorry I missed that this was waiting for feedback)

@peytondmurray peytondmurray removed the approval required This issue must be approved before work can begin label Feb 21, 2023
Carreau added a commit to Carreau/pyflyby that referenced this issue Jan 30, 2024
This add some test for what was requested in deshaw#13 and implemented in deshaw#263
@Carreau Carreau reopened this Mar 4, 2024
@Carreau
Copy link
Collaborator

Carreau commented Mar 4, 2024

A couple of notes following #287 as there was some issues with isort.:

  • input blank lines don't separate blocks (but comments still do)

I'm not sure this will work in practice, as from the top example shows:

input


import numpy

from pkg1.mod1 import foo
from pkg1.mod2 import bar
from pkg2 import baz
import yy

from pkg1.mod1 import foo2
from pkg1.mod3 import quux
from pkg2 import baar
import sympy
import zz

Output:

import numpy
import sympy

from pkg1.mod1 import foo, foo2
from pkg1.mod2 import bar
from pkg1.mod3 import quux

from pkg2 import baz, baar
import yy
import zz

The developer means to have (numpy, scipy) in it's own group.

If we do follow the logic proposed, then the output lexicographically ordered will be the following with "sympy" relagated into simple imports at the bottom.

import numpy

from pkg1.mod1 import foo, foo2
from pkg1.mod2 import bar
from pkg1.mod3 import quux

from pkg2 import baz, baar
import sympy
import yy
import zz

There are also questions with respect to comments, do the comments separate two grouping import, or do they mark a single block. That is to say:

import A
import D
import G

# comment
import B
import F
import J

import C
import E
import Z

Should we

  • [ ] merge ADG, and CEZ (see below this is impossible)
  • merge BFJ and CEZ

I'm inclined to go with the second and assume the second group of blank lines is a group separation in most case.

@Carreau
Copy link
Collaborator

Carreau commented Mar 12, 2024

So from reflexion and trying we can't merge ADG, and CEZ, reason being we need the sorting process and insertion of blank lines to be stable.

So a blocks like

# comment
import B
import B.A
import B.B
import F.A
import F.B
import J

Will after reformat have blanks lines due to the ..., with a blank line between groups that have more than 1 import statement.... requirements, becoming


# comment
import B
import B.A
import B.B

import F.A
import F.B

import J

Thus we need the comment to apply to multiple blocks with blank lines.

@Carreau
Copy link
Collaborator

Carreau commented Apr 8, 2024

I'm guessing there might be a need to special case from __future__ imports, those are usually always followed by a new line shouldn't they ?

Carreau added a commit to Carreau/pyflyby that referenced this issue Apr 8, 2024
This tries to implement some of the rule of import sorting as requested
in deshaw#13 using custom logic, This was originally fixed in deshaw#263 using isort,
but reverted and  re-requested as of deshaw#287
Carreau added a commit to Carreau/pyflyby that referenced this issue Apr 9, 2024
This tries to implement some of the rule of import sorting as requested
in deshaw#13 using custom logic, This was originally fixed in deshaw#263 using isort,
but reverted and  re-requested as of deshaw#287
Carreau added a commit to Carreau/pyflyby that referenced this issue Apr 16, 2024
This tries to implement some of the rule of import sorting as requested
in deshaw#13 using custom logic, This was originally fixed in deshaw#263 using isort,
but reverted and  re-requested as of deshaw#287
Carreau added a commit to Carreau/pyflyby that referenced this issue May 7, 2024
This tries to implement some of the rule of import sorting as requested
in deshaw#13 using custom logic, This was originally fixed in deshaw#263 using isort,
but reverted and  re-requested as of deshaw#287
Carreau added a commit to Carreau/pyflyby that referenced this issue May 7, 2024
This tries to implement some of the rule of import sorting as requested
in deshaw#13 using custom logic, This was originally fixed in deshaw#263 using isort,
but reverted and  re-requested as of deshaw#287
@sac111gp
Copy link
Collaborator

sac111gp commented Sep 3, 2024

I'm guessing there might be a need to special case from future imports, those are usually always followed by a new line shouldn't they ?

yes.

Any further update on this PR?

@Carreau Carreau assigned Carreau and unassigned aktech Sep 19, 2024
@Carreau
Copy link
Collaborator

Carreau commented Sep 19, 2024

#329 added the --experimental-sort-imports and should have been released.

I don't remember if it it unconditionally adds blank lines after future but will check.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Harder Issue will require a lot of work to fix High Priority
Projects
None yet
Development

Successfully merging a pull request may close this issue.

6 participants