Giter Site home page Giter Site logo

alanhamlett / pip-update-requirements Goto Github PK

View Code? Open in Web Editor NEW
595.0 11.0 22.0 4.39 MB

Update the packages in a requirements.txt file.

Home Page: https://pypi.python.org/pypi/pur

License: Other

Python 99.99% Makefile 0.01%
python pip dependency-manager

pip-update-requirements's Introduction

Tests Coverage Version Supported Python Versions WakaTime

pip-update-requirements

Update the packages in a requirements.txt file.

Purring Cat

Installation

pip install pur

Usage

Give pur your requirements.txt file and it updates all your packages to the latest versions.

For example, given a requirements.txt file:

flask==0.9
sqlalchemy==0.9.10
alembic==0.8.4

Running pur on that file updates the packages to current latest versions:

$ pur -r requirements.txt
Updated flask: 0.9 -> 1.0.2
Updated sqlalchemy: 0.9.10 -> 1.2.8
Updated alembic: 0.8.4 -> 0.9.9
All requirements up-to-date.

Pur never modifies your environment or installed packages, it only modifies your requirements.txt file.

You can also use Pur directly from Python:

$ python
Python 3.6.1
>>> from pur import update_requirements
>>> print([x[0]['message'] for x in update_requirements(input_file='requirements.txt').values()])
['Updated flask: 0.9 -> 1.0.2', 'Updated sqlalchemy: 0.9.10 -> 1.2.8', 'Updated alembic: 0.8.4 -> 0.9.9']
>>> print(open('requirements.txt').read())
flask==1.0.2
sqlalchemy==1.2.8
alembic==0.9.9

Options

-r, --requirement PATH   The requirements.txt file to update; Defaults to
                         using requirements.txt from the current directory
                         if it exist.
-o, --output PATH        Output updated packages to this file; Defaults to
                         overwriting the input requirements.txt file.
--interactive            Interactively prompts before updating each package.
-f, --force              Force updating packages even when a package has no
                         version specified in the input requirements.txt
                         file.
-d, --dry-run            Output changes to STDOUT instead of overwriting the
                         requirements.txt file.
--dry-run-changed        Enable dry run and only output packages with
                         updates, not packages that are already the latest.
-n, --no-recursive       Prevents updating nested requirements files.
--skip TEXT              Comma separated list of packages to skip updating.
--skip-gt                Skip updating packages using > or >= spec, to allow
                         specifying minimum supported versions of packages.
--index-url TEXT         Base URL of the Python Package Index. Can be
                         provided multiple times for extra index urls.
--cert PATH              Path to PEM-encoded CA certificate bundle. If
                         provided, overrides the default.
--no-ssl-verify          Disable verifying the server's TLS certificate.
--only TEXT              Comma separated list of packages. Only these
                         packages will be updated.
--minor TEXT             Comma separated list of packages to only update
                         minor versions, never major. Use "*" to limit every
                         package to minor version updates.
--patch TEXT             Comma separated list of packages to only update
                         patch versions, never major or minor. Use "*" to
                         limit every package to patch version updates.
--pre TEXT               Comma separated list of packages to allow updating
                         to pre-release versions. Use "*" to allow all
                         packages to be updated to pre-release versions. By
                         default packages are only updated to stable
                         versions.
-z, --nonzero-exit-code  Exit with status 1 when some packages were updated,
                         0 when no packages updated, or a number greater
                         than 1 when there was an error. By default, exit
                         status 0 is used unless there was an error
                         irregardless of whether packages were or not
                         updated.
--version                Show the version and exit.
--help                   Show this message and exit.

Contributing

Before contributing a pull request, make sure tests pass:

virtualenv venv
. venv/bin/activate
pip install tox
tox

Many thanks to all contributors!

pip-update-requirements's People

Contributors

alanhamlett avatar davegallant avatar lancelote avatar roaldnefs avatar svuk avatar tomdottom avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

pip-update-requirements's Issues

Recently stopped working

pip3 list --outdated provides plenty packages that need to be updated

Package           Version Latest Type 
----------------- ------- ------ -----
gunicorn          19.8.1  19.9.0 wheel
pandas            0.23.1  0.23.3 wheel
plotly            2.7.0   3.1.0  sdist

pur -r requirements.txt
Output: All requirements up-to-date.
Which is not correct

requirements.txt content example:

gunicorn==19.8.1
pandas==0.23.1
plotly==2.7.0

urllib3 dependency is missing

What it says in the title. If i install pur in python3.10 using pip, i can't run it because it's missing urllib3.

pip install urllib3 fixes the issue.

Installation error

Hi,

I try to install pur using pip install pur in virtual env. Installation fails due to no requirements specified in setup.py. installation will works if I run "pip install -r requirements.txt" after downloading the pur package.

I think you could easyly fix this issue reading content of requirements.txt and use its content in setup.py requires variable.

Error running with Python 3.10: cannot import name 'Mapping' from 'collections'

Running pur -r requirements.txt with Python 3.10 environment raises

Traceback (most recent call last):
  File "/Users/.../.virtualenvs/test_pur_python310/bin/pur", line 5, in <module>
    from pur.__init__ import pur
  File "/Users/.../.virtualenvs/test_pur_python310/lib/python3.10/site-packages/pur/__init__.py", line 37, in <module>
    from pip._internal.index import PackageFinder
  File "/Users/.../.virtualenvs/test_pur_python310/lib/python3.10/site-packages/pur/packages/pip/_internal/__init__.py", line 40, in <module>
    from pip._internal.cli.autocompletion import autocomplete
  File "/Users/.../.virtualenvs/test_pur_python310/lib/python3.10/site-packages/pur/packages/pip/_internal/cli/autocompletion.py", line 8, in <module>
    from pip._internal.cli.main_parser import create_main_parser
  File "/Users/.../.virtualenvs/test_pur_python310/lib/python3.10/site-packages/pur/packages/pip/_internal/cli/main_parser.py", line 12, in <module>
    from pip._internal.commands import (
  File "/Users/.../.virtualenvs/test_pur_python310/lib/python3.10/site-packages/pur/packages/pip/_internal/commands/__init__.py", line 6, in <module>
    from pip._internal.commands.completion import CompletionCommand
  File "/Users/.../.virtualenvs/test_pur_python310/lib/python3.10/site-packages/pur/packages/pip/_internal/commands/completion.py", line 6, in <module>
    from pip._internal.cli.base_command import Command
  File "/Users/.../.virtualenvs/test_pur_python310/lib/python3.10/site-packages/pur/packages/pip/_internal/cli/base_command.py", line 24, in <module>
    from pip._internal.index import PackageFinder
  File "/Users/.../.virtualenvs/test_pur_python310/lib/python3.10/site-packages/pur/packages/pip/_internal/index.py", line 14, in <module>
    from pip._vendor import html5lib, requests, six
  File "/Users/.../.virtualenvs/test_pur_python310/lib/python3.10/site-packages/pur/packages/pip/_vendor/html5lib/__init__.py", line 25, in <module>
    from .html5parser import HTMLParser, parse, parseFragment
  File "/Users/.../.virtualenvs/test_pur_python310/lib/python3.10/site-packages/pur/packages/pip/_vendor/html5lib/html5parser.py", line 8, in <module>
    from . import _tokenizer
  File "/Users/.../.virtualenvs/test_pur_python310/lib/python3.10/site-packages/pur/packages/pip/_vendor/html5lib/_tokenizer.py", line 16, in <module>
    from ._trie import Trie
  File "/Users/.../.virtualenvs/test_pur_python310/lib/python3.10/site-packages/pur/packages/pip/_vendor/html5lib/_trie/__init__.py", line 3, in <module>
    from .py import Trie as PyTrie
  File "/Users/.../.virtualenvs/test_pur_python310/lib/python3.10/site-packages/pur/packages/pip/_vendor/html5lib/_trie/py.py", line 6, in <module>
    from ._base import Trie as ABCTrie
  File "/Users/.../.virtualenvs/test_pur_python310/lib/python3.10/site-packages/pur/packages/pip/_vendor/html5lib/_trie/_base.py", line 3, in <module>
    from collections import Mapping
ImportError: cannot import name 'Mapping' from 'collections' (/Library/Frameworks/Python.framework/Versions/3.10/lib/python3.10/collections/__init__.py)

The bundled version of html5lib is too old to be used with Python 3.10. The latest version doesn't have this problem. Should the vendored pip be upgraded? One can also directly patch vendored html5lib as a cheap fix.

Library doc

Is there any api reference or lib documentation? I would like to use pur programmatically instead of the cli

Invalid literal for int

Hi, awesome stuff.

Some findings...

pur -p "*" throws some error on Django, because there is a Django Version 1.8a1

Traceback (most recent call last):
  File "/devel/project/.venv/bin/pur", line 11, in <module>
    load_entry_point('pur==5.2.0', 'console_scripts', 'pur')()
  File "/devel/project/.venv/lib/python3.7/site-packages/click/core.py", line 764, in __call__
    return self.main(*args, **kwargs)
  File "/devel/project/.venv/lib/python3.7/site-packages/click/core.py", line 717, in main
    rv = self.invoke(ctx)
  File "/devel/project/.venv/lib/python3.7/site-packages/click/core.py", line 956, in invoke
    return ctx.invoke(self.callback, **ctx.params)
  File "/devel/project/.venv/lib/python3.7/site-packages/click/core.py", line 555, in invoke
    return callback(*args, **kwargs)
  File "/devel/project/.venv/lib/python3.7/site-packages/pur/__init__.py", line 119, in pur
    echo=options['echo'],
  File "/devel/project/.venv/lib/python3.7/site-packages/pur/__init__.py", line 178, in update_requirements
    echo=echo)
  File "/devel/project/.venv/lib/python3.7/site-packages/pur/__init__.py", line 207, in _internal_update_requirements
    for line, req, spec_ver, latest_ver in requirements:
  File "/devel/project/.venv/lib/python3.7/site-packages/pur/__init__.py", line 346, in _get_requirements_and_latest
    minor=minor, patch=patch, pre=pre)
  File "/devel/project/.venv/lib/python3.7/site-packages/pur/utils.py", line 168, in latest_version
    all_candidates = [c for c in all_candidates
  File "/devel/project/.venv/lib/python3.7/site-packages/pur/utils.py", line 169, in <listcomp>
    if less_than(c.version, spec_ver[0], patch=True)]
  File "/devel/project/.venv/lib/python3.7/site-packages/pur/utils.py", line 320, in less_than
    new_minor = int((new_ver[1] if len(new_ver) > 1 else 0) or 0)
ValueError: invalid literal for int() with base 10: '8a1'

pur -m "*" throws some error on pytz, because there is a Pytz Version 2004d:

Traceback (most recent call last):
  File "/devel/project/.venv/bin/pur", line 11, in <module>
    load_entry_point('pur==5.2.0', 'console_scripts', 'pur')()
  File "/devel/project/.venv/lib/python3.7/site-packages/click/core.py", line 764, in __call__
    return self.main(*args, **kwargs)
  File "/devel/project/.venv/lib/python3.7/site-packages/click/core.py", line 717, in main
    rv = self.invoke(ctx)
  File "/devel/project/.venv/lib/python3.7/site-packages/click/core.py", line 956, in invoke
    return ctx.invoke(self.callback, **ctx.params)
  File "/devel/project/.venv/lib/python3.7/site-packages/click/core.py", line 555, in invoke
    return callback(*args, **kwargs)
  File "/devel/project/.venv/lib/python3.7/site-packages/pur/__init__.py", line 119, in pur
    echo=options['echo'],
  File "/devel/project/.venv/lib/python3.7/site-packages/pur/__init__.py", line 178, in update_requirements
    echo=echo)
  File "/devel/project/.venv/lib/python3.7/site-packages/pur/__init__.py", line 207, in _internal_update_requirements
    for line, req, spec_ver, latest_ver in requirements:
  File "/devel/project/.venv/lib/python3.7/site-packages/pur/__init__.py", line 346, in _get_requirements_and_latest
    minor=minor, patch=patch, pre=pre)
  File "/devel/project/.venv/lib/python3.7/site-packages/pur/utils.py", line 172, in latest_version
    all_candidates = [c for c in all_candidates
  File "/devel/project/.venv/lib/python3.7/site-packages/pur/utils.py", line 173, in <listcomp>
    if less_than(c.version, spec_ver[0])]
  File "/devel/project/.venv/lib/python3.7/site-packages/pur/utils.py", line 315, in less_than
    new_major = int(new_ver[0] or 0)
ValueError: invalid literal for int() with base 10: '2004d'

My requirements.txt to test with:

billiard==3.5.0.3
celery==4.2.0rc2
Django==1.11.11
django-filter==1.0.4
djangorestframework==3.7.7
kombu==4.1.0
packaging==16.8
python-pushover==0.3
pytz==2018.3
redis==2.10.6
requests==2.18.4
six==1.11.0
psycopg2

pull index_urls from pip.conf

Currently, we have to use the --index-urls option to get packages from our index, even pip would normally find the new packages using the indices set in the pip.conf

Set exit code

It would be very useful if pur set the exit code of the process based on the result of the update process. For example, if any versions were bumped, return 1. If nothing was changed, return 0. This will help using pur in a script that automates version updates.

pur cannot be called as a python module

python -m pur ... should work the same way as pur ... as this calling method has great advantages as it assures the used of the correct python interpreter (multiple can be installed).

Implementing this is extreamly easy, all is needed is to assure you have a main.py file that looks like https://github.com/ansible/molecule/blob/master/molecule/__main__.py and python will load it.

This is not a new python features, it is fully supported on 2.7+ and is used my most other tools I know (tox, pytest, flake8,....).

Feature: dry mode that lists packages that can be upgraded

Hello,

First of all, many thanks for this tool which is easy and convenient to use!

Is there a possibility to have a kind-of dry mode that lists only packages to be upgraded?

For instance:

$> pur -r requirements.txt -d
fastapi: 0.80.0 -> 0.82.0
python-dotenv: 0.20.0 -> 0.21.0
2 package upgrade(s) available.

I tried something like:

$> pur -n -r requirements.txt -d | sed '$ d' | diff --suppress-common-lines -y requirements.txt -
                                                              > ==> requirements.txt <==
fastapi==0.80.0                                               | fastapi==0.82.0
python-dotenv==0.20.0                                         | python-dotenv==0.21.0

Or maybe there is another tool that already provides this information.

Thank you!

Option to upgrade only packages with no specified version

There is an option -f that

forces updating packages even when a package has no version specified in the input requirements.txt file.

I would like an option for the inverse; to update only these packages and not touch the packages for which a version has been specified.

Example:

Input Output
argcomplete argcomplete==1.12.2
robotframework==3.1.2 robotframework==3.1.2

Note that robotframework is version 3.1.2 both in the input and in the output. Normally, robotframework would have been updated to 4.0, which is the newest version available at the time of writing this.

I can of course put the packages for which there is a specified version and the ones for which there isn't in two separate requirements.txt files, but it's much less convenient...

Update builtin pip

We have an error, that fixed in new version of pip
File "/Users/user/venv/lib/python3.9/site-packages/pur/packages/pip/_internal/utils/logging.py", line 81, in indent_log _log_state.indentation += num
pypa/pip#2977

And old version of pip Version object don't have major, minor, micro properties.

Please update builtin pip
Why we use builtin pip instead of pip as requirement?

Exit code l0 is a non-sysexits compliant code

Good afternoon,

I'm writing to ask if it'd be possible to explain why the choice for an l0 exit code instead of a 0 exit code was used. Generally speaking, application exit codes are meant to be numeric, with some being specifically meant for uses based on the sysexits.h file (can be viewed via man sysexits). This specifically documents:

0   /* successful termination */
64  /* base value for error messages */
64  /* command line usage error */
65  /* data format error */
66  /* cannot open input */
67  /* addressee unknown */
68  /* host name unknown */
69  /* service unavailable */
70  /* internal software error */
71  /* system error (e.g., can't fork) */
72  /* critical OS file missing */
73  /* can't create (user) output file */
74  /* input/output error */
75  /* temp failure; user is invited to retry */
76  /* remote error in protocol */
77  /* permission denied */
78  /* configuration error */
/* maximum listed value */

I was wondering why the choice for a leading character was used instead of the more broadly accepted 0 value for a successful exit. There are other exit codes which are common, such as:

1 - Catchall for general errors
2 - Misuse of shell builtins (according to Bash documentation)
6 - No such device or address
124 - command times out
125 - if a command itself fails (based on coreutils)
126 - if command is found but cannot be invoked (e.g. is not executable)
127 - if a command cannot be found, the child process created to execute it returns that status
128 - Invalid argument to exit (exit is meant to take only integer args in the range 0 - 255)
137 - if command is sent the KILL(9) signal (128+9), the exit status of command otherwise
141 - SIGPIPE - write on a pipe with no reader
143 - command terminated by signal code 15 (128+15=143)
255* - exit status out of range.

Any additional information would be appreciated, this had triggered some issues in our CI pipeline as it looks for 0 for success (Gitlab CI) and non-zero for failures.

Add click v8 compatibility

$ pur -i -r requirements.in

Traceback (most recent call last):
  File "//.pyenv/versions/varys/bin/pur", line 8, in <module>
    sys.exit(pur())
  File "//.pyenv/versions/3.8.10/envs/varys/lib/python3.8/site-packages/click/core.py", line 1137, in __call__
    return self.main(*args, **kwargs)
  File "//.pyenv/versions/3.8.10/envs/varys/lib/python3.8/site-packages/click/core.py", line 1061, in main
    with self.make_context(prog_name, args, **extra) as ctx:
  File "//.pyenv/versions/3.8.10/envs/varys/lib/python3.8/site-packages/click/core.py", line 923, in make_context
    self.parse_args(ctx, args)
  File "//.pyenv/versions/3.8.10/envs/varys/lib/python3.8/site-packages/click/core.py", line 1379, in parse_args
    value, args = param.handle_parse_result(ctx, opts, args)
  File "//.pyenv/versions/3.8.10/envs/varys/lib/python3.8/site-packages/click/core.py", line 2364, in handle_parse_result
    value = self.process_value(ctx, value)
  File "//.pyenv/versions/3.8.10/envs/varys/lib/python3.8/site-packages/click/core.py", line 2320, in process_value
    value = self.type_cast_value(ctx, value)
  File "//.pyenv/versions/3.8.10/envs/varys/lib/python3.8/site-packages/click/core.py", line 2307, in type_cast_value
    return convert(value)
  File "//.pyenv/versions/3.8.10/envs/varys/lib/python3.8/site-packages/click/types.py", line 75, in __call__
    return self.convert(value, param, ctx)
  File "//.pyenv/versions/3.8.10/envs/varys/lib/python3.8/site-packages/pur/__init__.py", line 54, in convert
    if value.lower() == 'true':
AttributeError: 'bool' object has no attribute 'lower'

https://click.palletsprojects.com/en/8.0.x/changes/#version-8-0-0

Version 3.0.2 is not working at all

Current version (3.0.2) is not working at all. Not with old version provided and not without version with --force argument. When I use v3.0.1, it's working (at least when there is old version provided). I'm using Python 2.7

EDIT: Problem emerged somewhere in commit 13c63b9

Comments getting space prefix with every run

Lines that contain nothing but a comment get a space prefix with every run of pur. Lines that have an actual requirement in them don't seem to be affected.

(DEV) amir@dev:~$ cat /tmp/req.txt
requests==2.10.0 # a comment
#hello
# hello
#  hello
(DEV) amir@dev:~$ pur /tmp/req.txt  && cat /tmp/req.txt
All requirements up-to-date.
requests==2.10.0 # a comment
 #hello
 # hello
 #  hello
(DEV) amir@dev:~$ pur /tmp/req.txt  && cat /tmp/req.txt
All requirements up-to-date.
requests==2.10.0 # a comment
  #hello
  # hello
  #  hello
(DEV) amir@dev:~$ pur /tmp/req.txt  && cat /tmp/req.txt
All requirements up-to-date.
requests==2.10.0 # a comment
   #hello
   # hello
   #  hello
(DEV) amir@dev:~$

This is a minor issue, but would be nice to get fixed. I plan to run pur, check for changes based on the existing version in git, and then run tests and commit if there are changes. If pur keeps changing the file without versions actually being updated, it makes the flow a little more difficult.

Add support for pyproject.toml

The same functionality should work, but you would just have to skip to only the "[dependencies]" section in pyproject.toml.

`--skip` param ignored for included requirements files

Using pur 7.1.1, and with a requirements-dev.txt containing

mypy
-r requirements.txt

and a requirements.txt containing

pandas==1.4.2

Running

pur --skip="pandas" requirements-dev.txt

results in

Updated pandas: 1.4.2 -> 2.0.3

Shouldn't pur respect the skip param in this case?

Allow to update multiple requirements files

Description

I was using https://github.com/simion/pip-upgrader for a while and having the following structure:

requirements/
    base.txt
    dev.txt
    prod.txt

I could update all of them using pip-upgrade requirements/*.txt.

It would be nice that pur allows the same to update multiple requirements files.

Workaround

for filename in requirements/*.txt; do pur -r $filename; done

command not found: pur

Hello
i'm using ubuntu 18.04
i installed pur using command

~ pip install pur
Collecting pur
Collecting click>=0.7 (from pur)
  Using cached https://files.pythonhosted.org/packages/fa/37/45185cb5abbc30d7257104c434fe0b07e5a195a6847506c074527aa599ec/Click-7.0-py2.py3-none-any.whl
Installing collected packages: click, pur
Successfully installed click-7.0 pur-5.0.0

but when i try to use it i have an error:

~ pur -r requirements.txt
zsh: command not found: pur

ps: i have both Python 2.7.15rc1 & Python 3.6.6 installed,
i tried pip3 install pur but stay same thing

Support for compatible release operator ~=

Hello,

I've noticed pur does not support the compatible release operator, i.e. ~=.
As described PEP-0440, ~= 1.4.5 is equivalent to >= 1.4.5, == 1.4.* (https://www.python.org/dev/peps/pep-0440/#compatible-release), but even if pur is able to update from click >= 7.1.0, == 7.1.* to click >= 7.1.2, == 7.1.*, it does nothing with click ~= 7.1.0.
I suppose this would be the appropriate behaviour to implement in pur.

That being said, it wouldn't fit my personal use case: basically I'm usually "soft-pinning" my requirements, meaning specifying boto3 ~= 1.12.49 instead of using the == operator, to allow security patches and also avoid dependency hell when I'm using inter-dependent modules.
So in my case, using requirements with ~= operator, I would prefer pur to behave just like it does with the == operator, meaning updating to the latest available version.
Would there be a way to enable this behaviour somehow while staying PEP-0440 compliant?

Thanks.

import error in version 6.0.0

Issue in version 6.0.0.

Below code return error

Code:
from pur import update_requirements

Error:
ImportError: cannot import name 'update_requirements' from 'pur'

Support for Python 3.12

With Python 3.12.0rc1

% pur -r requirements.txt 
Error: Traceback (most recent call last):
  File "/Users/User/git/leetcode/.venv/lib/python3.12/site-packages/pur/__init__.py", line 132, in pur
    update_requirements(
  File "/Users/User/git/leetcode/.venv/lib/python3.12/site-packages/pur/__init__.py", line 201, in update_requirements
    _update_requirements(
  File "/Users/User/git/leetcode/.venv/lib/python3.12/site-packages/pur/__init__.py", line 264, in _update_requirements
    for line, req, spec_ver, latest_ver in requirements:
  File "/Users/User/git/leetcode/.venv/lib/python3.12/site-packages/pur/__init__.py", line 344, in _get_requirements_and_latest
    session = PipSession(
              ^^^^^^^^^^^
  File "/Users/User/git/leetcode/.venv/lib/python3.12/site-packages/pur/packages/pip/_internal/network/session.py", line 282, in __init__
    self.headers["User-Agent"] = user_agent()
                                 ^^^^^^^^^^^^
  File "/Users/User/git/leetcode/.venv/lib/python3.12/site-packages/pur/packages/pip/_internal/network/session.py", line 157, in user_agent
    setuptools_dist = get_default_environment().get_distribution("setuptools")
                      ^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/User/git/leetcode/.venv/lib/python3.12/site-packages/pur/packages/pip/_internal/metadata/__init__.py", line 24, in get_default_environment
    from .pkg_resources import Environment
  File "/Users/User/git/leetcode/.venv/lib/python3.12/site-packages/pur/packages/pip/_internal/metadata/pkg_resources.py", line 9, in <module>
    from pip._vendor import pkg_resources
  File "/Users/User/git/leetcode/.venv/lib/python3.12/site-packages/pur/packages/pip/_vendor/pkg_resources/__init__.py", line 2164, in <module>
    register_finder(pkgutil.ImpImporter, find_on_path)
                    ^^^^^^^^^^^^^^^^^^^
AttributeError: module 'pkgutil' has no attribute 'ImpImporter'. Did you mean: 'zipimporter'?

Add `--only TEXT ` (the inverse of `--skip TEXT`)

Sometimes is better to:

  1. Upgrade one requirement
  2. Run the tests
  3. Fix the problems (if any)
  4. Re-run the tests
  5. Commit && Push
  6. Goto 1

...specially for projects with a lot of dependencies. Having the --only option in this case would be really nice.

Wish: allow to upgrade some packages in patchlevel only

Currently I run pur --skip=Django -r requirements.txt to make sure my project doesn't break due to a new Django version. However, I would love to have a flag to tell that Django can be upgraded, but only in it's patch-level (2.1.x) so it does upgrade for bugfixes.

Perhaps something like pur --patchlevel-only=Django,package2,package3 -r requirements.txt ?

Alphabetize requirements?

Hello, I was wondering if it would be possible to add a command line flag to automatically sort the requirements alphabetically? Thanks!

Option to add version to packages with no version

It would be great if there is an option to add latest version to packages with no explicit version defined.

Use-case: I don't have to fill in version for every package when I'm starting a new project, I'll just do it with one command when I have all requirements.

Example: flask --> flask==0.9

Breakage (due to click update?)

Hello,
I've been using pur as part of my build pipeline for a while and in the past few days it has started erroring for me. I'm using Python 3.8 on an intel Mac with everything kept up to date via homebrew and pip

cd src && pur -r requirements.txt
Traceback (most recent call last):
  File "/usr/local/bin/pur", line 8, in <module>
    sys.exit(pur())
  File "/usr/local/lib/python3.9/site-packages/click/core.py", line 1134, in __call__
    return self.main(*args, **kwargs)
  File "/usr/local/lib/python3.9/site-packages/click/core.py", line 1058, in main
    with self.make_context(prog_name, args, **extra) as ctx:
  File "/usr/local/lib/python3.9/site-packages/click/core.py", line 927, in make_context
    self.parse_args(ctx, args)
  File "/usr/local/lib/python3.9/site-packages/click/core.py", line 1376, in parse_args
    value, args = param.handle_parse_result(ctx, opts, args)
  File "/usr/local/lib/python3.9/site-packages/click/core.py", line 2352, in handle_parse_result
    value = self.process_value(ctx, value)
  File "/usr/local/lib/python3.9/site-packages/click/core.py", line 2308, in process_value
    value = self.type_cast_value(ctx, value)
  File "/usr/local/lib/python3.9/site-packages/click/core.py", line 2295, in type_cast_value
    return convert(value)
  File "/usr/local/lib/python3.9/site-packages/click/types.py", line 75, in __call__
    return self.convert(value, param, ctx)
  File "/usr/local/lib/python3.9/site-packages/pur/__init__.py", line 54, in convert
    if value.lower() == 'true':
AttributeError: 'bool' object has no attribute 'lower'

The versions I'm seeing via pip:

pur                      5.4.0
click                    8.0.0

It looks like click was just updated to 8.0.0 a few days ago so I'm guessing this broke something?
Please let me know if I can provide any more info..

Updating requirements with max version

Updating requirements with max version is not working, as far I can tell.
I tried django>=1.8.6,<1.9 which should update to django>=1.8.13,<1.9. Instead it just does nothing. I tried different format, like django==1.8.6,<1.9 or django==1.8.6,<=1.9, still nothing.

Allow for additional PyPI index-urls

Is there an option to fetch from a custom PyPI or specify multiple index-urls?

For example

pur --index-url https://pypi.internal/simple -r requirements.txt

requirments file contains another file

Currently if we have a requirements.txt file that contains smth like:

 -r requirements-common.txt

then it will not try to find the packages updates from that file(s). Would be great to have such feature.

Thx.

Interactive option? Like `npm-check -u`

I really miss something like npm-check but for Python.

Basically a menu that shows all requirements and allows you to select what to upgrade and only those packages are updated in the requirements file.

Updated version not detected

I notice that pur will not detect updates for black (https://github.com/ambv/black).

Reproduction of error:

  • make new virtualenv
  • pip install pur
  • make new requirements.txt
  • add black==18.6b4 to requirements.txt
  • pip install -r requirements.txt
  • confirm black==18.6b4 in output of pip freeze
  • run pur -f -r requirements.txt
  • pur will not update black version, confirm black==18.6b4 in requirements.txt
  • run pip install -U black
  • pip will find newer black version, at the time of writing black==18.9b0

Dry run option?

Some of my requirements.txts are for microservices that would be a hastle to run pip list -o on.

Show warning for invalid packages

Given the requirements file req.txt, with the following contents:

non-existent-package

The command

pip install -r req.txt produces the following output:

ERROR: Could not find a version that satisfies the requirement non-existent-package (from -r req.txt (line 1)) (from versions: none)
ERROR: No matching distribution found for non-existent-package (from -r req.txt (line 1))

However, pur -f -r req.txt (version 0.5.4) just says All requirements up-to-date. and exits with code 0. I'd say this is a bug?

pur installs yanked packages

Pur is currently upgrading requirements to the most recent version, even when that version is "yanked" (https://pypi.org/help/#yanked). It would be better if it checked for this and installed the most recent non-yanked version.

Example pur output right now:

Updated jupyter-client: 6.1.12 -> 6.2.0

And then installing:

:; pip install jupyter-client==6.2.0
Collecting jupyter-client==6.2.0
  Using cached jupyter_client-6.2.0-py3-none-any.whl (112 kB)
Collecting pyzmq>=13
  Using cached pyzmq-22.1.0-cp39-cp39-macosx_10_15_universal2.whl (1.9 MB)
Collecting python-dateutil>=2.1
  Using cached python_dateutil-2.8.1-py2.py3-none-any.whl (227 kB)
Collecting nest-asyncio>=1.5
  Using cached nest_asyncio-1.5.1-py3-none-any.whl (5.0 kB)
Collecting traitlets
  Using cached traitlets-5.0.5-py3-none-any.whl (100 kB)
Collecting jupyter-core>=4.6.0
  Using cached jupyter_core-4.7.1-py3-none-any.whl (82 kB)
Collecting tornado>=4.1
  Using cached tornado-6.1-cp39-cp39-macosx_10_9_x86_64.whl (416 kB)
Collecting six>=1.5
  Using cached six-1.16.0-py2.py3-none-any.whl (11 kB)
Collecting ipython-genutils
  Using cached ipython_genutils-0.2.0-py2.py3-none-any.whl (26 kB)
WARNING: The candidate selected for download or install is a yanked version: 'jupyter-client' candidate (version 6.2.0 at https://files.pythonhosted.org/packages/88/4e/50fcf8b38d9c08d5b4839c1650e595f6bfa4fc9b419e2b800db8f14ee532/jupyter_client-6.2.0-py3-none-any.whl#sha256=9715152067e3f7ea3b56f341c9a0f9715c8c7cc316ee0eb13c3c84f5ca0065f5 (from https://pypi.org/simple/jupyter-client/) (requires-python:>=3.6.1))
Reason for being yanked: Breaking API change
Installing collected packages: ipython-genutils, traitlets, six, tornado, pyzmq, python-dateutil, nest-asyncio, jupyter-core, jupyter-client
Successfully installed ipython-genutils-0.2.0 jupyter-client-6.2.0 jupyter-core-4.7.1 nest-asyncio-1.5.1 python-dateutil-2.8.1 pyzmq-22.1.0 six-1.16.0 tornado-6.1 traitlets-5.0.5

Use of the environment-markers

Usage of associated python version as a constraint, today pur is ignoring environment markers:

Before:

numpy==1.21.5; python_version<='3.7'

After:

numpy==1.22.3; python_version<='3.7'

Expected as this is the last version that supports Python 3.7:

numpy==1.21.5; python_version<='3.7'

detect resolution interdependencies

I'm not sure this can even be figured out by pur, but when I ran it against my requirements and then did a pip install this dependency error happened. I have to say it's not a big deal to manually fix these but an automated detection of this kind of dependency conflict would be great!

INFO: pip is looking at multiple versions of arrow to determine which version is compatible with other requirements. This could take a while.
ERROR: Cannot install -r requirements.txt (line 17) and arrow==0.17.0 because these package versions have conflicting dependencies.

The conflict is caused by:
    The user requested arrow==0.17.0
    ics 0.7 depends on arrow<0.15 and >=0.11

To fix this you could try to:
1. loosen the range of package versions you've specified
2. remove package versions to allow pip attempt to solve the dependency conflict

ERROR: ResolutionImpossible: for help visit https://pip.pypa.io/en/latest/user_guide/#fixing-conflicting-dependencies

and then after manually fixing that:

ERROR: Cannot install -r requirements.txt (line 37) and idna==3.1 because these package versions have conflicting dependencies.

The conflict is caused by:
    The user requested idna==3.1
    requests 2.25.1 depends on idna<3 and >=2.5

To fix this you could try to:
1. loosen the range of package versions you've specified
2. remove package versions to allow pip attempt to solve the dependency conflict

ERROR: ResolutionImpossible: for help visit https://pip.pypa.io/en/latest/user_guide/#fixing-conflicting-dependencies

Manually fixing that got me up to date with those two exceptions which is way better than the old way of pinning versions once and then never updating!

Python 3.6: AttributeError: '_NamespacePath' object has no attribute 'sort'

Traceback (most recent call last):
  File "/usr/local/bin/pur", line 7, in <module>
    from pur.__init__ import pur
  File "/usr/local/lib/python3.6/site-packages/pur/__init__.py", line 24, in <module>
    from pip.download import PipSession
  File "/usr/local/lib/python3.6/site-packages/pur/packages/pip/__init__.py", line 26, in <module>
    from pip.utils import get_installed_distributions, get_prog
  File "/usr/local/lib/python3.6/site-packages/pur/packages/pip/utils/__init__.py", line 27, in <module>
    from pip._vendor import pkg_resources
  File "/usr/local/lib/python3.6/site-packages/pur/packages/pip/_vendor/pkg_resources/__init__.py", line 3017, in <module>
    @_call_aside
  File "/usr/local/lib/python3.6/site-packages/pur/packages/pip/_vendor/pkg_resources/__init__.py", line 3003, in _call_aside
    f(*args, **kwargs)
  File "/usr/local/lib/python3.6/site-packages/pur/packages/pip/_vendor/pkg_resources/__init__.py", line 3045, in _initialize_master_working_set
    dist.activate(replace=False)
  File "/usr/local/lib/python3.6/site-packages/pur/packages/pip/_vendor/pkg_resources/__init__.py", line 2577, in activate
    declare_namespace(pkg)
  File "/usr/local/lib/python3.6/site-packages/pur/packages/pip/_vendor/pkg_resources/__init__.py", line 2151, in declare_namespace
    _handle_ns(packageName, path_item)
  File "/usr/local/lib/python3.6/site-packages/pur/packages/pip/_vendor/pkg_resources/__init__.py", line 2091, in _handle_ns
    _rebuild_mod_path(path, packageName, module)
  File "/usr/local/lib/python3.6/site-packages/pur/packages/pip/_vendor/pkg_resources/__init__.py", line 2120, in _rebuild_mod_path
    orig_path.sort(key=position_in_sys_path)
AttributeError: '_NamespacePath' object has no attribute 'sort'

AttributeError with git line

The following line in my requirements.txt file causes pur to fail.

git+git://github.com/django-haystack/django-haystack.git@10bcc7668ccaab499f8db516fd59de182aadbcb4

The exception I get is:

Traceback (most recent call last):
  File "/home/amir/DEV/bin/pur", line 11, in <module>
    sys.exit(pur())
  File "/home/amir/DEV/lib/python3.5/site-packages/click/core.py", line 716, in __call__
    return self.main(*args, **kwargs)
  File "/home/amir/DEV/lib/python3.5/site-packages/click/core.py", line 696, in main
    rv = self.invoke(ctx)
  File "/home/amir/DEV/lib/python3.5/site-packages/click/core.py", line 889, in invoke
    return ctx.invoke(self.callback, **ctx.params)
  File "/home/amir/DEV/lib/python3.5/site-packages/click/core.py", line 534, in invoke
    return callback(*args, **kwargs)
  File "/home/amir/DEV/lib/python3.5/site-packages/pur/__init__.py", line 44, in pur
    for line, req, spec_ver, latest_ver in requirements:
  File "/home/amir/DEV/lib/python3.5/site-packages/pur/__init__.py", line 90, in get_requirements_and_latest
    spec_ver = Version(req.req.specs[0][1])
AttributeError: 'NoneType' object has no attribute 'specs'

I'm on Python 3.5 with pip 8.1.1.

It seems like req.req is None for that kind of line. I was able to locally fix the issue by catching AttributeError on top of IndexError.

How can I make pur work faster?

I observe that updating single packages takes long time than it should be, which is around ~20 seconds.
Is there any way to make this process faster to update only a single package?

$ time pur -r requirements.txt --only pymysql
Updated pymysql: 1.0.2 -> 1.0.3
All requirements up-to-date.
pur -r requirements.txt --only pymysql  21.13s user 0.65s system 42% cpu 51.593 total

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.