black auto format and sort imports

This commit is contained in:
c-w-m 2023-01-12 09:50:00 -07:00
parent e0830d44a5
commit ffc2c11d99
6 changed files with 214 additions and 192 deletions

View File

@ -38,28 +38,29 @@ Options:
<gt> | e.g. Flask>=1.1.2 <gt> | e.g. Flask>=1.1.2
<no-pin> | e.g. Flask <no-pin> | e.g. Flask
""" """
from contextlib import contextmanager
import os
import sys
import re
import logging
import ast import ast
import logging
import os
import re
import sys
import traceback import traceback
from docopt import docopt from contextlib import contextmanager
import requests import requests
from docopt import docopt
from yarg import json2package from yarg import json2package
from yarg.exceptions import HTTPError from yarg.exceptions import HTTPError
from pipreqs import __version__ from pipreqs import __version__
REGEXP = [ REGEXP = [
re.compile(r'^import (.+)$'), re.compile(r"^import (.+)$"),
re.compile(r'^from ((?!\.+).*?) import (?:.*)$') re.compile(r"^from ((?!\.+).*?) import (?:.*)$"),
] ]
@contextmanager @contextmanager
def _open(filename=None, mode='r'): def _open(filename=None, mode="r"):
"""Open a file or ``sys.stdout`` depending on the provided filename. """Open a file or ``sys.stdout`` depending on the provided filename.
Args: Args:
@ -72,13 +73,13 @@ def _open(filename=None, mode='r'):
A file handle. A file handle.
""" """
if not filename or filename == '-': if not filename or filename == "-":
if not mode or 'r' in mode: if not mode or "r" in mode:
file = sys.stdin file = sys.stdin
elif 'w' in mode: elif "w" in mode:
file = sys.stdout file = sys.stdout
else: else:
raise ValueError('Invalid mode for file: {}'.format(mode)) raise ValueError("Invalid mode for file: {}".format(mode))
else: else:
file = open(filename, mode) file = open(filename, mode)
@ -90,7 +91,8 @@ def _open(filename=None, mode='r'):
def get_all_imports( def get_all_imports(
path, encoding=None, extra_ignore_dirs=None, follow_links=True): path, encoding=None, extra_ignore_dirs=None, follow_links=True
):
imports = set() imports = set()
raw_imports = set() raw_imports = set()
candidates = [] candidates = []
@ -139,11 +141,11 @@ def get_all_imports(
# Cleanup: We only want to first part of the import. # Cleanup: We only want to first part of the import.
# Ex: from django.conf --> django.conf. But we only want django # Ex: from django.conf --> django.conf. But we only want django
# as an import. # as an import.
cleaned_name, _, _ = name.partition('.') cleaned_name, _, _ = name.partition(".")
imports.add(cleaned_name) imports.add(cleaned_name)
packages = imports - (set(candidates) & imports) packages = imports - (set(candidates) & imports)
logging.debug('Found packages: {0}'.format(packages)) logging.debug("Found packages: {0}".format(packages))
with open(join("stdlib"), "r") as f: with open(join("stdlib"), "r") as f:
data = {x.strip() for x in f} data = {x.strip() for x in f}
@ -157,42 +159,59 @@ def filter_line(line):
def generate_requirements_file(path, imports, symbol): def generate_requirements_file(path, imports, symbol):
with _open(path, "w") as out_file: with _open(path, "w") as out_file:
logging.debug('Writing {num} requirements: {imports} to {file}'.format( logging.debug(
num=len(imports), "Writing {num} requirements: {imports} to {file}".format(
file=path, num=len(imports),
imports=", ".join([x['name'] for x in imports]) file=path,
)) imports=", ".join([x["name"] for x in imports]),
fmt = '{name}' + symbol + '{version}' )
out_file.write('\n'.join( )
fmt.format(**item) if item['version'] else '{name}'.format(**item) fmt = "{name}" + symbol + "{version}"
for item in imports) + '\n') out_file.write(
"\n".join(
fmt.format(**item)
if item["version"]
else "{name}".format(**item)
for item in imports
)
+ "\n"
)
def output_requirements(imports, symbol): def output_requirements(imports, symbol):
generate_requirements_file('-', imports, symbol) generate_requirements_file("-", imports, symbol)
def get_imports_info( def get_imports_info(
imports, pypi_server="https://pypi.python.org/pypi/", proxy=None, verify=None): imports,
pypi_server="https://pypi.python.org/pypi/",
proxy=None,
verify=None,
):
result = [] result = []
for item in imports: for item in imports:
try: try:
response = requests.get( response = requests.get(
"{0}{1}/json".format(pypi_server, item), proxies=proxy, verify=verify) "{0}{1}/json".format(pypi_server, item),
proxies=proxy,
verify=verify,
)
if response.status_code == 200: if response.status_code == 200:
if hasattr(response.content, 'decode'): if hasattr(response.content, "decode"):
data = json2package(response.content.decode()) data = json2package(response.content.decode())
else: else:
data = json2package(response.content) data = json2package(response.content)
elif response.status_code >= 300: elif response.status_code >= 300:
raise HTTPError(status_code=response.status_code, raise HTTPError(
reason=response.reason) status_code=response.status_code, reason=response.reason
)
except HTTPError: except HTTPError:
logging.debug( logging.debug(
'Package %s does not exist or network problems', item) "Package %s does not exist or network problems", item
)
continue continue
result.append({'name': item, 'version': data.latest_release_id}) result.append({"name": item, "version": data.latest_release_id})
return result return result
@ -212,16 +231,20 @@ def get_locally_installed_packages(encoding=None):
# TODO: What errors do we intend to suppress here? # TODO: What errors do we intend to suppress here?
continue continue
for i_item in package_import: for i_item in package_import:
if ((i_item not in ignore) and if (i_item not in ignore) and (
(package[0] not in ignore)): package[0] not in ignore
):
version = None version = None
if len(package) > 1: if len(package) > 1:
version = package[1].replace( version = (
".dist", "").replace(".egg", "") package[1]
.replace(".dist", "")
.replace(".egg", "")
)
packages[i_item] = { packages[i_item] = {
'version': version, "version": version,
'name': package[0] "name": package[0],
} }
return packages return packages
@ -234,12 +257,7 @@ def get_import_local(imports, encoding=None):
result.append(local[item.lower()]) result.append(local[item.lower()])
# removing duplicates of package/version # removing duplicates of package/version
result_unique = [ result_unique = [dict(t) for t in set([tuple(d.items()) for d in result])]
dict(t)
for t in set([
tuple(d.items()) for d in result
])
]
return result_unique return result_unique
@ -270,7 +288,7 @@ def get_name_without_alias(name):
match = REGEXP[0].match(name.strip()) match = REGEXP[0].match(name.strip())
if match: if match:
name = match.groups(0)[0] name = match.groups(0)[0]
return name.partition(' as ')[0].partition('.')[0].strip() return name.partition(" as ")[0].partition(".")[0].strip()
def join(f): def join(f):
@ -356,7 +374,8 @@ def diff(file_, imports):
logging.info( logging.info(
"The following modules are in {} but do not seem to be imported: " "The following modules are in {} but do not seem to be imported: "
"{}".format(file_, ", ".join(x for x in modules_not_imported))) "{}".format(file_, ", ".join(x for x in modules_not_imported))
)
def clean(file_, imports): def clean(file_, imports):
@ -404,20 +423,22 @@ def dynamic_versioning(scheme, imports):
def init(args): def init(args):
encoding = args.get('--encoding') encoding = args.get("--encoding")
extra_ignore_dirs = args.get('--ignore') extra_ignore_dirs = args.get("--ignore")
follow_links = not args.get('--no-follow-links') follow_links = not args.get("--no-follow-links")
input_path = args['<path>'] input_path = args["<path>"]
if input_path is None: if input_path is None:
input_path = os.path.abspath(os.curdir) input_path = os.path.abspath(os.curdir)
if extra_ignore_dirs: if extra_ignore_dirs:
extra_ignore_dirs = extra_ignore_dirs.split(',') extra_ignore_dirs = extra_ignore_dirs.split(",")
candidates = get_all_imports(input_path, candidates = get_all_imports(
encoding=encoding, input_path,
extra_ignore_dirs=extra_ignore_dirs, encoding=encoding,
follow_links=follow_links) extra_ignore_dirs=extra_ignore_dirs,
follow_links=follow_links,
)
candidates = get_pkg_names(candidates) candidates = get_pkg_names(candidates)
logging.debug("Found imports: " + ", ".join(candidates)) logging.debug("Found imports: " + ", ".join(candidates))
pypi_server = "https://pypi.python.org/pypi/" pypi_server = "https://pypi.python.org/pypi/"
@ -427,30 +448,36 @@ def init(args):
pypi_server = args["--pypi-server"] pypi_server = args["--pypi-server"]
if args["--proxy"]: if args["--proxy"]:
proxy = {'http': args["--proxy"], 'https': args["--proxy"]} proxy = {"http": args["--proxy"], "https": args["--proxy"]}
if args["--verify"]: if args["--verify"]:
verify = args["--verify"] verify = args["--verify"]
if args["--use-local"]: if args["--use-local"]:
logging.debug( logging.debug(
"Getting package information ONLY from local installation.") "Getting package information ONLY from local installation."
)
imports = get_import_local(candidates, encoding=encoding) imports = get_import_local(candidates, encoding=encoding)
else: else:
logging.debug("Getting packages information from Local/PyPI") logging.debug("Getting packages information from Local/PyPI")
local = get_import_local(candidates, encoding=encoding) local = get_import_local(candidates, encoding=encoding)
# Get packages that were not found locally # Get packages that were not found locally
difference = [x for x in candidates difference = [
if x.lower() not in [z['name'].lower() for z in local]] x
imports = local + get_imports_info(difference, for x in candidates
proxy=proxy, if x.lower() not in [z["name"].lower() for z in local]
verify=verify, ]
pypi_server=pypi_server) imports = local + get_imports_info(
difference, proxy=proxy, verify=verify, pypi_server=pypi_server
)
# sort imports based on lowercase name of package, similar to `pip freeze`. # sort imports based on lowercase name of package, similar to `pip freeze`.
imports = sorted(imports, key=lambda x: x['name'].lower()) imports = sorted(imports, key=lambda x: x["name"].lower())
path = (args["--savepath"] if args["--savepath"] else path = (
os.path.join(input_path, "requirements.txt")) args["--savepath"]
if args["--savepath"]
else os.path.join(input_path, "requirements.txt")
)
if args["--diff"]: if args["--diff"]:
diff(args["--diff"], imports) diff(args["--diff"], imports)
@ -460,12 +487,15 @@ def init(args):
clean(args["--clean"], imports) clean(args["--clean"], imports)
return return
if (not args["--print"] if (
and not args["--savepath"] not args["--print"]
and not args["--force"] and not args["--savepath"]
and os.path.exists(path)): and not args["--force"]
logging.warning("requirements.txt already exists, " and os.path.exists(path)
"use --force to overwrite it") ):
logging.warning(
"requirements.txt already exists, " "use --force to overwrite it"
)
return return
if args["--mode"]: if args["--mode"]:
@ -473,8 +503,10 @@ def init(args):
if scheme in ["compat", "gt", "no-pin"]: if scheme in ["compat", "gt", "no-pin"]:
imports, symbol = dynamic_versioning(scheme, imports) imports, symbol = dynamic_versioning(scheme, imports)
else: else:
raise ValueError("Invalid argument for mode flag, " raise ValueError(
"use 'compat', 'gt' or 'no-pin' instead") "Invalid argument for mode flag, "
"use 'compat', 'gt' or 'no-pin' instead"
)
else: else:
symbol = "==" symbol = "=="
@ -488,8 +520,8 @@ def init(args):
def main(): # pragma: no cover def main(): # pragma: no cover
args = docopt(__doc__, version=__version__) args = docopt(__doc__, version=__version__)
log_level = logging.DEBUG if args['--debug'] else logging.INFO log_level = logging.DEBUG if args["--debug"] else logging.INFO
logging.basicConfig(level=log_level, format='%(levelname)s: %(message)s') logging.basicConfig(level=log_level, format="%(levelname)s: %(message)s")
try: try:
init(args) init(args)
@ -497,5 +529,5 @@ def main(): # pragma: no cover
sys.exit(0) sys.exit(0)
if __name__ == '__main__': if __name__ == "__main__":
main() # pragma: no cover main() # pragma: no cover

View File

@ -1,56 +1,51 @@
"""unused import""" """unused import"""
# pylint: disable=undefined-all-variable, import-error, no-absolute-import, too-few-public-methods, missing-docstring # pylint: disable=undefined-all-variable, import-error, no-absolute-import, too-few-public-methods, missing-docstring
from __future__ import print_function
import atexit
import curses
import importlib # html/notebookapp.py
import logging
import os
import os.path as test # [unused-import]
import signal
import sqlite3
import sys
import time
import xml.etree # [unused-import] import xml.etree # [unused-import]
import xml.sax # [unused-import] import xml.sax # [unused-import]
import os.path as test # [unused-import] # astroid
from sys import argv as test2 # [unused-import]
from sys import flags # [unused-import]
# +1:[unused-import,unused-import]
from collections import deque, OrderedDict, Counter
# All imports above should be ignored
import requests # [unused-import]
# setuptools # setuptools
import zipimport # command/easy_install.py import zipimport # manager.py
# +1:[unused-import,unused-import]
from collections import Counter, OrderedDict, deque
# twisted # twisted
from importlib import invalidate_caches # python/test/test_deprecate.py from importlib import invalidate_caches # python/test/test_deprecate.py
# astroid
import zipimport # manager.py
# IPython # IPython
from importlib.machinery import all_suffixes # core/completerlib.py from importlib.machinery import all_suffixes # core/completerlib.py
import importlib # html/notebookapp.py from sys import argv as test2 # [unused-import]
from sys import flags # [unused-import]
from IPython.utils.importstring import import_item # Many files
# pyflakes
# test/test_doctests.py
from pyflakes.test.test_imports import Test as TestImports
# Nose
from nose.importer import Importer, add_path, remove_path # loader.py
# see issue #88 # see issue #88
import analytics import analytics
import flask_seasurf import boto as b
import atexit
from __future__ import print_function
from docopt import docopt
import curses, logging, sqlite3
import logging
import os
import sqlite3
import time
import sys
import signal
import bs4 import bs4
import nonexistendmodule
import boto as b, peewee as p
# import django # import django
import flask.ext.somext # # # import flask.ext.somext # # #
import flask_seasurf
import nonexistendmodule
import peewee as p
# All imports above should be ignored
import requests # [unused-import]
from docopt import docopt
from IPython.utils.importstring import import_item # Many files
# Nose
from nose.importer import Importer, add_path, remove_path # loader.py
# pyflakes
# test/test_doctests.py
from pyflakes.test.test_imports import Test as TestImports
from sqlalchemy import model from sqlalchemy import model
try: try:
import ujson as json import ujson as json
except ImportError: except ImportError:
@ -62,4 +57,5 @@ import models
def main(): def main():
pass pass
import after_method_is_valid_even_if_not_pep8 import after_method_is_valid_even_if_not_pep8

View File

@ -1,55 +1,50 @@
"""unused import""" """unused import"""
# pylint: disable=undefined-all-variable, import-error, no-absolute-import, too-few-public-methods, missing-docstring # pylint: disable=undefined-all-variable, import-error, no-absolute-import, too-few-public-methods, missing-docstring
from __future__ import print_function
import atexit
import curses
import importlib # html/notebookapp.py
import logging
import os
import os.path as test # [unused-import]
import signal
import sqlite3
import sys
import time
import xml.etree # [unused-import] import xml.etree # [unused-import]
import xml.sax # [unused-import] import xml.sax # [unused-import]
import os.path as test # [unused-import] # astroid
from sys import argv as test2 # [unused-import]
from sys import flags # [unused-import]
# +1:[unused-import,unused-import]
from collections import deque, OrderedDict, Counter
# All imports above should be ignored
import requests # [unused-import]
# setuptools # setuptools
import zipimport # command/easy_install.py import zipimport # manager.py
# +1:[unused-import,unused-import]
from collections import Counter, OrderedDict, deque
# twisted # twisted
from importlib import invalidate_caches # python/test/test_deprecate.py from importlib import invalidate_caches # python/test/test_deprecate.py
# astroid
import zipimport # manager.py
# IPython # IPython
from importlib.machinery import all_suffixes # core/completerlib.py from importlib.machinery import all_suffixes # core/completerlib.py
import importlib # html/notebookapp.py from sys import argv as test2 # [unused-import]
from sys import flags # [unused-import]
# see issue #88
import analytics
import boto as b
import bs4
# import django
import flask.ext.somext # # #
import flask_seasurf
import nonexistendmodule
import peewee as p
# All imports above should be ignored
import requests # [unused-import]
from docopt import docopt
from IPython.utils.importstring import import_item # Many files from IPython.utils.importstring import import_item # Many files
# Nose
from nose.importer import Importer, add_path, remove_path # loader.py
# pyflakes # pyflakes
# test/test_doctests.py # test/test_doctests.py
from pyflakes.test.test_imports import Test as TestImports from pyflakes.test.test_imports import Test as TestImports
# Nose
from nose.importer import Importer, add_path, remove_path # loader.py
# see issue #88
import analytics
import flask_seasurf
import atexit
from __future__ import print_function
from docopt import docopt
import curses, logging, sqlite3
import logging
import os
import sqlite3
import time
import sys
import signal
import bs4
import nonexistendmodule
import boto as b, peewee as p
# import django
import flask.ext.somext # # #
# from sqlalchemy import model # from sqlalchemy import model
try: try:
import ujson as json import ujson as json
@ -62,4 +57,5 @@ import models
def main(): def main():
pass pass
import after_method_is_valid_even_if_not_pep8 import after_method_is_valid_even_if_not_pep8

View File

@ -1,52 +1,48 @@
"""unused import""" """unused import"""
# pylint: disable=undefined-all-variable, import-error, no-absolute-import, too-few-public-methods, missing-docstring # pylint: disable=undefined-all-variable, import-error, no-absolute-import, too-few-public-methods, missing-docstring
from __future__ import print_function
import atexit
import curses
import importlib # html/notebookapp.py
import logging
import os
import os.path as test # [unused-import]
import signal
import sqlite3
import sys
import time
import xml.etree # [unused-import] import xml.etree # [unused-import]
import xml.sax # [unused-import] import xml.sax # [unused-import]
import os.path as test # [unused-import] # astroid
from sys import argv as test2 # [unused-import]
from sys import flags # [unused-import]
# +1:[unused-import,unused-import]
from collections import deque, OrderedDict, Counter
# All imports above should be ignored
import requests # [unused-import]
# setuptools # setuptools
import zipimport # command/easy_install.py import zipimport # manager.py
# +1:[unused-import,unused-import]
from collections import Counter, OrderedDict, deque
# twisted # twisted
from importlib import invalidate_caches # python/test/test_deprecate.py from importlib import invalidate_caches # python/test/test_deprecate.py
# astroid
import zipimport # manager.py
# IPython # IPython
from importlib.machinery import all_suffixes # core/completerlib.py from importlib.machinery import all_suffixes # core/completerlib.py
import importlib # html/notebookapp.py from sys import argv as test2 # [unused-import]
from sys import flags # [unused-import]
import boto as b
import bs4
# import django
import flask.ext.somext # # #
import nonexistendmodule
import peewee as p
# All imports above should be ignored
import requests # [unused-import]
from docopt import docopt
from IPython.utils.importstring import import_item # Many files from IPython.utils.importstring import import_item # Many files
# Nose
from nose.importer import Importer, add_path, remove_path # loader.py
# pyflakes # pyflakes
# test/test_doctests.py # test/test_doctests.py
from pyflakes.test.test_imports import Test as TestImports from pyflakes.test.test_imports import Test as TestImports
# Nose
from nose.importer import Importer, add_path, remove_path # loader.py
import atexit
from __future__ import print_function
from docopt import docopt
import curses, logging, sqlite3
import logging
import os
import sqlite3
import time
import sys
import signal
import bs4
import nonexistendmodule
import boto as b, peewee as p
# import django
import flask.ext.somext # # #
from sqlalchemy import model from sqlalchemy import model
try: try:
import ujson as json import ujson as json
except ImportError: except ImportError:
@ -58,4 +54,5 @@ import models
def main(): def main():
pass pass
import after_method_is_valid_even_if_not_pep8 import after_method_is_valid_even_if_not_pep8

View File

@ -8,8 +8,9 @@ test_pipreqs
Tests for `pipreqs` module. Tests for `pipreqs` module.
""" """
import unittest
import os import os
import unittest
import requests import requests
from pipreqs import pipreqs from pipreqs import pipreqs