Skip to content

Commit

Permalink
Merge branch 'master' into mypy-coverage
Browse files Browse the repository at this point in the history
  • Loading branch information
jaraco authored Nov 11, 2019
2 parents 453e344 + edc4606 commit b508e70
Show file tree
Hide file tree
Showing 12 changed files with 81 additions and 144 deletions.
4 changes: 0 additions & 4 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,6 @@ matrix:
name: Linting code smells
env:
TOXENV: lint-code-style
- python: 3.7
name: Linting distribution metadata
env:
TOXENV: lint-dist-meta
- python: 3.7
name: Linting type matching
env:
Expand Down
11 changes: 0 additions & 11 deletions MANIFEST.in

This file was deleted.

63 changes: 31 additions & 32 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

.. image:: https://img.shields.io/pypi/pyversions/twine.svg
:target: https://pypi.org/project/twine

.. image:: https://img.shields.io/readthedocs/twine
:target: https://twine.readthedocs.io

Expand Down Expand Up @@ -103,61 +103,60 @@ Keyring Support
---------------

Instead of typing in your password every time you upload a distribution, Twine
allows you to store your username and password securely using `keyring`_.

To use the keyring, you must first install the keyring packages:
allows storing a username and password securely using `keyring`_.
Keyring is installed with Twine but for some systems (Linux mainly) may
require
`additional installation steps <https://pypi.org/project/keyring/#linux>`_.

- On Windows and MacOS you just need to install ``keyring``, for example,
``pip install --user keyring``.
- On Linux, in addition to the ``keyring`` package you also need to ensure the
``python3-dbus`` system package is installed. For example, ``apt install
python3-dbus``. See `Keyring's installation instructions`_ for more details.
Once Twine is installed, use the ``keyring`` program to set a
username and password to use for each package index (repository) to
which you may upload.

Once keyring is installed you can use the ``keyring`` program to set your
username and password to use for each package index (repository) you want to
upload to using Twine.

To set your username and password for Test PyPI run the following command.
``keyring`` will prompt you for your password:

.. code-block:: console
$ keyring set https://test.pypi.org/legacy/ your-username
# or
$ python3 -m keyring set https://test.pypi.org/legacy/ your-username
To set your username and password for PyPI run this command, again, ``keyring``
will prompt for the password:
For example, to set a username and password for PyPI:

.. code-block:: console
$ keyring set https://upload.pypi.org/legacy/ your-username
# or
$ python3 -m keyring set https://upload.pypi.org/legacy/ your-username
And enter the password when prompted.

For a different repository, replace the URL with the relevant repository
URL. For example, for Test PyPI, use ``https://test.pypi.org/legacy/``.

The next time you run ``twine`` it will prompt you for a username and will grab
The next time you run ``twine``, it will prompt you for a username and will grab
the appropriate password from the keyring.

.. Note:: If you are using Linux in a headless environment (such as on a
server) you'll need to do some additional steps to ensure that Keyring can
store secrets securely. See `Using Keyring on headless systems`_.

.. _`keyring`: https://pypi.org/project/keyring/
.. _`Keyring's installation instructions`:
https://keyring.readthedocs.io/en/latest#installation-instructions
.. _`Using Keyring on headless systems`:
https://keyring.readthedocs.io/en/latest/#using-keyring-on-headless-linux-systems

Disabling Keyring
^^^^^^^^^^^^^^^^^

In some cases, the presence of keyring may be problematic. To disable
keyring and defer to a prompt for passwords, uninstall ``keyring``
or if that's not an option, you can also configure keyring to be disabled.
In most cases, simply not setting a password in keyring will allow twine
to fall back to prompting for a password. In some cases, the presence of
keyring will cause unexpected or undesirable prompts from the backing
system. In these cases, it may be desirable to disable keyring altogether.
To disable keyring, simply invoke:

.. code-block:: console
$ keyring --disable
or
$ python -m keyring --disable
That command will configure for the current user the "null" keyring,
effectively disabling the functionality, and allowing Twine to prompt
for passwords.

See `twine 338 <https://github.com/pypa/twine/issues/338>`_ for a
discussion on ways to do that.
See `twine 338 <https://github.com/pypa/twine/issues/338>`_ for
discussion and background.

Options
-------
Expand Down
6 changes: 4 additions & 2 deletions docs/changelog.rst
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,10 @@
=========
Changelog
=========
* :feature:`520`: Remove ``no_positional`` decorator in favor of native
syntax.
* :feature:`524`: Twine now unconditionally requires the keyring library
and no longer supports uninstalling ``keyring`` as a means to disable
that functionality. Instead, use ``keyring --disable`` keyring functionality
if necessary.
* :feature:`518` Add Python 3.8 to classifiers.
* :bug:`332` More robust handling of server response in ``--skip-existing``
* :release:`2.0.0 <2019-09-24>`
Expand Down
14 changes: 2 additions & 12 deletions docs/contributing.rst
Original file line number Diff line number Diff line change
Expand Up @@ -199,12 +199,7 @@ A checklist for creating, testing, and distributing a new version.

#. View your tag: ``git tag -v {number}``
#. Push your tag: ``git push upstream {number}``.
#. Delete old distributions: ``rm dist/*``.
#. Create distributions with ``python setup.py sdist bdist_wheel``.
#. Set your TestPyPI and canon PyPI credentials in your session with
``keyring`` (docs forthcoming).
#. Upload to Test PyPI: :command:`twine upload --repository-url
https://test.pypi.org/legacy/ --skip-existing dist/*`
#. Upload to TestPyPI with ``TWINE_REPOSITORY=https://test.pypi.org/legacy/ tox -e release``
#. Verify that everything looks good, downloads ok, etc. Make needed fixes.
#. Merge the last PR before the new release:

Expand All @@ -218,12 +213,7 @@ A checklist for creating, testing, and distributing a new version.
#. Create a new git tag with ``git tag -sam 'Release v{number}' {number}``.
#. View your tag: ``git tag -v {number}``
#. Push your tag: ``git push upstream {number}``.
#. Delete old distributions: ``rm dist/*``.
#. Create distributions with ``python setup.py sdist bdist_wheel``.
#. On a Monday or Tuesday, upload to canon PyPI: :command:`twine
upload --skip-existing dist/*`

.. note:: Will be replaced by ``tox -e release`` at some point.
#. On a Monday or Tuesday, upload to PyPI with ``tox -e release``.
#. Send announcement email to `pypa-dev mailing list`_ and celebrate.


Expand Down
3 changes: 3 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
[build-system]
requires = ["setuptools>=40.8", "wheel", "setuptools_scm>=1.15"]
build-backend = "setuptools.build_meta:__legacy__"
6 changes: 6 additions & 0 deletions pytest.ini
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
[pytest]
filterwarnings=
# workaround for https://github.com/mozilla/bleach/issues/425
ignore:Using or importing the ABCs:DeprecationWarning:bleach
# workaround for https://github.com/pypa/setuptools/issues/479
ignore:the imp module is deprecated::setuptools
7 changes: 0 additions & 7 deletions setup.cfg
Original file line number Diff line number Diff line change
@@ -1,9 +1,2 @@
[check-manifest]
ignore =
.travis.yml
tox.ini
.github
.github/*

[metadata]
license_file = LICENSE
9 changes: 4 additions & 5 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -73,10 +73,9 @@
"requests-toolbelt >= 0.8.0, != 0.9.0",
"setuptools >= 0.7.0",
"tqdm >= 4.14",
"keyring >= 15.1",
],
setup_requires=[
'setuptools_scm>=1.15',
],
extras_require={
'keyring': [
'keyring',
],
},
)
34 changes: 10 additions & 24 deletions tests/test_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import sys

import os.path
import textwrap

Expand Down Expand Up @@ -227,7 +227,7 @@ class MockKeyring:
def get_password(system, user):
return '{user}@{system} sekure pa55word'.format(**locals())

monkeypatch.setitem(sys.modules, 'keyring', MockKeyring)
monkeypatch.setattr(utils, 'keyring', MockKeyring)

pw = utils.get_password('system', 'user', None, {})
assert pw == 'user@system sekure pa55word'
Expand All @@ -241,7 +241,7 @@ class MockKeyring:
def get_password(system, user):
return

monkeypatch.setitem(sys.modules, 'keyring', MockKeyring)
monkeypatch.setattr(utils, 'keyring', MockKeyring)

pw = utils.get_password('system', 'user', None, {})
assert pw == 'entered pw'
Expand Down Expand Up @@ -278,30 +278,21 @@ def get_password(system, user):
raise RuntimeError("unexpected username")
return cred.password

monkeypatch.setitem(sys.modules, 'keyring', MockKeyring)
monkeypatch.setattr(utils, 'keyring', MockKeyring)

user = utils.get_username('system', None, {})
assert user == 'real_user'
pw = utils.get_password('system', user, None, {})
assert pw == 'real_user@system sekure pa55word'


@pytest.fixture
def keyring_missing(monkeypatch):
"""
Simulate that 'import keyring' raises an ImportError
"""
monkeypatch.delitem(sys.modules, 'keyring', raising=False)


@pytest.fixture
def keyring_missing_get_credentials(monkeypatch):
"""
Simulate older versions of keyring that do not have the
'get_credentials' API.
Simulate keyring prior to 15.2 that does not have the
'get_credential' API.
"""
monkeypatch.delattr('keyring.backends.KeyringBackend',
'get_credential', raising=False)
monkeypatch.delattr(utils.keyring, 'get_credential')


@pytest.fixture
Expand All @@ -319,11 +310,6 @@ def test_get_username_keyring_missing_get_credentials_prompts(
assert utils.get_username('system', None, {}) == 'entered user'


def test_get_password_keyring_missing_prompts(
entered_password, keyring_missing):
assert utils.get_password('system', 'user', None, {}) == 'entered pw'


@pytest.fixture
def keyring_no_backends(monkeypatch):
"""
Expand All @@ -335,21 +321,21 @@ class FailKeyring:
@staticmethod
def get_password(system, username):
raise RuntimeError("fail!")
monkeypatch.setitem(sys.modules, 'keyring', FailKeyring())
monkeypatch.setattr(utils, 'keyring', FailKeyring())


@pytest.fixture
def keyring_no_backends_get_credential(monkeypatch):
"""
Simulate that keyring has no available backends. When keyring
has no backends for the system, the backend will be a
fail.Keyring, which raises RuntimeError on get_password.
fail.Keyring, which raises RuntimeError on get_credential.
"""
class FailKeyring:
@staticmethod
def get_credential(system, username):
raise RuntimeError("fail!")
monkeypatch.setitem(sys.modules, 'keyring', FailKeyring())
monkeypatch.setattr(utils, 'keyring', FailKeyring())


def test_get_username_runtime_error_suppressed(
Expand Down
27 changes: 14 additions & 13 deletions tox.ini
Original file line number Diff line number Diff line change
Expand Up @@ -23,27 +23,30 @@ commands =
twine check dist/*

[testenv:release]
# disabled for twine to cause it to upload itself
# skip_install = True
# specify Python 3 to use platform's default Python 3
basepython = python3
deps =
wheel
pep517>=0.5
twine>=1.13
path.py
passenv =
TWINE_PASSWORD
TWINE_REPOSITORY
setenv =
TWINE_USERNAME = {env:TWINE_USERNAME:__token__}
commands =
python setup.py -q bdist_wheel sdist
twine upload --skip-existing dist/*
python -c "import path; path.Path('dist').rmtree_p()"
python -m pep517.build .
python -m twine upload dist/*

[testenv:lint-code-style]
deps =
flake8
commands =
flake8 twine/ tests/

[testenv:lint-dist-meta]
deps =
check-manifest
commands =
check-manifest -v
python setup.py sdist
twine check dist/*

[testenv:lint-mypy]
deps =
mypy
Expand All @@ -55,9 +58,7 @@ commands =
[testenv:lint]
deps =
{[testenv:lint-code-style]deps}
{[testenv:lint-dist-meta]deps}
{[testenv:lint-mypy]deps}
commands =
{[testenv:lint-code-style]commands}
{[testenv:lint-dist-meta]commands}
{[testenv:lint-mypy]commands}
Loading

0 comments on commit b508e70

Please sign in to comment.