From c83d7154c6f33ced068568f4f9983771d231a489 Mon Sep 17 00:00:00 2001 From: craigmiller Date: Sun, 15 Jan 2023 00:23:09 -0700 Subject: [PATCH] sync with master --- .gitignore | 8 + .vscode/extensions.json | 2 - .vscode/settings.json | 26 +-- CONTRIBUTING.rst | 7 +- README.rst | 4 + pipreqs/pipreqs.py | 176 ++++++++----------- requirements-dev.txt | 34 +++- requirements.txt | 3 +- setup.py | 5 +- tests/_data/test.py | 76 ++++---- tests/_data_clean/test.py | 74 ++++---- tests/_data_ignore/.ignore_second/ignored.py | 2 +- tests/_data_ignore/test.py | 69 ++++---- tests/settings.py | 12 ++ tests/test_pipreqs.py | 134 ++++++-------- 15 files changed, 325 insertions(+), 307 deletions(-) diff --git a/.gitignore b/.gitignore index 45a067a..f05ae8c 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,11 @@ +# fix_SSLError ----- +.env38/ +.vscode/ +pipreqs_flake8_results.txt +pipreqs_setup_test_results.txt +pipreqs_tox_results.txt +# ------------------ + *.py[cod] # C extensions diff --git a/.vscode/extensions.json b/.vscode/extensions.json index f5c874b..f813aaf 100644 --- a/.vscode/extensions.json +++ b/.vscode/extensions.json @@ -45,8 +45,6 @@ "ms-vscode.test-adapter-converter", // - Test Explorer UI "hbenl.vscode-test-explorer", - // - python-tox - "the-compiler.python-tox", // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Rust diff --git a/.vscode/settings.json b/.vscode/settings.json index b1f764a..ef5369f 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,25 +1,25 @@ { "workbench.colorCustomizations": { - "activityBar.activeBackground": "#990000", - "activityBar.background": "#990000", - "activityBar.foreground": "#e7e7e7", - "activityBar.inactiveForeground": "#e7e7e799", - "activityBarBadge.background": "#000000", - "activityBarBadge.foreground": "#e7e7e7", + "activityBar.activeBackground": "#5d98cd", + "activityBar.background": "#5d98cd", + "activityBar.foreground": "#15202b", + "activityBar.inactiveForeground": "#15202b99", + "activityBarBadge.background": "#f0cee0", + "activityBarBadge.foreground": "#15202b", "commandCenter.border": "#e7e7e799", - "sash.hoverBorder": "#990000", - "statusBar.background": "#660000", + "sash.hoverBorder": "#5d98cd", + "statusBar.background": "#3a7fbd", "statusBar.foreground": "#e7e7e7", - "statusBarItem.hoverBackground": "#990000", - "statusBarItem.remoteBackground": "#660000", + "statusBarItem.hoverBackground": "#5d98cd", + "statusBarItem.remoteBackground": "#3a7fbd", "statusBarItem.remoteForeground": "#e7e7e7", - "titleBar.activeBackground": "#660000", + "titleBar.activeBackground": "#3a7fbd", "titleBar.activeForeground": "#e7e7e7", - "titleBar.inactiveBackground": "#66000099", + "titleBar.inactiveBackground": "#3a7fbd99", "titleBar.inactiveForeground": "#e7e7e799" }, "python.testing.unittestArgs": ["-v", "-s", "./tests", "-p", "test_*.py"], "python.testing.pytestEnabled": false, "python.testing.unittestEnabled": true, - "peacock.color": "#660000" + "peacock.color": "#3a7fbd" } diff --git a/CONTRIBUTING.rst b/CONTRIBUTING.rst index 60fcb82..3229623 100644 --- a/CONTRIBUTING.rst +++ b/CONTRIBUTING.rst @@ -77,11 +77,16 @@ Ready to contribute? Here's how to set up `pipreqs` for local development. 5. When you're done making changes, check that your changes pass flake8 and the tests, including testing other Python versions with tox:: $ flake8 pipreqs tests - $ python setup.py test + $ python setup.py test > pipreqs_setup_test_result.txt $ tox To get flake8 and tox, just pip install them into your virtualenv. (or $pip install -r requirements-dev.txt) + You may also need to provide `CA_BUNDLE` as an environment variable or parameter in the `tests/.env.test` file. + + $ export CA_BUNDLE="/certs/path/certificates.pem" # for nix OS + $ set CA_BUNDLE="C:/certs/path/certificates.pem" # for win OS + 6. Commit your changes and push your branch to GitHub:: $ git add . diff --git a/README.rst b/README.rst index fe5c87a..e1d1931 100644 --- a/README.rst +++ b/README.rst @@ -46,6 +46,10 @@ Usage $ export HTTPS_PROXY="https://10.10.1.10:1080" --verify Use verify to provide a CA_BUNDLE file or directory with certificates of trusted CAs + You can also just set the environment variable in + your terminal: (`export` for nix and `set` for win) + $ export CA_BUNDLE="/certs/path/certificates.pem" + $ set CA_BUNDLE="C:/certs/path/certificates.pem" --debug Print debug information --ignore ... Ignore extra directories, each separated by a comma --no-follow-links Do not follow symbolic links in the project diff --git a/pipreqs/pipreqs.py b/pipreqs/pipreqs.py index 2bbb552..285a523 100644 --- a/pipreqs/pipreqs.py +++ b/pipreqs/pipreqs.py @@ -20,6 +20,10 @@ Options: $ export HTTPS_PROXY="https://10.10.1.10:1080" --verify Use verify to provide a CA_BUNDLE file or directory with certificates of trusted CAs + You can also just set the environment variable in + your terminal: (`export` for nix and `set` for win) + $ export CA_BUNDLE="/certs/path/certificates.pem" #or + $ set CA_BUNDLE="C:/certs/path/certificates.pem" --debug Print debug information --ignore ... Ignore extra directories, each separated by a comma --no-follow-links Do not follow symbolic links in the project @@ -54,13 +58,14 @@ from yarg.exceptions import HTTPError from pipreqs import __version__ REGEXP = [ - re.compile(r"^import (.+)$"), - re.compile(r"^from ((?!\.+).*?) import (?:.*)$"), + re.compile(r'^import (.+)$'), + re.compile(r'^from ((?!\.+).*?) import (?:.*)$') ] +CA_BUNDLE = os.environ.get("CA_BUNDLE") @contextmanager -def _open(filename=None, mode="r"): +def _open(filename=None, mode='r'): """Open a file or ``sys.stdout`` depending on the provided filename. Args: @@ -73,13 +78,13 @@ def _open(filename=None, mode="r"): A file handle. """ - if not filename or filename == "-": - if not mode or "r" in mode: + if not filename or filename == '-': + if not mode or 'r' in mode: file = sys.stdin - elif "w" in mode: + elif 'w' in mode: file = sys.stdout else: - raise ValueError("Invalid mode for file: {}".format(mode)) + raise ValueError('Invalid mode for file: {}'.format(mode)) else: file = open(filename, mode) @@ -91,8 +96,7 @@ def _open(filename=None, mode="r"): 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() raw_imports = set() candidates = [] @@ -141,11 +145,11 @@ def get_all_imports( # Cleanup: We only want to first part of the import. # Ex: from django.conf --> django.conf. But we only want django # as an import. - cleaned_name, _, _ = name.partition(".") + cleaned_name, _, _ = name.partition('.') imports.add(cleaned_name) 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: data = {x.strip() for x in f} @@ -159,34 +163,26 @@ def filter_line(line): def generate_requirements_file(path, imports, symbol): with _open(path, "w") as out_file: - logging.debug( - "Writing {num} requirements: {imports} to {file}".format( - num=len(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) - for item in imports - ) - + "\n" - ) + logging.debug('Writing {num} requirements: {imports} to {file}'.format( + num=len(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) + for item in imports) + '\n') def output_requirements(imports, symbol): - generate_requirements_file("-", imports, symbol) + generate_requirements_file('-', imports, symbol) def get_imports_info( imports, pypi_server="https://pypi.python.org/pypi/", proxy=None, - verify=None, + verify=CA_BUNDLE, c=None, ): result = [] @@ -199,20 +195,18 @@ def get_imports_info( verify=verify, ) if response.status_code == 200: - if hasattr(response.content, "decode"): + if hasattr(response.content, 'decode'): data = json2package(response.content.decode()) else: data = json2package(response.content) elif response.status_code >= 300: - raise HTTPError( - status_code=response.status_code, reason=response.reason - ) + raise HTTPError(status_code=response.status_code, + reason=response.reason) except HTTPError: logging.debug( - "Package %s does not exist or network problems", item - ) + 'Package %s does not exist or network problems', item) continue - result.append({"name": item, "version": data.latest_release_id}) + result.append({'name': item, 'version': data.latest_release_id}) return result @@ -232,20 +226,16 @@ def get_locally_installed_packages(encoding=None): # TODO: What errors do we intend to suppress here? continue for i_item in package_import: - if (i_item not in ignore) and ( - package[0] not in ignore - ): + if ((i_item not in ignore) and + (package[0] not in ignore)): version = None if len(package) > 1: - version = ( - package[1] - .replace(".dist", "") - .replace(".egg", "") - ) + version = package[1].replace( + ".dist", "").replace(".egg", "") packages[i_item] = { - "version": version, - "name": package[0], + 'version': version, + 'name': package[0] } return packages @@ -258,7 +248,12 @@ def get_import_local(imports, encoding=None): result.append(local[item.lower()]) # removing duplicates of package/version - result_unique = [dict(t) for t in set([tuple(d.items()) for d in result])] + result_unique = [ + dict(t) + for t in set([ + tuple(d.items()) for d in result + ]) + ] return result_unique @@ -289,7 +284,7 @@ def get_name_without_alias(name): match = REGEXP[0].match(name.strip()) if match: name = match.groups(0)[0] - return name.partition(" as ")[0].partition(".")[0].strip() + return name.partition(' as ')[0].partition('.')[0].strip() def join(f): @@ -375,8 +370,7 @@ def diff(file_, imports): logging.info( "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): @@ -424,22 +418,30 @@ def dynamic_versioning(scheme, imports): def init(args): - encoding = args.get("--encoding") - extra_ignore_dirs = args.get("--ignore") - follow_links = not args.get("--no-follow-links") - input_path = args[""] + encoding = args.get('--encoding') + extra_ignore_dirs = args.get('--ignore') + follow_links = not args.get('--no-follow-links') + input_path = args[''] if input_path is None: input_path = os.path.abspath(os.curdir) if extra_ignore_dirs: - extra_ignore_dirs = extra_ignore_dirs.split(",") + extra_ignore_dirs = extra_ignore_dirs.split(',') - candidates = get_all_imports( - input_path, - encoding=encoding, - extra_ignore_dirs=extra_ignore_dirs, - follow_links=follow_links, - ) + path = (args["--savepath"] if args["--savepath"] else + os.path.join(input_path, "requirements.txt")) + if (not args["--print"] + and not args["--savepath"] + and not args["--force"] + and os.path.exists(path)): + logging.warning("requirements.txt already exists, " + "use --force to overwrite it") + return + + candidates = get_all_imports(input_path, + encoding=encoding, + extra_ignore_dirs=extra_ignore_dirs, + follow_links=follow_links) candidates = get_pkg_names(candidates) logging.debug("Found imports: " + ", ".join(candidates)) pypi_server = "https://pypi.python.org/pypi/" @@ -449,36 +451,27 @@ def init(args): pypi_server = args["--pypi-server"] if args["--proxy"]: - proxy = {"http": args["--proxy"], "https": args["--proxy"]} + proxy = {'http': args["--proxy"], 'https': args["--proxy"]} if args["--verify"]: verify = args["--verify"] if args["--use-local"]: logging.debug( - "Getting package information ONLY from local installation." - ) + "Getting package information ONLY from local installation.") imports = get_import_local(candidates, encoding=encoding) else: logging.debug("Getting packages information from Local/PyPI") local = get_import_local(candidates, encoding=encoding) # Get packages that were not found locally - difference = [ - x - for x in candidates - if x.lower() not in [z["name"].lower() for z in local] - ] - imports = local + get_imports_info( - difference, proxy=proxy, verify=verify, pypi_server=pypi_server - ) + difference = [x for x in candidates + if x.lower() not in [z['name'].lower() for z in local]] + 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`. - imports = sorted(imports, key=lambda x: x["name"].lower()) - - path = ( - args["--savepath"] - if args["--savepath"] - else os.path.join(input_path, "requirements.txt") - ) + imports = sorted(imports, key=lambda x: x['name'].lower()) if args["--diff"]: diff(args["--diff"], imports) @@ -488,26 +481,13 @@ def init(args): clean(args["--clean"], imports) return - if ( - not args["--print"] - and not args["--savepath"] - and not args["--force"] - and os.path.exists(path) - ): - logging.warning( - "requirements.txt already exists, " "use --force to overwrite it" - ) - return - if args["--mode"]: scheme = args.get("--mode") if scheme in ["compat", "gt", "no-pin"]: imports, symbol = dynamic_versioning(scheme, imports) else: - raise ValueError( - "Invalid argument for mode flag, " - "use 'compat', 'gt' or 'no-pin' instead" - ) + raise ValueError("Invalid argument for mode flag, " + "use 'compat', 'gt' or 'no-pin' instead") else: symbol = "==" @@ -521,8 +501,8 @@ def init(args): def main(): # pragma: no cover args = docopt(__doc__, version=__version__) - log_level = logging.DEBUG if args["--debug"] else logging.INFO - logging.basicConfig(level=log_level, format="%(levelname)s: %(message)s") + log_level = logging.DEBUG if args['--debug'] else logging.INFO + logging.basicConfig(level=log_level, format='%(levelname)s: %(message)s') try: init(args) @@ -530,5 +510,5 @@ def main(): # pragma: no cover sys.exit(0) -if __name__ == "__main__": +if __name__ == '__main__': main() # pragma: no cover diff --git a/requirements-dev.txt b/requirements-dev.txt index de3d53b..322f7d9 100644 --- a/requirements-dev.txt +++ b/requirements-dev.txt @@ -1,4 +1,32 @@ -black +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +# > python38 -m venv .env38 +# # activate (.env38) virtual environment + +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +# upgrade pip +# (.env38)> python.exe -m pip install --upgrade pip + +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +# development packages +# (.env38)> pip install -r requirements-dev.txt + +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +# development mode installation of `pipreqs` +# (.env38)> pip install -e . + +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +# fix_SSLError tests.settings (optional) use of .env file +# alternative would be to set CA_BUNDLE environment variable +python-dotenv + +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +# required per CONTRIBUTING workflow flake8 -tox -python-dotenv # optional to use .env file instead of environment variables +tox # only needed in the environment from which tox is run + +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +# (optional, personal choice) +# vscode settings: "python.formatting.provider": "black", +#black + +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/requirements.txt b/requirements.txt index 959d1b7..3dc71a1 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,3 +1,4 @@ wheel==0.23.0 Yarg==0.1.9 -docopt==0.6.2 \ No newline at end of file +docopt==0.6.2 +requests==2.28.2 diff --git a/setup.py b/setup.py index 6506d54..f45c23b 100755 --- a/setup.py +++ b/setup.py @@ -7,7 +7,6 @@ except ImportError: from pipreqs import __version__ - with open('README.rst') as readme_file: readme = readme_file.read() @@ -15,10 +14,10 @@ with open('HISTORY.rst') as history_file: history = history_file.read().replace('.. :changelog:', '') requirements = [ - 'docopt', 'yarg' + 'docopt', 'yarg', 'requests' ] tests_requirements = [ - 'python-dotenv' + 'python-dotenv', 'flake8' ] setup( diff --git a/tests/_data/test.py b/tests/_data/test.py index 73c15d2..fdb6ec3 100644 --- a/tests/_data/test.py +++ b/tests/_data/test.py @@ -1,51 +1,56 @@ """unused import""" # 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.sax # [unused-import] -# astroid -# setuptools -import zipimport # manager.py -# +1:[unused-import,unused-import] -from collections import Counter, OrderedDict, deque -# twisted -from importlib import invalidate_caches # python/test/test_deprecate.py -# IPython -from importlib.machinery import all_suffixes # core/completerlib.py +import os.path as test # [unused-import] 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 +# +1:[unused-import,unused-import] +from collections import deque, OrderedDict, Counter # All imports above should be ignored import requests # [unused-import] -from docopt import docopt + +# setuptools +import zipimport # command/easy_install.py + +# twisted +from importlib import invalidate_caches # python/test/test_deprecate.py + +# astroid +import zipimport # manager.py +# IPython +from importlib.machinery import all_suffixes # core/completerlib.py +import importlib # html/notebookapp.py + 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 +# 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 try: import ujson as json except ImportError: @@ -57,5 +62,4 @@ import models def main(): pass - import after_method_is_valid_even_if_not_pep8 diff --git a/tests/_data_clean/test.py b/tests/_data_clean/test.py index 13a6d6b..8cffb51 100644 --- a/tests/_data_clean/test.py +++ b/tests/_data_clean/test.py @@ -1,50 +1,55 @@ """unused import""" # 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.sax # [unused-import] -# astroid -# setuptools -import zipimport # manager.py -# +1:[unused-import,unused-import] -from collections import Counter, OrderedDict, deque -# twisted -from importlib import invalidate_caches # python/test/test_deprecate.py -# IPython -from importlib.machinery import all_suffixes # core/completerlib.py +import os.path as test # [unused-import] 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 +# +1:[unused-import,unused-import] +from collections import deque, OrderedDict, Counter # All imports above should be ignored import requests # [unused-import] -from docopt import docopt + +# setuptools +import zipimport # command/easy_install.py + +# twisted +from importlib import invalidate_caches # python/test/test_deprecate.py + +# astroid +import zipimport # manager.py +# IPython +from importlib.machinery import all_suffixes # core/completerlib.py +import importlib # html/notebookapp.py + 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 +# 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 try: import ujson as json @@ -57,5 +62,4 @@ import models def main(): pass - import after_method_is_valid_even_if_not_pep8 diff --git a/tests/_data_ignore/.ignore_second/ignored.py b/tests/_data_ignore/.ignore_second/ignored.py index 6ea3598..b970ae3 100644 --- a/tests/_data_ignore/.ignore_second/ignored.py +++ b/tests/_data_ignore/.ignore_second/ignored.py @@ -1,2 +1,2 @@ # Everything in here should be ignored -from pattern.web import Twitter, plaintext +from pattern.web import Twitter, plaintext \ No newline at end of file diff --git a/tests/_data_ignore/test.py b/tests/_data_ignore/test.py index f520669..cfd039c 100644 --- a/tests/_data_ignore/test.py +++ b/tests/_data_ignore/test.py @@ -1,48 +1,52 @@ """unused import""" # 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.sax # [unused-import] -# astroid -# setuptools -import zipimport # manager.py -# +1:[unused-import,unused-import] -from collections import Counter, OrderedDict, deque -# twisted -from importlib import invalidate_caches # python/test/test_deprecate.py -# IPython -from importlib.machinery import all_suffixes # core/completerlib.py +import os.path as test # [unused-import] 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 +# +1:[unused-import,unused-import] +from collections import deque, OrderedDict, Counter # All imports above should be ignored import requests # [unused-import] -from docopt import docopt + +# setuptools +import zipimport # command/easy_install.py + +# twisted +from importlib import invalidate_caches # python/test/test_deprecate.py + +# astroid +import zipimport # manager.py +# IPython +from importlib.machinery import all_suffixes # core/completerlib.py +import importlib # html/notebookapp.py + 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 +# 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 try: import ujson as json except ImportError: @@ -54,5 +58,4 @@ import models def main(): pass - import after_method_is_valid_even_if_not_pep8 diff --git a/tests/settings.py b/tests/settings.py index f5698b6..c870b64 100644 --- a/tests/settings.py +++ b/tests/settings.py @@ -1,3 +1,15 @@ +""" +Environment variables can be used as a first choice +$ set CA_BUNDLE="certificates.pem" # for win OS +$ export CA_BUNDLE="certificates.pem" # for nix OS + +If environment variables are not found then a second attempt +will be made by loading the values from a .env.test file in +the same directory + +See ./env.test.example for details. +""" + import importlib import os diff --git a/tests/test_pipreqs.py b/tests/test_pipreqs.py index 1c861ba..1b3ff5e 100644 --- a/tests/test_pipreqs.py +++ b/tests/test_pipreqs.py @@ -6,11 +6,6 @@ test_pipreqs ---------------------------------- Tests for `pipreqs` module. - -Environment variables used to mock arguments -e.g., -$ set CA_BUNDLE="certificates.pem" # for win OS -$ export CA_BUNDLE="certificates.pem" # for nix OS """ import os @@ -19,55 +14,54 @@ import unittest import requests from pipreqs import pipreqs -from .settings import CA_BUNDLE + +CA_BUNDLE = os.environ.get("CA_BUNDLE") + +if CA_BUNDLE is None: + from tests.settings import CA_BUNDLE class TestPipreqs(unittest.TestCase): + def setUp(self): self.modules = [ - "flask", - "requests", - "sqlalchemy", - "docopt", - "boto", - "ipython", - "pyflakes", - "nose", - "analytics", - "flask_seasurf", - "peewee", - "ujson", - "nonexistendmodule", - "bs4", - "after_method_is_valid_even_if_not_pep8", - ] - self.modules2 = ["beautifulsoup4"] - self.local = ["docopt", "requests", "nose", "pyflakes"] + 'flask', 'requests', 'sqlalchemy', 'docopt', 'boto', 'ipython', + 'pyflakes', 'nose', 'analytics', 'flask_seasurf', 'peewee', + 'ujson', 'nonexistendmodule', 'bs4', + 'after_method_is_valid_even_if_not_pep8' + ] + self.modules2 = ['beautifulsoup4'] + self.local = ["docopt", "requests", "nose", 'pyflakes'] self.project = os.path.join(os.path.dirname(__file__), "_data") self.project_clean = os.path.join( - os.path.dirname(__file__), "_data_clean" - ) + os.path.dirname(__file__), + "_data_clean" + ) self.project_invalid = os.path.join( - os.path.dirname(__file__), "_invalid_data" - ) + os.path.dirname(__file__), + "_invalid_data" + ) self.project_with_ignore_directory = os.path.join( - os.path.dirname(__file__), "_data_ignore" - ) + os.path.dirname(__file__), + "_data_ignore" + ) self.project_with_duplicated_deps = os.path.join( - os.path.dirname(__file__), "_data_duplicated_deps" - ) + os.path.dirname(__file__), + "_data_duplicated_deps" + ) self.requirements_path = os.path.join(self.project, "requirements.txt") self.alt_requirement_path = os.path.join( - self.project, "requirements2.txt" - ) + self.project, + "requirements2.txt" + ) + def test_get_all_imports(self): imports = pipreqs.get_all_imports(self.project) self.assertEqual(len(imports), 15) for item in imports: self.assertTrue( - item.lower() in self.modules, "Import is missing: " + item - ) + item.lower() in self.modules, "Import is missing: " + item) self.assertFalse("time" in imports) self.assertFalse("logging" in imports) self.assertFalse("curses" in imports) @@ -86,8 +80,7 @@ class TestPipreqs(unittest.TestCase): Test that invalid python files cannot be imported. """ self.assertRaises( - SyntaxError, pipreqs.get_all_imports, self.project_invalid - ) + SyntaxError, pipreqs.get_all_imports, self.project_invalid) def test_get_imports_info(self): """ @@ -102,14 +95,13 @@ class TestPipreqs(unittest.TestCase): self.assertEqual(len(with_info), 13) for item in with_info: self.assertTrue( - item["name"].lower() in self.modules, - "Import item appears to be missing " + item["name"], - ) + item['name'].lower() in self.modules, + "Import item appears to be missing " + item['name']) def test_get_pkg_names(self): - pkgs = ["jury", "Japan", "camel", "Caroline"] + pkgs = ['jury', 'Japan', 'camel', 'Caroline'] actual_output = pipreqs.get_pkg_names(pkgs) - expected_output = ["camel", "Caroline", "Japan", "jury"] + expected_output = ['camel', 'Caroline', 'Japan', 'jury'] self.assertEqual(actual_output, expected_output) def test_get_use_local_only(self): @@ -124,7 +116,7 @@ class TestPipreqs(unittest.TestCase): # should find only docopt and requests imports_with_info = pipreqs.get_import_local(self.modules) for item in imports_with_info: - self.assertTrue(item["name"].lower() in self.local) + self.assertTrue(item['name'].lower() in self.local) def test_init(self): """ @@ -151,7 +143,7 @@ class TestPipreqs(unittest.TestCase): for item in self.modules[:-3]: self.assertTrue(item.lower() in data) # It should be sorted based on names. - data = data.strip().split("\n") + data = data.strip().split('\n') self.assertEqual(data, sorted(data)) def test_init_local_only(self): @@ -245,11 +237,11 @@ class TestPipreqs(unittest.TestCase): import_name_with_alias = "requests as R" expected_import_name_without_alias = "requests" import_name_without_aliases = pipreqs.get_name_without_alias( - import_name_with_alias - ) + import_name_with_alias) self.assertEqual( - import_name_without_aliases, expected_import_name_without_alias - ) + import_name_without_aliases, + expected_import_name_without_alias + ) def test_custom_pypi_server(self): """ @@ -290,14 +282,9 @@ class TestPipreqs(unittest.TestCase): "--mode": None, } ) - with open( - os.path.join( - self.project_with_ignore_directory, "requirements.txt" - ), - "r", - ) as f: + with open(os.path.join(self.project_with_ignore_directory, "requirements.txt"), "r") as f: data = f.read().lower() - for item in ["click", "getpass"]: + for item in ['click', 'getpass']: self.assertFalse(item.lower() in data) def test_dynamic_version_no_pin_scheme(self): @@ -319,14 +306,9 @@ class TestPipreqs(unittest.TestCase): "--mode": "no-pin", } ) - with open( - os.path.join( - self.project_with_ignore_directory, "requirements.txt" - ), - "r", - ) as f: + with open(os.path.join(self.project_with_ignore_directory, "requirements.txt"), "r") as f: data = f.read().lower() - for item in ["beautifulsoup4", "boto"]: + for item in ['beautifulsoup4', 'boto']: self.assertTrue(item.lower() in data) def test_dynamic_version_gt_scheme(self): @@ -348,16 +330,11 @@ class TestPipreqs(unittest.TestCase): "--mode": "gt", } ) - with open( - os.path.join( - self.project_with_ignore_directory, "requirements.txt" - ), - "r", - ) as f: + with open(os.path.join(self.project_with_ignore_directory, "requirements.txt"), "r") as f: data = f.readlines() for item in data: - symbol = ">=" - message = "symbol is not in item" + symbol = '>=' + message = 'symbol is not in item' self.assertIn(symbol, item, message) def test_dynamic_version_compat_scheme(self): @@ -379,16 +356,11 @@ class TestPipreqs(unittest.TestCase): "--mode": "compat", } ) - with open( - os.path.join( - self.project_with_ignore_directory, "requirements.txt" - ), - "r", - ) as f: + with open(os.path.join(self.project_with_ignore_directory, "requirements.txt"), "r") as f: data = f.readlines() for item in data: - symbol = "~=" - message = "symbol is not in item" + symbol = '~=' + message = 'symbol is not in item' self.assertIn(symbol, item, message) def test_clean(self): @@ -435,7 +407,7 @@ class TestPipreqs(unittest.TestCase): """ Test --clean parameter when there are imports to clean """ - cleaned_module = "sqlalchemy" + cleaned_module = 'sqlalchemy' pipreqs.init( { "": self.project, @@ -486,5 +458,5 @@ class TestPipreqs(unittest.TestCase): pass -if __name__ == "__main__": +if __name__ == '__main__': unittest.main()