Isort: skip statements

Created on 7 Aug 2015  路  23Comments  路  Source: PyCQA/isort

Some statements need to be nested within imports, is there a way for isort to ignore them?

Here's the motivating example:

import matplotlib
matplotlib.use('Agg')  # isort:skip
import matplotlib.pyplot as plt

the use Agg must be called before the plt import. isort:skip doesn't work here.

enhancement

Most helpful comment

Hi @timothycrosley can you point to some examples showing how will this work? Thanks

All 23 comments

I'm not sure how this would be implemented though as isort would not be aware of the proper ordering unless it's specified somehow.

hi @simonzack,

Thanks for submitting this issue! I think this is one people run into a lot and don't report, I certainly run into it myself, so it's great to have it documented. After putting some thought into it, I think one potential solution would be to add a list of 'stop_patterns' that when contained in a line isort stops looking for imports. This isn't ideal, but would let you group all your normal imports together (and automatically be sorted) and have all your magic imports below, manually sorted. Ideally, the imports that really on magic such as matlib use, and sys.path.append, would generally be minimal.

What do you think of this idea?

Thanks again!

~Timothy

:+1: for this as well, got the same problem with matplotlib.

Would this work?

import logging

# isort:maintain_block
import matplotlib
matplotlib.use('Agg')  
# isort:end_maintain_block

import matplotlib.pyplot as plt

Meaning that isort can shuffle above and below the maintain_block, but not over it?

@timothycrosley Sorry about the late reply, I've forgot about this issue :( That's an interesting idea but it wouldn't sort the imports below the block. The following still looks nicer:

import logging
import matplotlib
matplotlib.use('Agg')
import yaml

from yaml import load

than this:

import logging
import yaml

from yaml import load

import matplotlib
matplotlib.use('Agg')

I think @tino 's solution can fix this, although isort could also treat the block as a single item to sort, so in this case it still uses the line import matplotlib.

Perhaps it could also be done inline:

import logging
import matplotlib  # isort:block
matplotlib.use('Agg')  # isort:end_block
import matplotlib.pyplot as plt

I think for starters it would be good if isort:skip would be kept with the line above.

My use case is with django-configurations, which has this pattern:

 from configurations import importer
 importer.install()  # noqa  # isort:skip

Hmm, that might actually be a simple starting point indeed. I think it would have to work with multiple lines as well though, as these three need to be in this order (now that would work because of the default sorting, but that might not always be the case):

import matplotlib 
matplotlib.use('Agg')  # noqa  # isort:skip
import matplotlib.pyplot as plt  # isort:skip

I think this block would also be covered by "stick lines with isort:skip to the one above".

Only import matplotlib would then be sorted, with the other lines below as-is.

I just wanted to provide another common use case. Gtk will output warning if no specific minimal version is specified:

import gi
gi.require_version('Gdk', '3.0')  # NOQA
gi.require_version('Gtk', '3.0')  # NOQA
from gi.repository import Gdk, Gtk

Is there by any change news on this? Or a viable workaround?

One way or the other: thanks for all your work! :)

Thought I would share a viable workaround for isort and flake8:

import gi  # isort:skip
gi.require_version('PangoCairo', '1.0')  # NOQA: E402

# isort:imports-thirdparty
from gi.repository import PangoCairo

# isort:imports-firstparty
from my.module import MyClass

#isort:import-localfolder
from .common import util

This vim plugin prevents this situation by avoiding moving imports from the original placement: https://github.com/tweekmonster/impsort.vim

Can something like that be implemented? Are there any plans to work on this (i.e since the original issue has over 3 years now). Thanks!!

Hi @jdufresne I've noticed that you've making several changes to the library recently... any plans to tackle this issue? Thanks!

I thought this was implemented with #679 but PR #843 says

Expected behavior is now that all isort:skip and NOQA imports will be moved to bottom, unsorted.

:(

Edit: There are a few other bugs which make me think the skip code probably needs an overhaul
:

  1. #455
  2. noqa needs to be in CAPS or else it won't be detected
  3. another weird bug when constants are mixed in
#!/usr/bin/python

"""Docstring."""

import os

import requests

constant = 5

import zed  # isort:skip
import ujson  # isort:skip

turns into

#!/usr/bin/python

import ujson  # isort:skip
import zed  # isort:skip
"""Docstring."""

import os

import requests

constant = 5

with version 4.3.21.

closing as the latest development branch (which will be release 5.0.0) includes extensive support for skipping statements as well as simply turning isort on and off over sections of code as needed.

Hi @timothycrosley can you point to some examples showing how will this work? Thanks

@timothycrosley Hi, I was wondering if it were possible to skip rearrangement of certain blocks but still
rearrange within the block as someone in this thread has already mentioned?

eg: current behaviour:

import b

import c
import a

becomes

import a
import b
import c

Where a grouping comment would come in handy a work:

import b

# isort:block
import c
import a
# isort:block

becomes

import b

# isort:block
import a
import c
# isort: block

@timothycrosley when will this version be released?

Can we re-open this? It seems the latest released version does not allow you to skip a code statement and and version 5.0.0 is not released yet.

I'm running version 4.3.21 and it always wants to move the import marked as isort:skip to the end of all imports, instead of leaving it alone in place. Seems to be a related issue.

@duanyutong one could interpret that as sort moving the imports after your skips to before.

@duanyutong one could interpret that as sort moving the imports after your skips to before.

Yes, either way, the same end result produced, not leaving skipped imports in place.

For anyone running isort < version 5, this works for me:

import matplotlib  # isort:skip

matplotlib.use("agg")  # noqa: E402
import matplotlib.pyplot as plt  # isort:skip

python --version

Python 3.7.0

isort --version

VERSION 4.3.21

flake8 --version

3.7.8 (mccabe: 0.6.1, pycodestyle: 2.5.0, pyflakes: 2.1.1) CPython 3.7.0 on Darwin

Was this page helpful?
0 / 5 - 0 ratings

Related issues

and-semakin picture and-semakin  路  3Comments

johnthagen picture johnthagen  路  3Comments

pawamoy picture pawamoy  路  3Comments

jedie picture jedie  路  3Comments

pradyunsg picture pradyunsg  路  3Comments