Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Failtest_installation on warnings, and remove deprecated license classifier#2054

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to ourterms of service andprivacy statement. We’ll occasionally send you account related emails.

Already on GitHub?Sign in to your account

Merged

Conversation

EliahKagan
Copy link
Member

@EliahKaganEliahKagan commentedJun 16, 2025
edited
Loading

The license trove classifier was imprecise and deprecated

The main way we indicate the license in the project's metadata is:

license="BSD-3-Clause",

However, we have for some time, until this PR, also had a trove classifier indicating "BSD License":

"License :: OSI Approved :: BSD License",

This has a couple of problems. One is that there is no specific "BSD License", but instead various BSD licenses, of which two are very popular: BSD-3-Clause, which this project uses, and BSD-2-Clause, which is not what this project uses. (No PyPI-recognized trove classifiers for those specific BSD licenses exist.)

The other problem is thatall usage ofLicense :: ... trove classifiers has been deprecated. When the package is installed, the build backend generates a warning. The warning is typically not shown when usingpip, but it will be shown if-v is passed, and it will be shown and cause an error ifPYTHONWARNINGS=error is set in the environment. (Runningpython -Werror -m pip … is not sufficient to produce it, because it is not passed down to the subprocess runningsetuptools, which is where the warning occurs.)

SetuptoolsDeprecationWarning: License classifiers are deprecated.    !!        ********************************************************************************        Please consider removing the following classifiers in favor of a SPDX license expression:        License :: OSI Approved :: BSD License        See https://packaging.python.org/en/latest/guides/writing-pyproject-toml/#license for details.        ********************************************************************************    !!

The"BSD-3-Clause" value of thelicense argument we pass tosetuptools.setup is already such an SDPX license expression. So all that is needed to fix both these problems is to remove the deprecated trove classifier. However, there are other related problems, some of which make sense to fix at the same time.

The installation test didn't detect warnings, nor report errors clearly

test_installation seeks to detect problems installing GitPython, and with#2053 it is back running and passing on all platforms we test. But it has not treated warnings during installation as errors.

Especially considering the small number of dependencies GitPython has (when not installing thetest ordoc extra), we shouldn't ordinarily have any warnings on any supported platform and Python version, and anytime we do, we probably want to know about it. I think it would not be reasonable to setPYTHONWARNINGS=error in the top-levelpip install '.[test]' commands in the CI test workflows, but that this is a good thing to do intest_installation.

Setting it intest_installation does reveal that an error occurs, but without making other changes to the test, it does not reveal in a readily understandable waywhat error occurs.test_installation contains this code (and some other code like it):

result=subprocess.run(
[venv.pip,"install","."],
stdout=subprocess.PIPE,
cwd=venv.sources,
)
self.assertEqual(
0,
result.returncode,
msg=result.stderrorresult.stdoutor"Can't install project",
)

The intent ofresult.stderr or result.stdout or "Can't install project" is to show what, if anything, was written to stderr; otherwise show what, if anything, was written to stdout; and otherwise show the prewritten message. It's true that the most important information to understand an error is often on stderr.

The problem is that it will never show what was written to stderr, because the call tosubprocess.run captures only stdout, then attempts to access stderr as though it had been captured too. Here's a simplified demonstration of that problem:

>>> from subprocess import run, PIPE>>> result = run(["sh", "-c", "echo 'this is stdout'; echo 'this is stderr' >&2"], stdout=PIPE)this is stderr>>> result.stdoutb'this is stdout\n'>>> result.stderr>>>

Depending on how the test runner (usuallypytest, which is the only runner the whole test suite supports) is run, the stderr message may be captured by the test runner and not shown, captured by the test runner and shown later where it may not be readily identified, or not captured by the test runner and possibly seen at some point either at the intuitive position or interleaved elsewhere.

The fixes

This PR:

  • Refactorstest_installation and its helpers to decrease code duplication and to clarify what the steps that set up the new virtual environment are doing, fixes the test bug where stderr was not captured, interacts with thepython andpip subprocesses assuming text-based streams and includes in the assertion message the prewritten summary as well as stdout and stderr (labeling each), and runs the subprocesses withPYTHONWARNINGS=error.

    This surfaces the deprecation warning and causes it to failtest_installation with fully detailed output reporting the problem.

  • Removes the deprecated trove classifier fromsetup.py. This is sufficient to make the test pass, as there are no other diagnostic messages of warning or higher level.

Outscoped

Improve license metadata byHugo van Kemenade, though not at all specific to GitPython, covers both the problem with some license classifiers (including "BSD License") being unclear and the deprecation, pointing out that an SPDX string should be used to identify in metadata what license a project has chosen.

However, it recommends that one also specify the paths to one's license files usinglicense-files. This is already something we were not doing, and removing the deprecated classifier does not worsen that situation. OurLICENSE file also does not have customized elements besides a listed author, who is also one of the authors listed in metadata about authorship. Most importantly, this is just about metadata: theLICENSE file is part of the project and listed inMANIFEST.in (and various files in the project also carry notices). Nonetheless, it would be good to do something like this.

I don't know if we can straightforwardly achieve the effect oflicense-files insetup.py. That blog post covers static project definitions inpyproject.toml. In addition, that meaning inpyproject.toml oflicense andlicense-files is only recognized in sufficiently new versions of build backends. Usually this isn't a problem, but some of these changes to the way licenses are expected to be indicated are actually fairly recent. GitPython supports some old versions of Python that are older than supported by the oldest version ofsetuptools that recognizespyproject.toml with alicense value that is an SPDX string (even aside from supportinglicense-files).

The packaging guide shows thecurrent status for this (PEP 639). One implication here is that it looks like we will have to choose between:

  • Not usingpyproject.toml to specifylicense as an SPDX identifier (and I think maybe not switching topyproject.toml at all, and maybe not being able to specifylicense-files or equivalent at all).
  • Dropping Python 3.7 and 3.8 support. This is not unreasonable and will definitely happen eventually--they are end-of-life, after all--but I'd rather the reason we stop supporting them relate either to something that matters at runtime, broader maintainability considerations, or major benefits of unconditionally using newer features. GitPython has a lot of users, and while hopefully just about everyone is using a supported Python, I'd be interested in moving slowly on dropping old versions, at least as far as 3.8 is concerned.
  • Usingpyproject.toml with an old, less usefullicense value, which will generate deprecation warnings, and which will eventually--sometime in 2026, I believe--stop the project from being able to be installed and/or published properly. (This deprecation is a more serious deprecation than the one fixed here with classifiers.)
  • Switching from thesetuptools build backend to another build backend that continues to support older Python versions and also supports modernlicense andlicense-files, such asflit-core or (if we drop 3.7 by then)hatchling.

Although the original plan was to stick withsetuptools per#1716 (comment), some time has passed since then and I suspect there may end up being other reasons to switch build backends. I think it may be best to decide all this at the same time, and when actually making the project definition declarative. Therefore, I have not attempted to addlicense-files or equivalent metadata in this PR.

Byron reacted with heart emoji
So that the meaning of the `venv.sources` accesses in`test_installation` is more readily clear.
This creates a function (technically, a callable `partial` object)for `test_installation` to use instead of repeating `subproces.run`keyword arguments all the time.This relates directly to steps in `_set_up_venv`, and it's makesabout as much sense to do it there as in `test_installation`, so itis placed (and described) in `_set_up_venv`.
By setting the `PYTHONWARNINGS` environment variable to `error` ineach of the subprocess invocations.This is strictly stronger than passing `-Werror` for the `python`commands, because it automatically applies to subprocesses (unlessthey are created with a sanitized environment or otherwise with onein which `PYTHONWARNINGS` has been customized), and because itworks for `pip` automatically.Importantly, this will cause warnings internal to Pythonsubprocesses created by `pip` to be treated as errors. It shouldthus surface any warnings coming from the `setuptools` backend.
Previously, it attempted to show stderr unless empty, first fallingback to stdout unless empty, then falling back to the prewrittensummary identifying the specific assertion.This now has the `test_installation` assertions capture stderr aswell as stdout, handle standard streams as text rather than binary,and show more information when failing, always distinguishing wherethe information came from: the summary, then labeled capturedstdout (empty or not), then labeled captured stderr (empty or not).That applies to all but the last assertion, which does not try toshow information differently when it fails, but is simplified to dothe right thing now that `subprocess.run` is using text streams.(This subtly changes its semantics, but overall it should be aseffective as before at finding the `sys.path` woe it anticipates.)
GitPython project metadata specify the project's license primarilythrough the value of `license`, currently passed as an argument to`setuptools.setup`, which holds the string `"BSD-3-Clause"`. Thisis an SPDX license identifier readily understood by both humans andmachines.The PyPI trove classifier "License :: OSI Approved :: BSD License"has also been specified in `setup.py`. However, this is not ideal,because:1. It does not identify a specific license. There are multiple   "BSD" licenses in use, with BSD-2-Clause and BSD-3-Clause both   in very wide use.2. It is no longer recommended to use a trove classifier to   indicate a license. The use of license classifiers (even   unambiguous ones) has been deprecated. See:   -https://packaging.python.org/en/latest/specifications/core-metadata/#classifier-multiple-use   -https://peps.python.org/pep-0639/#deprecate-license-classifiersThis commit removes the classifier. The license itself is of courseunchanged, as is the `license` value of `"BSD-3-Clause"`.(An expected effect of this change is that, starting in the nextrelease of GitPython, PyPI may show "License: BSD-3-Clause" insteadof the current text "License: BSD License (BSD-3-Clause)".)This change fixes a warning issued by a subprocess of `pip` wheninstalling the package. The warning, until this change, could beobserved by running `pip install . -v` or `pip install -e . -v` andexamining the verbose output, or by running `pip install .` or`pip install -e .` with the `PYTHONWARNINGS` environment variableset to `error`:    SetuptoolsDeprecationWarning: License classifiers are deprecated.      !!              ********************************************************************************              Please consider removing the following classifiers in favor of a SPDX license expression:              License :: OSI Approved :: BSD License              Seehttps://packaging.python.org/en/latest/guides/writing-pyproject-toml/#license for details.              ********************************************************************************      !!(In preceding commits, `test_installation` has been augmented toset that environment variable, surfacing the error. This changeshould allow that test to pass, unless it finds other problems.)
It was originally made explicit like this, but it ended up becomingposition in my last few commits. This restores that clearer aspectof how it was written before, while keeping all the other changes.
@EliahKagan

This comment was marked as outdated.

@EliahKaganEliahKagan marked this pull request as ready for reviewJune 16, 2025 05:43
@EliahKaganEliahKagan merged commit2e10199 intogitpython-developers:mainJun 16, 2025
27 checks passed
@EliahKaganEliahKagan deleted the deprecated-classifier branchJune 16, 2025 05:43
Sign up for freeto join this conversation on GitHub. Already have an account?Sign in to comment
Reviewers
No reviews
Assignees
No one assigned
Labels
None yet
Milestone
No milestone
Development

Successfully merging this pull request may close these issues.

1 participant
@EliahKagan

[8]ページ先頭

©2009-2025 Movatter.jp