diff --git a/.coveralls.yml b/.coveralls.yml deleted file mode 100644 index c9c691f..0000000 --- a/.coveralls.yml +++ /dev/null @@ -1 +0,0 @@ -service_name: "travis-ci" \ No newline at end of file diff --git a/.github/workflows/flake8.yml b/.github/workflows/flake8.yml new file mode 100644 index 0000000..819104d --- /dev/null +++ b/.github/workflows/flake8.yml @@ -0,0 +1,20 @@ +name: flake8 + +on: pull_request + +jobs: + flake8-lint: + runs-on: ubuntu-latest + name: Lint + steps: + - name: Check out source repository + uses: actions/checkout@v2 + - name: Set up Python environment + uses: actions/setup-python@v2 + with: + python-version: "3.9" + - name: flake8 Lint + uses: reviewdog/action-flake8@v3 + with: + github_token: ${{ secrets.GITHUB_TOKEN }} + reporter: github-pr-review diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml new file mode 100644 index 0000000..288065e --- /dev/null +++ b/.github/workflows/tests.yml @@ -0,0 +1,50 @@ +name: Tests and Codecov +on: pull_request +jobs: + run_tests: + runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + python-version: [3.6, 3.7, 3.8, 3.9, pypy-3.7] + + steps: + - name: Checkout repository + uses: actions/checkout@v2 + + - name: Set up Python ${{ matrix.python-version }} + uses: actions/setup-python@v2 + with: + python-version: ${{ matrix.python-version }} + + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install tox tox-gh-actions + + - name: Test with tox + run: tox + + coverage_report: + needs: run_tests + runs-on: ubuntu-latest + steps: + - name: Checkout repository + uses: actions/checkout@v2 + + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install coverage docopt yarg requests + + - name: Calculate coverage + run: coverage run --source=pipreqs -m unittest discover + + - name: Create XML report + run: coverage xml + + - name: Upload coverage to Codecov + uses: codecov/codecov-action@v2 + with: + files: coverage.xml + fail_ci_if_error: true diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 324b044..0000000 --- a/.travis.yml +++ /dev/null @@ -1,30 +0,0 @@ -# Config file for automatic testing at travis-ci.org - -language: python - -matrix: - include: - - python: 3.6 - env: TOX_ENV=py36 - - python: 3.5 - env: TOX_ENV=py35 - - python: 3.4 - env: TOX_ENV=py34 - - python: 2.7 - env: TOX_ENV=py27 - - python: pypy - env: TOX_ENV=pypy - - python: 3.6 - env: TOX_ENV=flake8 - -# Use tox to run tests on Travis-CI to keep one unified method of running tests in any environment -install: - - pip install coverage coveralls tox - -# Command to run tests, e.g. python setup.py test -script: tox -e $TOX_ENV - -# Use after_success to get a single coveralls report -after_success: - - coverage run --source=pipreqs setup.py test - - coveralls diff --git a/AUTHORS.rst b/AUTHORS.rst index eaa038a..2f31bac 100644 --- a/AUTHORS.rst +++ b/AUTHORS.rst @@ -10,4 +10,5 @@ Development Lead Contributors ------------ -None yet. Why not be the first? +* Jake Teo +* Jerome Chan diff --git a/HISTORY.rst b/HISTORY.rst index b9d17e7..cb4d47b 100644 --- a/HISTORY.rst +++ b/HISTORY.rst @@ -3,6 +3,11 @@ History ------- +0.4.11 (2020-03-29) +-------------------- + +* Implement '--mode' (Jake Teo, Jerome Chan) + 0.4.8 (2017-06-30) -------------------- diff --git a/README.rst b/README.rst index 139fa7d..68411fc 100644 --- a/README.rst +++ b/README.rst @@ -4,20 +4,19 @@ .. image:: https://img.shields.io/travis/bndr/pipreqs.svg :target: https://travis-ci.org/bndr/pipreqs - - + + .. image:: https://img.shields.io/pypi/v/pipreqs.svg :target: https://pypi.python.org/pypi/pipreqs - -.. image:: https://img.shields.io/coveralls/bndr/pipreqs.svg - :target: https://coveralls.io/r/bndr/pipreqs - - -.. image:: https://img.shields.io/pypi/l/pipreqs.svg + +.. image:: https://codecov.io/gh/bndr/pipreqs/branch/master/graph/badge.svg?token=0rfPfUZEAX + :target: https://codecov.io/gh/bndr/pipreqs + +.. image:: https://img.shields.io/pypi/l/pipreqs.svg :target: https://pypi.python.org/pypi/pipreqs - + Installation ------------ @@ -32,7 +31,11 @@ Usage :: Usage: - pipreqs [options] + pipreqs [options] [] + + Arguments: + The path to the directory containing the application files for which a requirements file + should be generated (defaults to the current working directory) Options: --use-local Use ONLY local package info instead of querying PyPI @@ -42,14 +45,18 @@ Usage $ export HTTP_PROXY="http://10.10.1.10:3128" $ export HTTPS_PROXY="https://10.10.1.10:1080" --debug Print debug information - --ignore ... Ignore extra directories + --ignore ... Ignore extra directories, each separated by a comma + --no-follow-links Do not follow symbolic links in the project --encoding Use encoding parameter for file open --savepath Save the list of requirements in the given file --print Output the list of requirements in the standard output --force Overwrite existing requirements.txt - --diff Compare modules in requirements.txt to project imports. - --clean Clean up requirements.txt by removing modules that are not imported in project. - --no-pin Omit version of output packages. + --diff Compare modules in requirements.txt to project imports + --clean Clean up requirements.txt by removing modules that are not imported in project + --mode Enables dynamic versioning with , or schemes + | e.g. Flask~=1.1.2 + | e.g. Flask>=1.1.2 + | e.g. Flask Example ------- @@ -65,10 +72,10 @@ Contents of requirements.txt wheel==0.23.0 Yarg==0.1.9 docopt==0.6.2 - + Why not pip freeze? ------------------- -- ``pip freeze`` only saves the packages that are installed with ``pip install`` in your environment. -- ``pip freeze`` saves all packages in the environment including those that you don't use in your current project. (if you don't have virtualenv) -- and sometimes you just need to create requirements.txt for a new project without installing modules. +- ``pip freeze`` only saves the packages that are installed with ``pip install`` in your environment. +- ``pip freeze`` saves all packages in the environment including those that you don't use in your current project (if you don't have ``virtualenv``). +- and sometimes you just need to create ``requirements.txt`` for a new project without installing modules. diff --git a/pipreqs/mapping b/pipreqs/mapping index 6f5a469..c1729eb 100644 --- a/pipreqs/mapping +++ b/pipreqs/mapping @@ -1,3 +1,4 @@ +AFQ:pyAFQ AG_fft_tools:agpy ANSI:pexpect Adafruit:Adafruit_Libraries @@ -13,6 +14,7 @@ Crypto:pycryptodome Cryptodome:pycryptodomex FSM:pexpect FiftyOneDegrees:51degrees_mobile_detector_v3_wrapper +functional:pyfunctional GeoBaseMain:GeoBasesDev GeoBases:GeoBasesDev Globals:Zope2 @@ -22,6 +24,7 @@ Kittens:astro_kittens Levenshtein:python_Levenshtein Lifetime:Zope2 MethodObject:ExtensionClass +MySQLdb:MySQL-python OFS:Zope2 OpenGL:PyOpenGL OpenSSL:pyOpenSSL @@ -592,6 +595,7 @@ devtools:tg.devtools dgis:2gis dhtmlparser:pyDHTMLParser digitalocean:python_digitalocean +discord:discord.py distribute_setup:ez_setup distutils2:Distutils2 django:Django @@ -675,6 +679,7 @@ geventwebsocket:gevent_websocket gflags:python_gflags git:GitPython github:PyGithub +github3:github3.py gitpy:git_py globusonline:globusonline_transfer_api_client google:protobuf @@ -701,7 +706,7 @@ html:pies2overrides htmloutput:nosehtmloutput http:pies2overrides hvad:django_hvad -krbV:krbv +hydra:hydra-core i99fix:199Fix igraph:python_igraph imdb:IMDbPY @@ -727,6 +732,7 @@ keyczar:python_keyczar keyedcache:django_keyedcache keystoneclient:python_keystoneclient kickstarter:kickstart +krbv:krbV kss:kss.core kuyruk:Kuyruk langconv:AdvancedLangConv @@ -798,7 +804,6 @@ msgpack:msgpack_python mutations:aino_mutations mws:amazon_mws mysql:mysql_connector_repackaged -MySQL-python:MySQLdb native_tags:django_native_tags ndg:ndg_httpsclient nereid:trytond_nereid @@ -999,6 +1004,7 @@ ruamel:ruamel.base s2repoze:pysaml2 saga:saga_python saml2:pysaml2 +samtranslator:aws-sam-translator sass:libsass sassc:libsass sasstests:libsass diff --git a/pipreqs/pipreqs.py b/pipreqs/pipreqs.py old mode 100755 new mode 100644 index 4b817c3..24eeeb7 --- a/pipreqs/pipreqs.py +++ b/pipreqs/pipreqs.py @@ -1,5 +1,4 @@ #!/usr/bin/env python -# -*- coding: utf-8 -*- """pipreqs - Generate pip requirements.txt file based on imports Usage: @@ -19,27 +18,29 @@ Options: parameter in your terminal: $ export HTTP_PROXY="http://10.10.1.10:3128" $ export HTTPS_PROXY="https://10.10.1.10:1080" - --debug Print debug information. - --ignore ... Ignore extra directories, each separated by a comma. + --debug Print debug information + --ignore ... Ignore extra directories, each separated by a comma --no-follow-links Do not follow symbolic links in the project --encoding Use encoding parameter for file open --savepath Save the list of requirements in the given file --print Output the list of requirements in the standard - output. + output --force Overwrite existing requirements.txt --diff Compare modules in requirements.txt to project - imports. + imports --clean Clean up requirements.txt by removing modules - that are not imported in project. - --no-pin Omit version of output packages. + that are not imported in project + --mode Enables dynamic versioning with , + or schemes. + | e.g. Flask~=1.1.2 + | e.g. Flask>=1.1.2 + | e.g. Flask """ -from __future__ import print_function, absolute_import from contextlib import contextmanager import os import sys import re import logging -import codecs import ast import traceback from docopt import docopt @@ -54,14 +55,6 @@ REGEXP = [ re.compile(r'^from ((?!\.+).*?) import (?:.*)$') ] -if sys.version_info[0] > 2: - open_func = open - py2 = False -else: - open_func = codecs.open - py2 = True - py2_exclude = ["concurrent", "concurrent.futures"] - @contextmanager def _open(filename=None, mode='r'): @@ -118,7 +111,7 @@ def get_all_imports( candidates += [os.path.splitext(fn)[0] for fn in files] for file_name in files: file_name = os.path.join(root, file_name) - with open_func(file_name, "r", encoding=encoding) as f: + with open(file_name, "r", encoding=encoding) as f: contents = f.read() try: tree = ast.parse(contents) @@ -153,29 +146,28 @@ def get_all_imports( with open(join("stdlib"), "r") as f: data = {x.strip() for x in f} - data = {x for x in data if x not in py2_exclude} if py2 else data return list(packages - data) -def filter_line(l): - return len(l) > 0 and l[0] != "#" +def filter_line(line): + return len(line) > 0 and line[0] != "#" -def generate_requirements_file(path, imports): +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}=={version}' + 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): - generate_requirements_file('-', imports) +def output_requirements(imports, symbol): + generate_requirements_file('-', imports, symbol) def get_imports_info( @@ -210,7 +202,7 @@ def get_locally_installed_packages(encoding=None): for item in files: if "top_level" in item: item = os.path.join(root, item) - with open_func(item, "r", encoding=encoding) as f: + with open(item, "r", encoding=encoding) as f: package = root.split(os.sep)[-1].split("-") try: package_import = f.read().strip().split("\n") @@ -305,7 +297,7 @@ def parse_requirements(file_): delim = ["<", ">", "=", "!", "~"] try: - f = open_func(file_, "r") + f = open(file_, "r") except OSError: logging.error("Failed on file: {}".format(file_)) raise @@ -368,11 +360,16 @@ def diff(file_, imports): def clean(file_, imports): """Remove modules that aren't imported in project from file.""" modules_not_imported = compare_modules(file_, imports) + + if len(modules_not_imported) == 0: + logging.info("Nothing to clean in " + file_) + return + re_remove = re.compile("|".join(modules_not_imported)) to_write = [] try: - f = open_func(file_, "r+") + f = open(file_, "r+") except OSError: logging.error("Failed on file: {}".format(file_)) raise @@ -392,6 +389,18 @@ def clean(file_, imports): logging.info("Successfully cleaned up requirements in " + file_) +def dynamic_versioning(scheme, imports): + """Enables dynamic versioning with , or schemes.""" + if scheme == "no-pin": + imports = [{"name": item["name"], "version": ""} for item in imports] + symbol = "" + elif scheme == "gt": + symbol = ">=" + elif scheme == "compat": + symbol = "~=" + return imports, symbol + + def init(args): encoding = args.get('--encoding') extra_ignore_dirs = args.get('--ignore') @@ -430,6 +439,8 @@ def init(args): imports = local + get_imports_info(difference, proxy=proxy, 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")) @@ -446,18 +457,25 @@ def init(args): and not args["--savepath"] and not args["--force"] and os.path.exists(path)): - logging.warning("Requirements.txt already exists, " + logging.warning("requirements.txt already exists, " "use --force to overwrite it") return - if args.get('--no-pin'): - imports = [{'name': item["name"], 'version': ''} for item in imports] + 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") + else: + symbol = "==" if args["--print"]: - output_requirements(imports) + output_requirements(imports, symbol) logging.info("Successfully output requirements") else: - generate_requirements_file(path, imports) + generate_requirements_file(path, imports, symbol) logging.info("Successfully saved requirements file in " + path) diff --git a/pipreqs/stdlib b/pipreqs/stdlib index 470fd5c..ec03d25 100644 --- a/pipreqs/stdlib +++ b/pipreqs/stdlib @@ -1,148 +1,181 @@ -__builtin__ -__future__ -__main__ -_dummy_thread -_thread -_winreg +_abc abc -aepack -aetools -aetypes aifc -AL -al -anydbm -applesingle +_aix_support +antigravity argparse array +_ast ast asynchat +_asyncio asyncio +asyncio.base_events +asyncio.base_futures +asyncio.base_subprocess +asyncio.base_tasks +asyncio.constants +asyncio.coroutines +asyncio.events +asyncio.exceptions +asyncio.format_helpers +asyncio.futures +asyncio.locks +asyncio.log +asyncio.__main__ +asyncio.proactor_events +asyncio.protocols +asyncio.queues +asyncio.runners +asyncio.selector_events +asyncio.sslproto +asyncio.staggered +asyncio.streams +asyncio.subprocess +asyncio.tasks +asyncio.threads +asyncio.transports +asyncio.trsock +asyncio.unix_events +asyncio.windows_events +asyncio.windows_utils asyncore atexit audioop -autoGIL base64 -BaseHTTPServer -Bastion bdb binascii binhex +_bisect bisect -bsddb -buildtools +_blake2 +_bootlocale +_bootsubprocess builtins +_bz2 bz2 calendar -Carbon -Carbon.AE -Carbon.AH -Carbon.App -Carbon.Appearance -Carbon.CarbonEvents -Carbon.CarbonEvt -Carbon.CF -Carbon.CG -Carbon.Cm -Carbon.Components -Carbon.ControlAccessor -Carbon.Controls -Carbon.CoreFounation -Carbon.CoreGraphics -Carbon.Ctl -Carbon.Dialogs -Carbon.Dlg -Carbon.Drag -Carbon.Dragconst -Carbon.Events -Carbon.Evt -Carbon.File -Carbon.Files -Carbon.Fm -Carbon.Folder -Carbon.Folders -Carbon.Fonts -Carbon.Help -Carbon.IBCarbon -Carbon.IBCarbonRuntime -Carbon.Icns -Carbon.Icons -Carbon.Launch -Carbon.LaunchServices -Carbon.List -Carbon.Lists -Carbon.MacHelp -Carbon.MediaDescr -Carbon.Menu -Carbon.Menus -Carbon.Mlte -Carbon.OSA -Carbon.OSAconst -Carbon.Qd -Carbon.Qdoffs -Carbon.QDOffscreen -Carbon.Qt -Carbon.QuickDraw -Carbon.QuickTime -Carbon.Res -Carbon.Resources -Carbon.Scrap -Carbon.Snd -Carbon.Sound -Carbon.TE -Carbon.TextEdit -Carbon.Win -Carbon.Windows -cd -cfmfile cgi -CGIHTTPServer cgitb chunk cmath cmd code +_codecs codecs +_codecs_cn +_codecs_hk +_codecs_iso2022 +_codecs_jp +_codecs_kr +_codecs_tw codeop +_collections collections +_collections_abc collections.abc -ColorPicker colorsys -commands +_compat_pickle compileall -compiler -compiler.ast -compiler.visitor +_compression concurrent concurrent.futures -ConfigParser +concurrent.futures._base +concurrent.futures.process +concurrent.futures.thread configparser contextlib -Cookie -cookielib +_contextvars +contextvars copy -copy_reg copyreg -cPickle cProfile +_crypt crypt -cStringIO +_csv csv +_ctypes ctypes +ctypes._aix +ctypes._endian +ctypes.macholib +ctypes.macholib.dyld +ctypes.macholib.dylib +ctypes.macholib.framework +_ctypes_test +ctypes.test +ctypes.test.__main__ +ctypes.test.test_anon +ctypes.test.test_array_in_pointer +ctypes.test.test_arrays +ctypes.test.test_as_parameter +ctypes.test.test_bitfields +ctypes.test.test_buffers +ctypes.test.test_bytes +ctypes.test.test_byteswap +ctypes.test.test_callbacks +ctypes.test.test_cast +ctypes.test.test_cfuncs +ctypes.test.test_checkretval +ctypes.test.test_delattr +ctypes.test.test_errno +ctypes.test.test_find +ctypes.test.test_frombuffer +ctypes.test.test_funcptr +ctypes.test.test_functions +ctypes.test.test_incomplete +ctypes.test.test_init +ctypes.test.test_internals +ctypes.test.test_keeprefs +ctypes.test.test_libc +ctypes.test.test_loading +ctypes.test.test_macholib +ctypes.test.test_memfunctions +ctypes.test.test_numbers +ctypes.test.test_objects +ctypes.test.test_parameters +ctypes.test.test_pep3118 +ctypes.test.test_pickling +ctypes.test.test_pointers +ctypes.test.test_prototypes +ctypes.test.test_python_api +ctypes.test.test_random_things +ctypes.test.test_refcounts +ctypes.test.test_repr +ctypes.test.test_returnfuncptrs +ctypes.test.test_simplesubclasses +ctypes.test.test_sizes +ctypes.test.test_slicing +ctypes.test.test_stringptr +ctypes.test.test_strings +ctypes.test.test_struct_fields +ctypes.test.test_structures +ctypes.test.test_unaligned_structures +ctypes.test.test_unicode +ctypes.test.test_values +ctypes.test.test_varsize_struct +ctypes.test.test_win32 +ctypes.test.test_wintypes +ctypes.util +ctypes.wintypes +_curses curses curses.ascii +curses.has_key +_curses_panel curses.panel curses.textpad +dataclasses +_datetime datetime -dbhash +_dbm dbm dbm.dumb dbm.gnu dbm.ndbm +_decimal decimal -DEVICE difflib -dircache dis distutils distutils.archive_util @@ -166,247 +199,688 @@ distutils.command.clean distutils.command.config distutils.command.install distutils.command.install_data +distutils.command.install_egg_info distutils.command.install_headers distutils.command.install_lib distutils.command.install_scripts distutils.command.register distutils.command.sdist +distutils.command.upload +distutils.config distutils.core distutils.cygwinccompiler distutils.debug distutils.dep_util distutils.dir_util distutils.dist -distutils.emxccompiler distutils.errors distutils.extension distutils.fancy_getopt -distutils.file_util distutils.filelist +distutils.file_util distutils.log +distutils.msvc9compiler +distutils._msvccompiler distutils.msvccompiler distutils.spawn distutils.sysconfig +distutils.tests +distutils.tests.support +distutils.tests.test_archive_util +distutils.tests.test_bdist +distutils.tests.test_bdist_dumb +distutils.tests.test_bdist_msi +distutils.tests.test_bdist_rpm +distutils.tests.test_bdist_wininst +distutils.tests.test_build +distutils.tests.test_build_clib +distutils.tests.test_build_ext +distutils.tests.test_build_py +distutils.tests.test_build_scripts +distutils.tests.test_check +distutils.tests.test_clean +distutils.tests.test_cmd +distutils.tests.test_config +distutils.tests.test_config_cmd +distutils.tests.test_core +distutils.tests.test_cygwinccompiler +distutils.tests.test_dep_util +distutils.tests.test_dir_util +distutils.tests.test_dist +distutils.tests.test_extension +distutils.tests.test_filelist +distutils.tests.test_file_util +distutils.tests.test_install +distutils.tests.test_install_data +distutils.tests.test_install_headers +distutils.tests.test_install_lib +distutils.tests.test_install_scripts +distutils.tests.test_log +distutils.tests.test_msvc9compiler +distutils.tests.test_msvccompiler +distutils.tests.test_register +distutils.tests.test_sdist +distutils.tests.test_spawn +distutils.tests.test_sysconfig +distutils.tests.test_text_file +distutils.tests.test_unixccompiler +distutils.tests.test_upload +distutils.tests.test_util +distutils.tests.test_version +distutils.tests.test_versionpredicate distutils.text_file distutils.unixccompiler distutils.util distutils.version -dl +distutils.versionpredicate doctest -DocXMLRPCServer -dumbdbm -dummy_thread +_dummy_thread dummy_threading -EasyDialogs +_elementtree email +email.base64mime email.charset email.contentmanager +email._encoded_words email.encoders email.errors +email.feedparser email.generator email.header email.headerregistry +email._header_value_parser email.iterators email.message email.mime +email.mime.application +email.mime.audio +email.mime.base +email.mime.image +email.mime.message +email.mime.multipart +email.mime.nonmultipart +email.mime.text +email._parseaddr email.parser email.policy +email._policybase +email.quoprimime email.utils encodings +encodings.aliases +encodings.ascii +encodings.base64_codec +encodings.big5 +encodings.big5hkscs +encodings.bz2_codec +encodings.charmap +encodings.cp037 +encodings.cp1006 +encodings.cp1026 +encodings.cp1125 +encodings.cp1140 +encodings.cp1250 +encodings.cp1251 +encodings.cp1252 +encodings.cp1253 +encodings.cp1254 +encodings.cp1255 +encodings.cp1256 +encodings.cp1257 +encodings.cp1258 +encodings.cp273 +encodings.cp424 +encodings.cp437 +encodings.cp500 +encodings.cp720 +encodings.cp737 +encodings.cp775 +encodings.cp850 +encodings.cp852 +encodings.cp855 +encodings.cp856 +encodings.cp857 +encodings.cp858 +encodings.cp860 +encodings.cp861 +encodings.cp862 +encodings.cp863 +encodings.cp864 +encodings.cp865 +encodings.cp866 +encodings.cp869 +encodings.cp874 +encodings.cp875 +encodings.cp932 +encodings.cp949 +encodings.cp950 +encodings.euc_jis_2004 +encodings.euc_jisx0213 +encodings.euc_jp +encodings.euc_kr +encodings.gb18030 +encodings.gb2312 +encodings.gbk +encodings.hex_codec +encodings.hp_roman8 +encodings.hz encodings.idna +encodings.iso2022_jp +encodings.iso2022_jp_1 +encodings.iso2022_jp_2 +encodings.iso2022_jp_2004 +encodings.iso2022_jp_3 +encodings.iso2022_jp_ext +encodings.iso2022_kr +encodings.iso8859_1 +encodings.iso8859_10 +encodings.iso8859_11 +encodings.iso8859_13 +encodings.iso8859_14 +encodings.iso8859_15 +encodings.iso8859_16 +encodings.iso8859_2 +encodings.iso8859_3 +encodings.iso8859_4 +encodings.iso8859_5 +encodings.iso8859_6 +encodings.iso8859_7 +encodings.iso8859_8 +encodings.iso8859_9 +encodings.johab +encodings.koi8_r +encodings.koi8_t +encodings.koi8_u +encodings.kz1048 +encodings.latin_1 +encodings.mac_arabic +encodings.mac_centeuro +encodings.mac_croatian +encodings.mac_cyrillic +encodings.mac_farsi +encodings.mac_greek +encodings.mac_iceland +encodings.mac_latin2 +encodings.mac_roman +encodings.mac_romanian +encodings.mac_turkish encodings.mbcs +encodings.oem +encodings.palmos +encodings.ptcp154 +encodings.punycode +encodings.quopri_codec +encodings.raw_unicode_escape +encodings.rot_13 +encodings.shift_jis +encodings.shift_jis_2004 +encodings.shift_jisx0213 +encodings.tis_620 +encodings.undefined +encodings.unicode_escape +encodings.utf_16 +encodings.utf_16_be +encodings.utf_16_le +encodings.utf_32 +encodings.utf_32_be +encodings.utf_32_le +encodings.utf_7 +encodings.utf_8 encodings.utf_8_sig +encodings.uu_codec +encodings.zlib_codec ensurepip +ensurepip._bundled +ensurepip.__main__ +ensurepip._uninstall enum errno -exceptions faulthandler fcntl filecmp fileinput -findertools -FL -fl -flp -fm fnmatch formatter -fpectl -fpformat fractions -FrameWork +_frozen_importlib +_frozen_importlib_external ftplib +_functools functools -future_builtins +__future__ gc -gdbm -gensuitemodule +_gdbm +genericpath getopt getpass gettext -GL -gl glob +graphlib grp gzip +_hashlib hashlib +_heapq heapq hmac -hotshot -hotshot.stats html html.entities html.parser -htmlentitydefs -htmllib -HTMLParser http http.client http.cookiejar http.cookies http.server -httplib -ic -icopen -imageop +idlelib +idlelib.autocomplete +idlelib.autocomplete_w +idlelib.autoexpand +idlelib.browser +idlelib.calltip +idlelib.calltip_w +idlelib.codecontext +idlelib.colorizer +idlelib.config +idlelib.configdialog +idlelib.config_key +idlelib.debugger +idlelib.debugger_r +idlelib.debugobj +idlelib.debugobj_r +idlelib.delegator +idlelib.dynoption +idlelib.editor +idlelib.filelist +idlelib.format +idlelib.grep +idlelib.help +idlelib.help_about +idlelib.history +idlelib.hyperparser +idlelib.idle +idlelib.idle_test +idlelib.idle_test.htest +idlelib.idle_test.mock_idle +idlelib.idle_test.mock_tk +idlelib.idle_test.template +idlelib.idle_test.test_autocomplete +idlelib.idle_test.test_autocomplete_w +idlelib.idle_test.test_autoexpand +idlelib.idle_test.test_browser +idlelib.idle_test.test_calltip +idlelib.idle_test.test_calltip_w +idlelib.idle_test.test_codecontext +idlelib.idle_test.test_colorizer +idlelib.idle_test.test_config +idlelib.idle_test.test_configdialog +idlelib.idle_test.test_config_key +idlelib.idle_test.test_debugger +idlelib.idle_test.test_debugger_r +idlelib.idle_test.test_debugobj +idlelib.idle_test.test_debugobj_r +idlelib.idle_test.test_delegator +idlelib.idle_test.test_editmenu +idlelib.idle_test.test_editor +idlelib.idle_test.test_filelist +idlelib.idle_test.test_format +idlelib.idle_test.test_grep +idlelib.idle_test.test_help +idlelib.idle_test.test_help_about +idlelib.idle_test.test_history +idlelib.idle_test.test_hyperparser +idlelib.idle_test.test_iomenu +idlelib.idle_test.test_macosx +idlelib.idle_test.test_mainmenu +idlelib.idle_test.test_multicall +idlelib.idle_test.test_outwin +idlelib.idle_test.test_parenmatch +idlelib.idle_test.test_pathbrowser +idlelib.idle_test.test_percolator +idlelib.idle_test.test_pyparse +idlelib.idle_test.test_pyshell +idlelib.idle_test.test_query +idlelib.idle_test.test_redirector +idlelib.idle_test.test_replace +idlelib.idle_test.test_rpc +idlelib.idle_test.test_run +idlelib.idle_test.test_runscript +idlelib.idle_test.test_scrolledlist +idlelib.idle_test.test_search +idlelib.idle_test.test_searchbase +idlelib.idle_test.test_searchengine +idlelib.idle_test.test_sidebar +idlelib.idle_test.test_squeezer +idlelib.idle_test.test_stackviewer +idlelib.idle_test.test_statusbar +idlelib.idle_test.test_text +idlelib.idle_test.test_textview +idlelib.idle_test.test_tooltip +idlelib.idle_test.test_tree +idlelib.idle_test.test_undo +idlelib.idle_test.test_warning +idlelib.idle_test.test_window +idlelib.idle_test.test_zoomheight +idlelib.iomenu +idlelib.macosx +idlelib.__main__ +idlelib.mainmenu +idlelib.multicall +idlelib.outwin +idlelib.parenmatch +idlelib.pathbrowser +idlelib.percolator +idlelib.pyparse +idlelib.pyshell +idlelib.query +idlelib.redirector +idlelib.replace +idlelib.rpc +idlelib.run +idlelib.runscript +idlelib.scrolledlist +idlelib.search +idlelib.searchbase +idlelib.searchengine +idlelib.sidebar +idlelib.squeezer +idlelib.stackviewer +idlelib.statusbar +idlelib.textview +idlelib.tooltip +idlelib.tree +idlelib.undo +idlelib.window +idlelib.zoomheight +idlelib.zzdummy imaplib -imgfile imghdr +_imp imp importlib importlib.abc +importlib._bootstrap +importlib._bootstrap_external +importlib._common importlib.machinery +importlib.metadata +importlib.resources importlib.util -imputil inspect +_io io ipaddress itertools -jpeg +_json json +json.decoder +json.encoder +json.scanner json.tool keyword lib2to3 +lib2to3.btm_matcher +lib2to3.btm_utils +lib2to3.fixer_base +lib2to3.fixer_util +lib2to3.fixes +lib2to3.fixes.fix_apply +lib2to3.fixes.fix_asserts +lib2to3.fixes.fix_basestring +lib2to3.fixes.fix_buffer +lib2to3.fixes.fix_dict +lib2to3.fixes.fix_except +lib2to3.fixes.fix_exec +lib2to3.fixes.fix_execfile +lib2to3.fixes.fix_exitfunc +lib2to3.fixes.fix_filter +lib2to3.fixes.fix_funcattrs +lib2to3.fixes.fix_future +lib2to3.fixes.fix_getcwdu +lib2to3.fixes.fix_has_key +lib2to3.fixes.fix_idioms +lib2to3.fixes.fix_import +lib2to3.fixes.fix_imports +lib2to3.fixes.fix_imports2 +lib2to3.fixes.fix_input +lib2to3.fixes.fix_intern +lib2to3.fixes.fix_isinstance +lib2to3.fixes.fix_itertools +lib2to3.fixes.fix_itertools_imports +lib2to3.fixes.fix_long +lib2to3.fixes.fix_map +lib2to3.fixes.fix_metaclass +lib2to3.fixes.fix_methodattrs +lib2to3.fixes.fix_ne +lib2to3.fixes.fix_next +lib2to3.fixes.fix_nonzero +lib2to3.fixes.fix_numliterals +lib2to3.fixes.fix_operator +lib2to3.fixes.fix_paren +lib2to3.fixes.fix_print +lib2to3.fixes.fix_raise +lib2to3.fixes.fix_raw_input +lib2to3.fixes.fix_reduce +lib2to3.fixes.fix_reload +lib2to3.fixes.fix_renames +lib2to3.fixes.fix_repr +lib2to3.fixes.fix_set_literal +lib2to3.fixes.fix_standarderror +lib2to3.fixes.fix_sys_exc +lib2to3.fixes.fix_throw +lib2to3.fixes.fix_tuple_params +lib2to3.fixes.fix_types +lib2to3.fixes.fix_unicode +lib2to3.fixes.fix_urllib +lib2to3.fixes.fix_ws_comma +lib2to3.fixes.fix_xrange +lib2to3.fixes.fix_xreadlines +lib2to3.fixes.fix_zip +lib2to3.main +lib2to3.__main__ +lib2to3.patcomp +lib2to3.pgen2 +lib2to3.pgen2.conv +lib2to3.pgen2.driver +lib2to3.pgen2.grammar +lib2to3.pgen2.literals +lib2to3.pgen2.parse +lib2to3.pgen2.pgen +lib2to3.pgen2.token +lib2to3.pgen2.tokenize +lib2to3.pygram +lib2to3.pytree +lib2to3.refactor +lib2to3.tests +lib2to3.tests.data.bom +lib2to3.tests.data.crlf +lib2to3.tests.data.different_encoding +lib2to3.tests.data.false_encoding +lib2to3.tests.data.fixers.bad_order +lib2to3.tests.data.fixers.myfixes +lib2to3.tests.data.fixers.myfixes.fix_explicit +lib2to3.tests.data.fixers.myfixes.fix_first +lib2to3.tests.data.fixers.myfixes.fix_last +lib2to3.tests.data.fixers.myfixes.fix_parrot +lib2to3.tests.data.fixers.myfixes.fix_preorder +lib2to3.tests.data.fixers.no_fixer_cls +lib2to3.tests.data.fixers.parrot_example +lib2to3.tests.data.infinite_recursion +lib2to3.tests.data.py2_test_grammar +lib2to3.tests.data.py3_test_grammar +lib2to3.tests.__main__ +lib2to3.tests.pytree_idempotency +lib2to3.tests.support +lib2to3.tests.test_all_fixers +lib2to3.tests.test_fixers +lib2to3.tests.test_main +lib2to3.tests.test_parser +lib2to3.tests.test_pytree +lib2to3.tests.test_refactor +lib2to3.tests.test_util +lib.libpython3 linecache +_locale locale logging logging.config logging.handlers +_lsprof +_lzma lzma -macerrors -MacOS -macostools -macpath -macresource mailbox mailcap +__main__ +_markupbase marshal math -md5 -mhlib -mimetools +_md5 mimetypes -MimeWriter -mimify -MiniAEFrame mmap modulefinder msilib msvcrt -multifile +_multibytecodec +_multiprocessing multiprocessing multiprocessing.connection +multiprocessing.context multiprocessing.dummy +multiprocessing.dummy.connection +multiprocessing.forkserver +multiprocessing.heap multiprocessing.managers multiprocessing.pool +multiprocessing.popen_fork +multiprocessing.popen_forkserver +multiprocessing.popen_spawn_posix +multiprocessing.popen_spawn_win32 +multiprocessing.process +multiprocessing.queues +multiprocessing.reduction +multiprocessing.resource_sharer +multiprocessing.resource_tracker multiprocessing.sharedctypes -mutex -Nav +multiprocessing.shared_memory +multiprocessing.spawn +multiprocessing.synchronize +multiprocessing.util netrc -new nis nntplib +ntpath +nturl2path numbers +_opcode +opcode +_operator operator optparse os os.path ossaudiodev +_osx_support parser pathlib pdb +__phello__.foo +_pickle pickle pickletools pipes -PixMapWrapper -pkg_resources pkgutil platform plistlib -popen2 poplib posix -posixfile +posixpath +_posixshmem +_posixsubprocess pprint profile pstats pty pwd -py_compile +_py_abc pyclbr +py_compile +_pydecimal pydoc -Queue +pydoc_data +pydoc_data.topics +pyexpat +_pyio +_queue queue quopri +_random random re readline reprlib resource -rexec -rfc822 rlcompleter -robotparser runpy sched -ScrolledText +secrets select selectors -sets -setuptools -sgmllib -sha +_sha1 +_sha256 +_sha3 +_sha512 shelve shlex shutil +_signal signal -SimpleHTTPServer -SimpleXMLRPCServer site +_sitebuiltins smtpd smtplib sndhdr +_socket socket -SocketServer socketserver spwd +_sqlite3 sqlite3 +sqlite3.dbapi2 +sqlite3.dump +sqlite3.test +sqlite3.test.backup +sqlite3.test.dbapi +sqlite3.test.dump +sqlite3.test.factory +sqlite3.test.hooks +sqlite3.test.regression +sqlite3.test.transactions +sqlite3.test.types +sqlite3.test.userfunctions +_sre +sre_compile +sre_constants +sre_parse +_ssl ssl +_stat stat +_statistics statistics -statvfs +_string string -StringIO stringprep +_strptime +_struct struct subprocess sunau -SUNAUDIODEV -sunaudiodev symbol +_symtable symtable sys sysconfig +_sysconfigdata_x86_64_conda_cos6_linux_gnu +_sysconfigdata_x86_64_conda_linux_gnu syslog tabnanny tarfile @@ -414,55 +888,853 @@ telnetlib tempfile termios test +test.ann_module +test.ann_module2 +test.ann_module3 +test.audiotests +test.autotest +test.bad_coding +test.bad_coding2 +test.bad_getattr +test.bad_getattr2 +test.bad_getattr3 +test.badsyntax_3131 +test.badsyntax_future10 +test.badsyntax_future3 +test.badsyntax_future4 +test.badsyntax_future5 +test.badsyntax_future6 +test.badsyntax_future7 +test.badsyntax_future8 +test.badsyntax_future9 +test.badsyntax_pep3120 +test.bisect_cmd +_testbuffer +test.bytecode_helper +_testcapi +test.coding20731 +test.curses_tests +test.dataclass_module_1 +test.dataclass_module_1_str +test.dataclass_module_2 +test.dataclass_module_2_str +test.datetimetester +test.dis_module +test.doctest_aliases +test.double_const +test.dtracedata.call_stack +test.dtracedata.gc +test.dtracedata.instance +test.dtracedata.line +test.eintrdata.eintr_tester +test.encoded_modules +test.encoded_modules.module_iso_8859_1 +test.encoded_modules.module_koi8_r +test.final_a +test.final_b +test.fork_wait +test.future_test1 +test.future_test2 +test.gdb_sample +test.good_getattr +test.imp_dummy +_testimportmultiple +test.inspect_fodder +test.inspect_fodder2 +_testinternalcapi +test.libregrtest +test.libregrtest.cmdline +test.libregrtest.main +test.libregrtest.pgo +test.libregrtest.refleak +test.libregrtest.runtest +test.libregrtest.runtest_mp +test.libregrtest.save_env +test.libregrtest.setup +test.libregrtest.utils +test.libregrtest.win_utils +test.list_tests +test.lock_tests +test.__main__ +test.make_ssl_certs +test.mapping_tests +test.memory_watchdog +test.mock_socket +test.mod_generics_cache +test.mp_fork_bomb +test.mp_preload +test.multibytecodec_support +_testmultiphase +test.outstanding_bugs +test.pickletester +test.profilee +test.pyclbr_input +test.pydocfodder +test.pydoc_mod +test.pythoninfo +test.regrtest +test.relimport +test.reperf +test.re_tests +test.sample_doctest +test.sample_doctest_no_docstrings +test.sample_doctest_no_doctests +test.seq_tests +test.signalinterproctester +test.sortperf +test.ssl_servers +test.ssltests +test.string_tests +test.subprocessdata.fd_status +test.subprocessdata.input_reader +test.subprocessdata.qcat +test.subprocessdata.qgrep +test.subprocessdata.sigchild_ignore test.support +test.support.bytecode_helper +test.support.hashlib_helper +test.support.logging_helper +test.support.script_helper +test.support.socket_helper +test.support.testresult +test.test_abc +test.test_abstract_numbers +test.test_aifc +test.test___all__ +test.test_argparse +test.test_array +test.test_asdl_parser +test.test_ast +test.test_asyncgen +test.test_asynchat +test.test_asyncio +test.test_asyncio.echo +test.test_asyncio.echo2 +test.test_asyncio.echo3 +test.test_asyncio.functional +test.test_asyncio.__main__ +test.test_asyncio.test_base_events +test.test_asyncio.test_buffered_proto +test.test_asyncio.test_context +test.test_asyncio.test_events +test.test_asyncio.test_futures +test.test_asyncio.test_locks +test.test_asyncio.test_pep492 +test.test_asyncio.test_proactor_events +test.test_asyncio.test_protocols +test.test_asyncio.test_queues +test.test_asyncio.test_runners +test.test_asyncio.test_selector_events +test.test_asyncio.test_sendfile +test.test_asyncio.test_server +test.test_asyncio.test_sock_lowlevel +test.test_asyncio.test_sslproto +test.test_asyncio.test_streams +test.test_asyncio.test_subprocess +test.test_asyncio.test_tasks +test.test_asyncio.test_transports +test.test_asyncio.test_unix_events +test.test_asyncio.test_windows_events +test.test_asyncio.test_windows_utils +test.test_asyncio.utils +test.test_asyncore +test.test_atexit +test.test_audioop +test.test_audit +test.test_augassign +test.test_base64 +test.test_baseexception +test.test_bdb +test.test_bigaddrspace +test.test_bigmem +test.test_binascii +test.test_binhex +test.test_binop +test.test_bisect +test.test_bool +test.test_buffer +test.test_bufio +test.test_builtin +test.test_bytes +test.test_bz2 +test.test_calendar +test.test_call +test.test_capi +test.test_cgi +test.test_cgitb +test.test_charmapcodec +test.test_class +test.test_clinic +test.test_c_locale_coercion +test.test_cmath +test.test_cmd +test.test_cmd_line +test.test_cmd_line_script +test.test_code +test.testcodec +test.test_codeccallbacks +test.test_codecencodings_cn +test.test_codecencodings_hk +test.test_codecencodings_iso2022 +test.test_codecencodings_jp +test.test_codecencodings_kr +test.test_codecencodings_tw +test.test_codecmaps_cn +test.test_codecmaps_hk +test.test_codecmaps_jp +test.test_codecmaps_kr +test.test_codecmaps_tw +test.test_codecs +test.test_code_module +test.test_codeop +test.test_collections +test.test_colorsys +test.test_compare +test.test_compile +test.test_compileall +test.test_complex +test.test_concurrent_futures +test.test_configparser +test.test_contains +test.test_context +test.test_contextlib +test.test_contextlib_async +test.test_copy +test.test_copyreg +test.test_coroutines +test.test_cprofile +test.test_crashers +test.test_crypt +test.test_csv +test.test_ctypes +test.test_curses +test.test_dataclasses +test.test_datetime +test.test_dbm +test.test_dbm_dumb +test.test_dbm_gnu +test.test_dbm_ndbm +test.test_decimal +test.test_decorators +test.test_defaultdict +test.test_deque +test.test_descr +test.test_descrtut +test.test_devpoll +test.test_dict +test.test_dictcomps +test.test_dict_version +test.test_dictviews +test.test_difflib +test.test_dis +test.test_distutils +test.test_doctest +test.test_doctest2 +test.test_docxmlrpc +test.test_dtrace +test.test_dummy_thread +test.test_dummy_threading +test.test_dynamic +test.test_dynamicclassattribute +test.test_eintr +test.test_email +test.test_email.__main__ +test.test_email.test_asian_codecs +test.test_email.test_contentmanager +test.test_email.test_defect_handling +test.test_email.test_email +test.test_email.test__encoded_words +test.test_email.test_generator +test.test_email.test_headerregistry +test.test_email.test__header_value_parser +test.test_email.test_inversion +test.test_email.test_message +test.test_email.test_parser +test.test_email.test_pickleable +test.test_email.test_policy +test.test_email.test_utils +test.test_email.torture_test +test.test_embed +test.test_ensurepip +test.test_enum +test.test_enumerate +test.test_eof +test.test_epoll +test.test_errno +test.test_exception_hierarchy +test.test_exceptions +test.test_exception_variations +test.test_extcall +test.test_faulthandler +test.test_fcntl +test.test_file +test.test_filecmp +test.test_file_eintr +test.test_fileinput +test.test_fileio +test.test_finalization +test.test_float +test.test_flufl +test.test_fnmatch +test.test_fork1 +test.test_format +test.test_fractions +test.test_frame +test.test_frozen +test.test_fstring +test.test_ftplib +test.test_funcattrs +test.test_functools +test.test___future__ +test.test_future +test.test_future3 +test.test_future4 +test.test_future5 +test.test_gc +test.test_gdb +test.test_generators +test.test_generator_stop +test.test_genericclass +test.test_genericpath +test.test_genexps +test.test_getargs2 +test.test_getopt +test.test_getpass +test.test_gettext +test.test_glob +test.test_global +test.test_grammar +test.test_grp +test.test_gzip +test.test_hash +test.test_hashlib +test.test_heapq +test.test_hmac +test.test_html +test.test_htmlparser +test.test_http_cookiejar +test.test_http_cookies +test.test_httplib +test.test_httpservers +test.test_idle +test.test_imaplib +test.test_imghdr +test.test_imp +test.test_import +test.test_import.data.circular_imports.basic +test.test_import.data.circular_imports.basic2 +test.test_import.data.circular_imports.binding +test.test_import.data.circular_imports.binding2 +test.test_import.data.circular_imports.from_cycle1 +test.test_import.data.circular_imports.from_cycle2 +test.test_import.data.circular_imports.indirect +test.test_import.data.circular_imports.rebinding +test.test_import.data.circular_imports.rebinding2 +test.test_import.data.circular_imports.source +test.test_import.data.circular_imports.subpackage +test.test_import.data.circular_imports.subpkg.subpackage2 +test.test_import.data.circular_imports.subpkg.util +test.test_import.data.circular_imports.use +test.test_import.data.circular_imports.util +test.test_import.data.package +test.test_import.data.package2.submodule1 +test.test_import.data.package2.submodule2 +test.test_import.data.package.submodule +test.test_importlib +test.test_importlib.abc +test.test_importlib.builtin +test.test_importlib.builtin.__main__ +test.test_importlib.builtin.test_finder +test.test_importlib.builtin.test_loader +test.test_importlib.data +test.test_importlib.data01 +test.test_importlib.data01.subdirectory +test.test_importlib.data02 +test.test_importlib.data02.one +test.test_importlib.data02.two +test.test_importlib.data03 +test.test_importlib.data03.namespace.portion1 +test.test_importlib.data03.namespace.portion2 +test.test_importlib.extension +test.test_importlib.extension.__main__ +test.test_importlib.extension.test_case_sensitivity +test.test_importlib.extension.test_finder +test.test_importlib.extension.test_loader +test.test_importlib.extension.test_path_hook +test.test_importlib.fixtures +test.test_importlib.frozen +test.test_importlib.frozen.__main__ +test.test_importlib.frozen.test_finder +test.test_importlib.frozen.test_loader +test.test_importlib.import_ +test.test_importlib.import_.__main__ +test.test_importlib.import_.test_api +test.test_importlib.import_.test_caching +test.test_importlib.import_.test_fromlist +test.test_importlib.import_.test___loader__ +test.test_importlib.import_.test_meta_path +test.test_importlib.import_.test___package__ +test.test_importlib.import_.test_packages +test.test_importlib.import_.test_path +test.test_importlib.import_.test_relative_imports +test.test_importlib.__main__ +test.test_importlib.namespace_pkgs.both_portions.foo.one +test.test_importlib.namespace_pkgs.both_portions.foo.two +test.test_importlib.namespace_pkgs.module_and_namespace_package.a_test +test.test_importlib.namespace_pkgs.not_a_namespace_pkg.foo +test.test_importlib.namespace_pkgs.not_a_namespace_pkg.foo.one +test.test_importlib.namespace_pkgs.portion1.foo.one +test.test_importlib.namespace_pkgs.portion2.foo.two +test.test_importlib.namespace_pkgs.project1.parent.child.one +test.test_importlib.namespace_pkgs.project2.parent.child.two +test.test_importlib.namespace_pkgs.project3.parent.child.three +test.test_importlib.source +test.test_importlib.source.__main__ +test.test_importlib.source.test_case_sensitivity +test.test_importlib.source.test_file_loader +test.test_importlib.source.test_finder +test.test_importlib.source.test_path_hook +test.test_importlib.source.test_source_encoding +test.test_importlib.test_abc +test.test_importlib.test_api +test.test_importlib.test_lazy +test.test_importlib.test_locks +test.test_importlib.test_main +test.test_importlib.test_metadata_api +test.test_importlib.test_namespace_pkgs +test.test_importlib.test_open +test.test_importlib.test_path +test.test_importlib.test_read +test.test_importlib.test_resource +test.test_importlib.test_spec +test.test_importlib.test_util +test.test_importlib.test_windows +test.test_importlib.test_zip +test.test_importlib.util +test.test_importlib.zipdata01 +test.test_importlib.zipdata02 +test.test_import.__main__ +test.test_index +test.test_inspect +test.test_int +test.test_int_literal +test.test_io +test.test_ioctl +test.test_ipaddress +test.test_isinstance +test.test_iter +test.test_iterlen +test.test_itertools +test.test_json +test.test_json.__main__ +test.test_json.test_decode +test.test_json.test_default +test.test_json.test_dump +test.test_json.test_encode_basestring_ascii +test.test_json.test_enum +test.test_json.test_fail +test.test_json.test_float +test.test_json.test_indent +test.test_json.test_pass1 +test.test_json.test_pass2 +test.test_json.test_pass3 +test.test_json.test_recursion +test.test_json.test_scanstring +test.test_json.test_separators +test.test_json.test_speedups +test.test_json.test_tool +test.test_json.test_unicode +test.test_keyword +test.test_keywordonlyarg +test.test_kqueue +test.test_largefile +test.test_lib2to3 +test.test_linecache +test.test_list +test.test_listcomps +test.test_lltrace +test.test__locale +test.test_locale +test.test_logging +test.test_long +test.test_longexp +test.test_lzma +test.test_mailbox +test.test_mailcap +test.test_marshal +test.test_math +test.test_memoryio +test.test_memoryview +test.test_metaclass +test.test_mimetypes +test.test_minidom +test.test_mmap +test.test_module +test.test_modulefinder +test.test_msilib +test.test_multibytecodec +test._test_multiprocessing +test.test_multiprocessing_fork +test.test_multiprocessing_forkserver +test.test_multiprocessing_main_handling +test.test_multiprocessing_spawn +test.test_named_expressions +test.test_netrc +test.test_nis +test.test_nntplib +test.test_normalization +test.test_ntpath +test.test_numeric_tower +test.test__opcode +test.test_opcodes +test.test_openpty +test.test_operator +test.test_optparse +test.test_ordered_dict +test.test_os +test.test_ossaudiodev +test.test_osx_env +test.test__osx_support +test.test_parser +test.test_pathlib +test.test_pdb +test.test_peepholer +test.test_pickle +test.test_picklebuffer +test.test_pickletools +test.test_pipes +test.test_pkg +test.test_pkgimport +test.test_pkgutil +test.test_platform +test.test_plistlib +test.test_poll +test.test_popen +test.test_poplib +test.test_positional_only_arg +test.test_posix +test.test_posixpath +test.test_pow +test.test_pprint +test.test_print +test.test_profile +test.test_property +test.test_pstats +test.test_pty +test.test_pulldom +test.test_pwd +test.test_pyclbr +test.test_py_compile +test.test_pydoc +test.test_pyexpat +test.test_queue +test.test_quopri +test.test_raise +test.test_random +test.test_range +test.test_re +test.test_readline +test.test_regrtest +test.test_repl +test.test_reprlib +test.test_resource +test.test_richcmp +test.test_rlcompleter +test.test_robotparser +test.test_runpy +test.test_sax +test.test_sched +test.test_scope +test.test_script_helper +test.test_secrets +test.test_select +test.test_selectors +test.test_set +test.test_setcomps +test.test_shelve +test.test_shlex +test.test_shutil +test.test_signal +test.test_site +test.test_slice +test.test_smtpd +test.test_smtplib +test.test_smtpnet +test.test_sndhdr +test.test_socket +test.test_socketserver +test.test_sort +test.test_source_encoding +test.test_spwd +test.test_sqlite +test.test_ssl +test.test_startfile +test.test_stat +test.test_statistics +test.test_strftime +test.test_string +test.test_string_literals +test.test_stringprep +test.test_strptime +test.test_strtod +test.test_struct +test.test_structmembers +test.test_structseq +test.test_subclassinit +test.test_subprocess +test.test_sunau +test.test_sundry +test.test_super test.test_support +test.test_symbol +test.test_symtable +test.test_syntax +test.test_sys +test.test_sysconfig +test.test_syslog +test.test_sys_setprofile +test.test_sys_settrace +test.test_tabnanny +test.test_tarfile +test.test_tcl +test.test_telnetlib +test.test_tempfile +test.test_textwrap +test.test_thread +test.test_threaded_import +test.test_threadedtempfile +test.test_threading +test.test_threading_local +test.test_threadsignals +test.test_time +test.test_timeit +test.test_timeout +test.test_tix +test.test_tk +test.test_tokenize +test.test_tools +test.test_tools.__main__ +test.test_tools.test_fixcid +test.test_tools.test_gprof2html +test.test_tools.test_i18n +test.test_tools.test_lll +test.test_tools.test_md5sum +test.test_tools.test_pathfix +test.test_tools.test_pdeps +test.test_tools.test_pindent +test.test_tools.test_reindent +test.test_tools.test_sundry +test.test_tools.test_unparse +test.test_trace +test.test_traceback +test.test_tracemalloc +test.test_ttk_guionly +test.test_ttk_textonly +test.test_tuple +test.test_turtle +test.test_typechecks +test.test_type_comments +test.test_types +test.test_typing +test.test_ucn +test.test_unary +test.test_unicode +test.test_unicodedata +test.test_unicode_file +test.test_unicode_file_functions +test.test_unicode_identifiers +test.test_unittest +test.test_univnewlines +test.test_unpack +test.test_unpack_ex +test.test_urllib +test.test_urllib2 +test.test_urllib2_localnet +test.test_urllib2net +test.test_urllibnet +test.test_urllib_response +test.test_urlparse +test.test_userdict +test.test_userlist +test.test_userstring +test.test_utf8_mode +test.test_utf8source +test.test_uu +test.test_uuid +test.test_venv +test.test_wait3 +test.test_wait4 +test.test_warnings +test.test_warnings.data.import_warning +test.test_warnings.data.stacklevel +test.test_warnings.__main__ +test.test_wave +test.test_weakref +test.test_weakset +test.test_webbrowser +test.test_winconsoleio +test.test_winreg +test.test_winsound +test.test_with +test.test_wsgiref +test.test_xdrlib +test.test_xml_dom_minicompat +test.test_xml_etree +test.test_xml_etree_c +test.test_xmlrpc +test.test_xmlrpc_net +test.test__xxsubinterpreters +test.test_xxtestfuzz +test.test_yield_from +test.test_zipapp +test.test_zipfile +test.test_zipfile64 +test.test_zipimport +test.test_zipimport_support +test.test_zlib +test.tf_inherit_check +test.threaded_import_hangers +test.time_hashlib +test.tracedmodules +test.tracedmodules.testmod +test.win_console_handler +test.xmltests +test.ziptestdata.testdata_module_inside_zip textwrap -thread +this +_thread threading +_threading_local time timeit -Tix -Tkinter +_tkinter tkinter +tkinter.colorchooser +tkinter.commondialog +tkinter.constants +tkinter.dialog +tkinter.dnd +tkinter.filedialog +tkinter.font +tkinter.__main__ +tkinter.messagebox tkinter.scrolledtext +tkinter.simpledialog +tkinter.test +tkinter.test.runtktests +tkinter.test.support +tkinter.test.test_tkinter +tkinter.test.test_tkinter.test_font +tkinter.test.test_tkinter.test_geometry_managers +tkinter.test.test_tkinter.test_images +tkinter.test.test_tkinter.test_loadtk +tkinter.test.test_tkinter.test_misc +tkinter.test.test_tkinter.test_text +tkinter.test.test_tkinter.test_variables +tkinter.test.test_tkinter.test_widgets +tkinter.test.test_ttk +tkinter.test.test_ttk.test_extensions +tkinter.test.test_ttk.test_functions +tkinter.test.test_ttk.test_style +tkinter.test.test_ttk.test_widgets +tkinter.test.widget_tests tkinter.tix tkinter.ttk token tokenize trace traceback +_tracemalloc tracemalloc -ttk tty turtle turtledemo +turtledemo.bytedesign +turtledemo.chaos +turtledemo.clock +turtledemo.colormixer +turtledemo.forest +turtledemo.fractalcurves +turtledemo.lindenmayer +turtledemo.__main__ +turtledemo.minimal_hanoi +turtledemo.nim +turtledemo.paint +turtledemo.peace +turtledemo.penrose +turtledemo.planet_and_moon +turtledemo.rosette +turtledemo.round_dance +turtledemo.sorting_animate +turtledemo.tree +turtledemo.two_canvases +turtledemo.yinyang types typing +typing.io +typing.re unicodedata unittest +unittest.async_case +unittest.case +unittest.loader +unittest._log +unittest.__main__ +unittest.main unittest.mock +unittest.result +unittest.runner +unittest.signals +unittest.suite +unittest.test +unittest.test.dummy +unittest.test.__main__ +unittest.test.support +unittest.test.test_assertions +unittest.test.test_async_case +unittest.test.test_break +unittest.test.test_case +unittest.test.test_discovery +unittest.test.test_functiontestcase +unittest.test.test_loader +unittest.test.testmock +unittest.test.testmock.__main__ +unittest.test.testmock.support +unittest.test.testmock.testasync +unittest.test.testmock.testcallable +unittest.test.testmock.testhelpers +unittest.test.testmock.testmagicmethods +unittest.test.testmock.testmock +unittest.test.testmock.testpatch +unittest.test.testmock.testsealable +unittest.test.testmock.testsentinel +unittest.test.testmock.testwith +unittest.test.test_program +unittest.test.test_result +unittest.test.test_runner +unittest.test.test_setups +unittest.test.test_skipping +unittest.test.test_suite +unittest.test._test_warnings +unittest.util urllib urllib.error urllib.parse urllib.request urllib.response urllib.robotparser -urllib2 -urlparse -user -UserDict -UserList -UserString uu +_uuid uuid venv -videoreader -W +venv.__main__ +_warnings warnings wave +_weakref weakref +_weakrefset webbrowser -whichdb winreg winsound wsgiref @@ -474,22 +1746,40 @@ wsgiref.validate xdrlib xml xml.dom +xml.dom.domreg +xml.dom.expatbuilder +xml.dom.minicompat xml.dom.minidom +xml.dom.NodeFilter xml.dom.pulldom +xml.dom.xmlbuilder +xml.etree +xml.etree.cElementTree +xml.etree.ElementInclude +xml.etree.ElementPath xml.etree.ElementTree +xml.parsers xml.parsers.expat xml.parsers.expat.errors xml.parsers.expat.model -xml.sax -xml.sax.handler -xml.sax.saxutils -xml.sax.xmlreader xmlrpc xmlrpc.client xmlrpc.server -xmlrpclib -yp +xml.sax +xml.sax._exceptions +xml.sax.expatreader +xml.sax.handler +xml.sax.saxutils +xml.sax.xmlreader +xxlimited +_xxsubinterpreters +xxsubtype +_xxtestfuzz zipapp zipfile zipimport zlib +zoneinfo +zoneinfo._common +zoneinfo._tzpath +zoneinfo._zoneinfo diff --git a/setup.py b/setup.py index 1afa42f..f119905 100755 --- a/setup.py +++ b/setup.py @@ -1,6 +1,4 @@ #!/usr/bin/env python -# -*- coding: utf-8 -*- - try: from setuptools import setup @@ -34,7 +32,7 @@ setup( package_dir={'pipreqs': 'pipreqs'}, include_package_data=True, - package_data={'': ['stdlib','mapping']}, + package_data={'': ['stdlib', 'mapping']}, install_requires=requirements, license='Apache License', zip_safe=False, @@ -44,12 +42,11 @@ setup( 'Intended Audience :: Developers', 'License :: OSI Approved :: Apache Software License', 'Natural Language :: English', - 'Programming Language :: Python :: 2', - 'Programming Language :: Python :: 2.7', 'Programming Language :: Python :: 3', - 'Programming Language :: Python :: 3.4', - 'Programming Language :: Python :: 3.5', 'Programming Language :: Python :: 3.6', + 'Programming Language :: Python :: 3.7', + 'Programming Language :: Python :: 3.8', + 'Programming Language :: Python :: 3.9', ], test_suite='tests', entry_points={ diff --git a/tests/_data/test.py b/tests/_data/test.py index cfd039c..fdb6ec3 100644 --- a/tests/_data/test.py +++ b/tests/_data/test.py @@ -31,6 +31,10 @@ 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 diff --git a/tests/_data_clean/test.py b/tests/_data_clean/test.py new file mode 100644 index 0000000..8cffb51 --- /dev/null +++ b/tests/_data_clean/test.py @@ -0,0 +1,65 @@ +"""unused import""" +# pylint: disable=undefined-all-variable, import-error, no-absolute-import, too-few-public-methods, missing-docstring +import xml.etree # [unused-import] +import xml.sax # [unused-import] +import os.path as test # [unused-import] +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 +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 + +# 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 +except ImportError: + import json + +import models + + +def main(): + pass + +import after_method_is_valid_even_if_not_pep8 diff --git a/tests/test_pipreqs.py b/tests/test_pipreqs.py old mode 100755 new mode 100644 index dcd75c5..f82d3db --- a/tests/test_pipreqs.py +++ b/tests/test_pipreqs.py @@ -18,22 +18,40 @@ from pipreqs import pipreqs class TestPipreqs(unittest.TestCase): def setUp(self): - self.modules = ['flask', 'requests', 'sqlalchemy', - 'docopt', 'boto', 'ipython', 'pyflakes', 'nose', - 'peewee', 'ujson', 'nonexistendmodule', 'bs4', 'after_method_is_valid_even_if_not_pep8' ] + 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'] self.project = os.path.join(os.path.dirname(__file__), "_data") - self.project_invalid = os.path.join(os.path.dirname(__file__), "_invalid_data") - self.project_with_ignore_directory = os.path.join(os.path.dirname(__file__), "_data_ignore") - self.project_with_duplicated_deps = os.path.join(os.path.dirname(__file__), "_data_duplicated_deps") + self.project_clean = os.path.join( + os.path.dirname(__file__), + "_data_clean" + ) + self.project_invalid = os.path.join( + os.path.dirname(__file__), + "_invalid_data" + ) + self.project_with_ignore_directory = os.path.join( + os.path.dirname(__file__), + "_data_ignore" + ) + self.project_with_duplicated_deps = os.path.join( + 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), 13) + self.assertEqual(len(imports), 15) for item in imports: self.assertTrue( item.lower() in self.modules, "Import is missing: " + item) @@ -54,7 +72,8 @@ class TestPipreqs(unittest.TestCase): """ Test that invalid python files cannot be imported. """ - self.assertRaises(SyntaxError, pipreqs.get_all_imports, self.project_invalid) + self.assertRaises( + SyntaxError, pipreqs.get_all_imports, self.project_invalid) def test_get_imports_info(self): """ @@ -62,8 +81,9 @@ class TestPipreqs(unittest.TestCase): """ imports = pipreqs.get_all_imports(self.project) with_info = pipreqs.get_imports_info(imports) - # Should contain 10 items without the "nonexistendmodule" and "after_method_is_valid_even_if_not_pep8" - self.assertEqual(len(with_info), 11) + # Should contain 10 items without the "nonexistendmodule" and + # "after_method_is_valid_even_if_not_pep8" + self.assertEqual(len(with_info), 13) for item in with_info: self.assertTrue( item['name'].lower() in self.modules, @@ -77,10 +97,12 @@ class TestPipreqs(unittest.TestCase): def test_get_use_local_only(self): """ - Test without checking PyPI, check to see if names of local imports matches what we expect + Test without checking PyPI, check to see if names of local + imports matches what we expect - Note even though pyflakes isn't in requirements.txt, - It's added to locals since it is a development dependency for testing + It's added to locals since it is a development dependency + for testing """ # should find only docopt and requests imports_with_info = pipreqs.get_import_local(self.modules) @@ -89,24 +111,28 @@ class TestPipreqs(unittest.TestCase): def test_init(self): """ - Test that all modules we will test upon, are in requirements file + Test that all modules we will test upon are in requirements file """ pipreqs.init({'': self.project, '--savepath': None, '--print': False, '--use-local': None, '--force': True, '--proxy':None, '--pypi-server':None, - '--diff': None, '--clean': None}) + '--diff': None, '--clean': None, '--mode': None}) assert os.path.exists(self.requirements_path) == 1 with open(self.requirements_path, "r") as f: data = f.read().lower() for item in self.modules[:-3]: self.assertTrue(item.lower() in data) + # It should be sorted based on names. + data = data.strip().split('\n') + self.assertEqual(data, sorted(data)) def test_init_local_only(self): """ - Test that items listed in requirements.text are the same as locals expected + Test that items listed in requirements.text are the same + as locals expected """ pipreqs.init({'': self.project, '--savepath': None, '--print': False, '--use-local': True, '--force': True, '--proxy':None, '--pypi-server':None, - '--diff': None, '--clean': None}) + '--diff': None, '--clean': None, '--mode': None}) assert os.path.exists(self.requirements_path) == 1 with open(self.requirements_path, "r") as f: data = f.readlines() @@ -116,11 +142,12 @@ class TestPipreqs(unittest.TestCase): def test_init_savepath(self): """ - Test that we can save requiremnts.tt correctly to a different path + Test that we can save requirements.txt correctly + to a different path """ - pipreqs.init({'': self.project, '--savepath': - self.alt_requirement_path, '--use-local': None, '--proxy':None, '--pypi-server':None, '--print': False, - "--diff": None, "--clean": None}) + pipreqs.init({'': self.project, '--savepath': self.alt_requirement_path, + '--use-local': None, '--proxy':None, '--pypi-server':None, '--print': False, + '--diff': None, '--clean': None, '--mode': None}) assert os.path.exists(self.alt_requirement_path) == 1 with open(self.alt_requirement_path, "r") as f: data = f.read().lower() @@ -131,13 +158,14 @@ class TestPipreqs(unittest.TestCase): def test_init_overwrite(self): """ - Test that if requiremnts.txt exists, it will not automatically be overwritten + Test that if requiremnts.txt exists, it will not be + automatically overwritten """ with open(self.requirements_path, "w") as f: f.write("should_not_be_overwritten") - pipreqs.init({'': self.project, '--savepath': None, - '--use-local': None, '--force': None, '--proxy':None, '--pypi-server':None, '--print': False, - "--diff": None, "--clean": None}) + pipreqs.init({'': self.project, '--savepath': None, '--use-local': None, + '--force': None, '--proxy':None, '--pypi-server':None, '--print': False, + '--diff': None, '--clean': None, '--mode': None}) assert os.path.exists(self.requirements_path) == 1 with open(self.requirements_path, "r") as f: data = f.read().lower() @@ -145,35 +173,43 @@ class TestPipreqs(unittest.TestCase): def test_get_import_name_without_alias(self): """ - Test that function get_name_without_alias() will work on a string. - - Note: This isn't truly needed when pipreqs is walking the AST to find imports + Test that function get_name_without_alias() + will work on a string. + - Note: This isn't truly needed when pipreqs is walking + the AST to find imports """ 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) 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): """ Test that trying to get a custom pypi sever fails correctly """ - self.assertRaises(requests.exceptions.MissingSchema, pipreqs.init, {'': self.project, '--savepath': None, '--print': False, - '--use-local': None, '--force': True, '--proxy': None, '--pypi-server': 'nonexistent'}) + self.assertRaises( + requests.exceptions.MissingSchema, pipreqs.init, + {'': self.project, '--savepath': None, '--print': False, + '--use-local': None, '--force': True, '--proxy': None, + '--pypi-server': 'nonexistent'} + ) def test_ignored_directory(self): """ Test --ignore parameter """ pipreqs.init( - {'': self.project_with_ignore_directory, '--savepath': None, '--print': False, - '--use-local': None, '--force': True, - '--proxy':None, - '--pypi-server':None, + {'': self.project_with_ignore_directory, '--savepath': None, + '--print': False, '--use-local': None, '--force': True, + '--proxy':None, '--pypi-server':None, '--ignore':'.ignored_dir,.ignore_second', '--diff': None, - '--clean': None + '--clean': None, + '--mode': None } ) with open(os.path.join(self.project_with_ignore_directory, "requirements.txt"), "r") as f: @@ -181,9 +217,27 @@ class TestPipreqs(unittest.TestCase): for item in ['click', 'getpass']: self.assertFalse(item.lower() in data) - def test_omit_version(self): + def test_dynamic_version_no_pin_scheme(self): """ - Test --no-pin parameter + Test --mode=no-pin + """ + pipreqs.init( + {'': self.project_with_ignore_directory, '--savepath': None, + '--print': False, '--use-local': None, '--force': True, + '--proxy': None, '--pypi-server': None, + '--diff': None, + '--clean': None, + '--mode': 'no-pin' + } + ) + with open(os.path.join(self.project_with_ignore_directory, "requirements.txt"), "r") as f: + data = f.read().lower() + for item in ['beautifulsoup4', 'boto']: + self.assertTrue(item.lower() in data) + + def test_dynamic_version_gt_scheme(self): + """ + Test --mode=gt """ pipreqs.init( {'': self.project_with_ignore_directory, '--savepath': None, '--print': False, @@ -192,13 +246,81 @@ class TestPipreqs(unittest.TestCase): '--pypi-server': None, '--diff': None, '--clean': None, - '--no-pin': True + '--mode': 'gt' } ) 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' + self.assertIn(symbol, item, message) + + def test_dynamic_version_compat_scheme(self): + """ + Test --mode=compat + """ + pipreqs.init( + {'': self.project_with_ignore_directory, '--savepath': None, '--print': False, + '--use-local': None, '--force': True, + '--proxy': None, + '--pypi-server': None, + '--diff': None, + '--clean': None, + '--mode': 'compat' + } + ) + 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' + self.assertIn(symbol, item, message) + + def test_clean(self): + """ + Test --clean parameter + """ + pipreqs.init( + {'': self.project, '--savepath': None, '--print': False, + '--use-local': None, '--force': True, '--proxy': None, + '--pypi-server': None, '--diff': None, '--clean': None, + '--mode': None} + ) + assert os.path.exists(self.requirements_path) == 1 + pipreqs.init( + {'': self.project, '--savepath': None, '--print': False, + '--use-local': None, '--force': None, '--proxy': None, + '--pypi-server': None, '--diff': None, + '--clean': self.requirements_path, '--mode': 'non-pin'} + ) + with open(self.requirements_path, "r") as f: data = f.read().lower() - for item in ['beautifulsoup4==4.8.1', 'boto==2.49.0']: - self.assertFalse(item.lower() in data) + for item in self.modules[:-3]: + self.assertTrue(item.lower() in data) + + def test_clean_with_imports_to_clean(self): + """ + Test --clean parameter when there are imports to clean + """ + cleaned_module = 'sqlalchemy' + pipreqs.init( + {'': self.project, '--savepath': None, '--print': False, + '--use-local': None, '--force': True, '--proxy': None, + '--pypi-server': None, '--diff': None, '--clean': None, + '--mode': None} + ) + assert os.path.exists(self.requirements_path) == 1 + modules_clean = [m for m in self.modules if m != cleaned_module] + pipreqs.init( + {'': self.project_clean, '--savepath': None, + '--print': False, '--use-local': None, '--force': None, + '--proxy': None, '--pypi-server': None, '--diff': None, + '--clean': self.requirements_path, '--mode': 'non-pin'} + ) + with open(self.requirements_path, "r") as f: + data = f.read().lower() + self.assertTrue(cleaned_module not in data) def tearDown(self): """ diff --git a/tox.ini b/tox.ini index 28a1dfa..cf5c2c2 100644 --- a/tox.ini +++ b/tox.ini @@ -1,16 +1,17 @@ [tox] -envlist = py27, py34, py35, py36, pypy, flake8 +envlist = py36, py37, py38, py39, pypy3, flake8 + +[gh-actions] +python = + 3.6: py36 + 3.7: py37 + 3.8: py38 + 3.9: py39 + pypy-3.7: pypy3 [testenv] setenv = PYTHONPATH = {toxinidir}:{toxinidir}/pipreqs commands = python setup.py test deps = - -r{toxinidir}/requirements.txt - -[testenv:flake8] -basepython = python3.6 -commands = flake8 pipreqs -deps = - -r{toxinidir}/requirements.txt - flake8 + -r{toxinidir}/requirements.txt \ No newline at end of file