Bug 1915665 - python-cartopy: FTBFS in Fedora rawhide
Summary: python-cartopy: FTBFS in Fedora rawhide
Keywords:
Status: CLOSED RAWHIDE
Alias: None
Product: Fedora
Classification: Fedora
Component: python-cartopy
Version: rawhide
Hardware: Unspecified
OS: Unspecified
unspecified
unspecified
Target Milestone: ---
Assignee: Elliott Sales de Andrade
QA Contact: Fedora Extras Quality Assurance
URL: https://koschei.fedoraproject.org/pac...
Whiteboard:
Depends On:
Blocks: F34FTBFS PYTHON3.10
TreeView+ depends on / blocked
 
Reported: 2021-01-13 08:03 UTC by Tomáš Hrnčiar
Modified: 2021-02-03 07:04 UTC (History)
3 users (show)

Fixed In Version:
Doc Type: If docs needed, set a value
Doc Text:
Clone Of:
Environment:
Last Closed: 2021-02-03 06:37:01 UTC
Type: Bug


Attachments (Terms of Use)

Description Tomáš Hrnčiar 2021-01-13 08:03:05 UTC
Description of problem:
Package python-cartopy fails to build from source in Fedora rawhide.

Version-Release number of selected component (if applicable):
0.18.0-4.fc34

Steps to Reproduce:
koji build --scratch f34 python-cartopy-0.18.0-4.fc34.src.rpm

Additional info:
This package is tracked by Koschei. See:
https://koschei.fedoraproject.org/package/python-cartopy

=================================== FAILURES ===================================
______________________________ test_ellipse_globe ______________________________
    def test_ellipse_globe():
        globe = ccrs.Globe(ellipse='WGS84')
        with pytest.warns(UserWarning,
                          match='does not handle elliptical globes.') as w:
            mill = ccrs.Miller(globe=globe)
>           assert len(w) == 1
E           assert 2 == 1
E            +  where 2 = len(WarningsChecker(record=True))
../../BUILDROOT/python-cartopy-0.18.0-4.fc34.aarch64/usr/lib64/python3.9/site-packages/cartopy/tests/crs/test_miller.py:58: AssertionError
_____________________________ test_eccentric_globe _____________________________
    def test_eccentric_globe():
        globe = ccrs.Globe(semimajor_axis=1000, semiminor_axis=500,
                           ellipse=None)
        with pytest.warns(UserWarning,
                          match='does not handle elliptical globes.') as w:
            mill = ccrs.Miller(globe=globe)
>           assert len(w) == 1
E           assert 2 == 1
E            +  where 2 = len(WarningsChecker(record=True))
../../BUILDROOT/python-cartopy-0.18.0-4.fc34.aarch64/usr/lib64/python3.9/site-packages/cartopy/tests/crs/test_miller.py:78: AssertionError
______________________________ test_ellipse_globe ______________________________
    def test_ellipse_globe():
        globe = ccrs.Globe(ellipse='WGS84')
        with pytest.warns(UserWarning,
                          match='does not handle elliptical globes.') as w:
            ortho = ccrs.Orthographic(globe=globe)
>           assert len(w) == (2
                              if (5, 0, 0) <= ccrs.PROJ4_VERSION < (5, 1, 0)
                              else 1)
E           assert 2 == 1
E            +  where 2 = len(WarningsChecker(record=True))
../../BUILDROOT/python-cartopy-0.18.0-4.fc34.aarch64/usr/lib64/python3.9/site-packages/cartopy/tests/crs/test_orthographic.py:59: AssertionError
_____________________________ test_eccentric_globe _____________________________
    def test_eccentric_globe():
        globe = ccrs.Globe(semimajor_axis=1000, semiminor_axis=500,
                           ellipse=None)
        with pytest.warns(UserWarning,
                          match='does not handle elliptical globes.') as w:
            ortho = ccrs.Orthographic(globe=globe)
>           assert len(w) == (2
                              if (5, 0, 0) <= ccrs.PROJ4_VERSION < (5, 1, 0)
                              else 1)
E           assert 2 == 1
E            +  where 2 = len(WarningsChecker(record=True))
../../BUILDROOT/python-cartopy-0.18.0-4.fc34.aarch64/usr/lib64/python3.9/site-packages/cartopy/tests/crs/test_orthographic.py:77: AssertionError
_______________________________ test_grid_labels _______________________________
args = (), kwargs = {}, orig_backend = 'agg'
style_context = <function context at 0xffff91a383a0>
    def wrapped(*args, **kwargs):
        orig_backend = plt.get_backend()
        plt.switch_backend('agg')
        mpl_setup()
    
        if plt.get_fignums():
            warnings.warn('Figures existed before running the %s %s test.'
                          ' All figures should be closed after they run. '
                          'They will be closed automatically now.' %
                          (mod_name, test_name))
            plt.close('all')
    
        if MPL_VERSION >= '2':
            style_context = mpl.style.context
        else:
            @contextlib.contextmanager
            def style_context(style, after_reset=False):
                yield
    
        with style_context(self.style):
            if MPL_VERSION >= '3.2.0':
                mpl.rcParams['text.kerning_factor'] = 6
    
>           r = test_func(*args, **kwargs)
../../BUILDROOT/python-cartopy-0.18.0-4.fc34.aarch64/usr/lib64/python3.9/site-packages/cartopy/tests/mpl/__init__.py:231: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
    @pytest.mark.natural_earth
    @ImageTesting([grid_label_image], tolerance=grid_label_tol)
    def test_grid_labels():
        fig = plt.figure(figsize=(10, 10))
    
        crs_pc = ccrs.PlateCarree()
        crs_merc = ccrs.Mercator()
    
        ax = fig.add_subplot(3, 2, 1, projection=crs_pc)
        ax.coastlines(resolution="110m")
        ax.gridlines(draw_labels=True)
    
        # Check that adding labels to Mercator gridlines gives an error.
        # (Currently can only label PlateCarree gridlines.)
        ax = fig.add_subplot(3, 2, 2,
                             projection=ccrs.PlateCarree(central_longitude=180))
        ax.coastlines(resolution="110m")
    
        ax.set_title('Known bug')
        gl = ax.gridlines(crs=crs_pc, draw_labels=True)
        gl.top_labels = False
        gl.left_labels = False
        gl.xlines = False
    
        ax = fig.add_subplot(3, 2, 3, projection=crs_merc)
        ax.coastlines(resolution="110m")
        gl = ax.gridlines(draw_labels=True)
        gl.xlabel_style = gl.ylabel_style = {'size': 9}
    
        ax = plt.subplot(3, 2, 4, projection=crs_pc)
        ax.coastlines(resolution="110m")
        gl = ax.gridlines(
            crs=crs_pc, linewidth=2, color='gray', alpha=0.5, linestyle=':')
        gl.bottom_labels = True
        gl.right_labels = True
        gl.xlines = False
        gl.xlocator = mticker.FixedLocator([-180, -45, 45, 180])
        gl.xformatter = LONGITUDE_FORMATTER
        gl.yformatter = LATITUDE_FORMATTER
        gl.xlabel_style = {'size': 15, 'color': 'gray'}
        gl.xlabel_style = {'color': 'red'}
        gl.xpadding = 10
        gl.ypadding = 15
    
        # trigger a draw at this point and check the appropriate artists are
        # populated on the gridliner instance
        fig.canvas.draw()
    
>       assert len(gl.bottom_label_artists) == 4
E       assert 0 == 4
E        +  where 0 = len([])
E        +    where [] = <cartopy.mpl.gridliner.Gridliner object at 0xffff9431b130>.bottom_label_artists
../../BUILDROOT/python-cartopy-0.18.0-4.fc34.aarch64/usr/lib64/python3.9/site-packages/cartopy/tests/mpl/test_gridliner.py:222: AssertionError
------------------------------ Captured log call -------------------------------
WARNING  matplotlib.testing:__init__.py:40 Could not set locale to English/United States. Some date-related tests may fail.
___________________________ test_grid_labels_inline ____________________________
args = (), kwargs = {}, orig_backend = 'agg'
style_context = <function context at 0xffff91a383a0>, r = None
figures = [<Figure size 2800x2800 with 23 Axes>]
figure = <Figure size 2800x2800 with 23 Axes>
    def wrapped(*args, **kwargs):
        orig_backend = plt.get_backend()
        plt.switch_backend('agg')
        mpl_setup()
    
        if plt.get_fignums():
            warnings.warn('Figures existed before running the %s %s test.'
                          ' All figures should be closed after they run. '
                          'They will be closed automatically now.' %
                          (mod_name, test_name))
            plt.close('all')
    
        if MPL_VERSION >= '2':
            style_context = mpl.style.context
        else:
            @contextlib.contextmanager
            def style_context(style, after_reset=False):
                yield
    
        with style_context(self.style):
            if MPL_VERSION >= '3.2.0':
                mpl.rcParams['text.kerning_factor'] = 6
    
            r = test_func(*args, **kwargs)
    
            figures = [plt.figure(num) for num in plt.get_fignums()]
    
            try:
>               self.run_figure_comparisons(figures, test_name=mod_name)
../../BUILDROOT/python-cartopy-0.18.0-4.fc34.aarch64/usr/lib64/python3.9/site-packages/cartopy/tests/mpl/__init__.py:236: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
../../BUILDROOT/python-cartopy-0.18.0-4.fc34.aarch64/usr/lib64/python3.9/site-packages/cartopy/tests/mpl/__init__.py:162: in run_figure_comparisons
    self.do_compare(result_path, expected_path, self.tolerance)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
self = <cartopy.tests.mpl.ImageTesting object at 0xffff8b917e50>
result_fname = '/builddir/build/BUILD/Cartopy-0.18.0/cartopy_test_output/test_gridliner/result-gridliner_labels_inline.png'
expected_fname = '/builddir/build/BUILDROOT/python-cartopy-0.18.0-4.fc34.aarch64/usr/lib64/python3.9/site-packages/cartopy/tests/mpl/baseline_images/mpl/test_gridliner/gridliner_labels_inline.png'
tol = 10.2
    def do_compare(self, result_fname, expected_fname, tol):
        """
        Runs the comparison of the result file with the expected file.
    
        If an RMS difference greater than ``tol`` is found an assertion
        error is raised with an appropriate message with the paths to
        the files concerned.
    
        """
        if not os.path.exists(expected_fname):
            warnings.warn('Created image in %s' % expected_fname)
            shutil.copy2(result_fname, expected_fname)
    
        err = mcompare.compare_images(expected_fname, result_fname,
                                      tol=tol, in_decorator=True)
    
        if err:
            msg = ('Images were different (RMS: %s).\n%s %s %s\nConsider '
                   'running idiff to inspect these differences.'
                   '' % (err['rms'], err['actual'],
                         err['expected'], err['diff']))
>           assert False, msg
E           AssertionError: Images were different (RMS: 10.7704958823).
E           /builddir/build/BUILD/Cartopy-0.18.0/cartopy_test_output/test_gridliner/result-gridliner_labels_inline.png /builddir/build/BUILDROOT/python-cartopy-0.18.0-4.fc34.aarch64/usr/lib64/python3.9/site-packages/cartopy/tests/mpl/baseline_images/mpl/test_gridliner/gridliner_labels_inline.png /builddir/build/BUILD/Cartopy-0.18.0/cartopy_test_output/test_gridliner/result-gridliner_labels_inline-failed-diff.png
E           Consider running idiff to inspect these differences.
../../BUILDROOT/python-cartopy-0.18.0-4.fc34.aarch64/usr/lib64/python3.9/site-packages/cartopy/tests/mpl/__init__.py:196: AssertionError
------------------------------ Captured log call -------------------------------
WARNING  matplotlib.testing:__init__.py:40 Could not set locale to English/United States. Some date-related tests may fail.
_________________________ test_grid_labels_inline_usa __________________________
args = (), kwargs = {}, orig_backend = 'agg'
style_context = <function context at 0xffff91a383a0>, r = None
figures = [<Figure size 2800x2800 with 23 Axes>]
figure = <Figure size 2800x2800 with 23 Axes>
    def wrapped(*args, **kwargs):
        orig_backend = plt.get_backend()
        plt.switch_backend('agg')
        mpl_setup()
    
        if plt.get_fignums():
            warnings.warn('Figures existed before running the %s %s test.'
                          ' All figures should be closed after they run. '
                          'They will be closed automatically now.' %
                          (mod_name, test_name))
            plt.close('all')
    
        if MPL_VERSION >= '2':
            style_context = mpl.style.context
        else:
            @contextlib.contextmanager
            def style_context(style, after_reset=False):
                yield
    
        with style_context(self.style):
            if MPL_VERSION >= '3.2.0':
                mpl.rcParams['text.kerning_factor'] = 6
    
            r = test_func(*args, **kwargs)
    
            figures = [plt.figure(num) for num in plt.get_fignums()]
    
            try:
>               self.run_figure_comparisons(figures, test_name=mod_name)
../../BUILDROOT/python-cartopy-0.18.0-4.fc34.aarch64/usr/lib64/python3.9/site-packages/cartopy/tests/mpl/__init__.py:236: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
../../BUILDROOT/python-cartopy-0.18.0-4.fc34.aarch64/usr/lib64/python3.9/site-packages/cartopy/tests/mpl/__init__.py:162: in run_figure_comparisons
    self.do_compare(result_path, expected_path, self.tolerance)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
self = <cartopy.tests.mpl.ImageTesting object at 0xffff8b917250>
result_fname = '/builddir/build/BUILD/Cartopy-0.18.0/cartopy_test_output/test_gridliner/result-gridliner_labels_inline_usa.png'
expected_fname = '/builddir/build/BUILDROOT/python-cartopy-0.18.0-4.fc34.aarch64/usr/lib64/python3.9/site-packages/cartopy/tests/mpl/baseline_images/mpl/test_gridliner/gridliner_labels_inline_usa.png'
tol = 11.5
    def do_compare(self, result_fname, expected_fname, tol):
        """
        Runs the comparison of the result file with the expected file.
    
        If an RMS difference greater than ``tol`` is found an assertion
        error is raised with an appropriate message with the paths to
        the files concerned.
    
        """
        if not os.path.exists(expected_fname):
            warnings.warn('Created image in %s' % expected_fname)
            shutil.copy2(result_fname, expected_fname)
    
        err = mcompare.compare_images(expected_fname, result_fname,
                                      tol=tol, in_decorator=True)
    
        if err:
            msg = ('Images were different (RMS: %s).\n%s %s %s\nConsider '
                   'running idiff to inspect these differences.'
                   '' % (err['rms'], err['actual'],
                         err['expected'], err['diff']))
>           assert False, msg
E           AssertionError: Images were different (RMS: 12.6053780489).
E           /builddir/build/BUILD/Cartopy-0.18.0/cartopy_test_output/test_gridliner/result-gridliner_labels_inline_usa.png /builddir/build/BUILDROOT/python-cartopy-0.18.0-4.fc34.aarch64/usr/lib64/python3.9/site-packages/cartopy/tests/mpl/baseline_images/mpl/test_gridliner/gridliner_labels_inline_usa.png /builddir/build/BUILD/Cartopy-0.18.0/cartopy_test_output/test_gridliner/result-gridliner_labels_inline_usa-failed-diff.png
E           Consider running idiff to inspect these differences.
../../BUILDROOT/python-cartopy-0.18.0-4.fc34.aarch64/usr/lib64/python3.9/site-packages/cartopy/tests/mpl/__init__.py:196: AssertionError

Comment 1 Fedora Release Engineering 2021-01-24 04:22:57 UTC
Dear Maintainer,

your package has an open Fails To Build From Source bug for Fedora 34.
Action is required from you.

If you can fix your package to build, perform a build in koji, and either create
an update in bodhi, or close this bug without creating an update, if updating is
not appropriate [1]. If you are working on a fix, set the status to ASSIGNED to
acknowledge this. If you have already fixed this issue, please close this Bugzilla report.

Following the policy for such packages [2], your package will be orphaned if
this bug remains in NEW state more than 8 weeks (not sooner than 2021-03-10).

A week before the mass branching of Fedora 35 according to the schedule [3],
any packages not successfully rebuilt at least on Fedora 33 will be
retired regardless of the status of this bug.

[1] https://docs.fedoraproject.org/en-US/fesco/Updates_Policy/
[2] https://docs.fedoraproject.org/en-US/fesco/Fails_to_build_from_source_Fails_to_install/
[3] https://fedorapeople.org/groups/schedule/f-35/f-35-key-tasks.html

Comment 2 Jos de Kloe 2021-01-27 20:44:01 UTC
Rebuilding python-cartopy-0.18.0-4.fc34.src.rpm using:
   mock -r fedora-rawhide-x86_64 --rebuild python-cartopy-0.18.0-4.fc34.src.rpm 
I can reproduce the failing testcases locally.

Stepping into the mock-shell and replaying the first test like this:

mock -r  fedora-rawhide-x86_64  --no-clean --shell

export PYTHONPATH=/builddir/build/BUILDROOT/python-cartopy-0.18.0-4.fc34.x86_64/usr/lib64/python3.9/site-packages/

import pytest
import cartopy.crs as ccrs
globe = ccrs.Globe(ellipse='WGS84')
with pytest.warns(UserWarning,match='does not handle elliptical globes.') as w:
    mill = ccrs.Miller(globe=globe)
    print(w._list[0])
    print(w._list[1])

shows that there are indeed 2 warnings in w:

{message : DeprecationWarning('`np.float` is a deprecated alias for the builtin `float`. Use `float` by itself, which is identical in behavior, to silence this warning. If you specifically wanted the numpy scalar type, use `np.float_` here.'), category : 'DeprecationWarning', filename : '/builddir/build/BUILDROOT/python-cartopy-0.18.0-4.fc34.x86_64/usr/lib64/python3.9/site-packages/cartopy/crs.py', lineno : 1342, line : None}
{message : UserWarning('The "Miller" projection does not handle elliptical globes.'), category : 'UserWarning', filename : '/builddir/build/BUILDROOT/python-cartopy-0.18.0-4.fc34.x86_64/usr/lib64/python3.9/site-packages/cartopy/crs.py', lineno : 665, line : None}

So it seems the match argument to the pytest.warns function records both the unexpected DeprecationWarning warning and the UserWarning that is to be tested here.

According to https://docs.pytest.org/en/stable/warnings.html#ensuring-function-triggers this setting: warnings.simplefilter("always") is needexd to catch Deprecation warnings, and indeed the method  __enter__ of the class WarningsRecorder does execute this setting, see: https://github.com/pytest-dev/pytest/blob/master/src/_pytest/recwarn.py

I am not sure if it is a recent change in the pytest.warns implementation or if it was like this al along, but clearly the DeprecationWarning issued by numpy triggered this test failure, and probably some of the others as well.

Comment 3 Jos de Kloe 2021-01-28 08:42:14 UTC
Patching lib/cartopy/crs.py and replacing the 10 occurrences of np.float() by a plain float() fixes the first 4 failing tests, executed by cartopy/tests/crs/test_miller.py and cartopy/tests/crs/test_orthographic.py. The other failures remain.

Comment 4 Jos de Kloe 2021-01-30 15:00:16 UTC
Remaining failures are: 
* tolerance for image comparisions need yet to be widened a bit
* tests/mpl/test_gridliner.py::test_grid_labels is suffering from a bug that is not yet fixed upstream.

If the main maintainer agrees, I can submit an update that fixes the first 2 issues, and disables the problematic test case.

Comment 5 Elliott Sales de Andrade 2021-02-03 07:04:26 UTC
Thanks for taking care of that.


Note You need to log in before you can comment on or make changes to this bug.