Note: This is a public test instance of Red Hat Bugzilla. The data contained within is a snapshot of the live data so any changes you make will not be reflected in the production Bugzilla. Email is disabled so feel free to test any aspect of the site that you want. File any problems you find or give feedback at bugzilla.redhat.com.

Bug 1915665

Summary: python-cartopy: FTBFS in Fedora rawhide
Product: [Fedora] Fedora Reporter: Tomáš Hrnčiar <thrnciar>
Component: python-cartopyAssignee: Elliott Sales de Andrade <quantum.analyst>
Status: CLOSED RAWHIDE QA Contact: Fedora Extras Quality Assurance <extras-qa>
Severity: unspecified Docs Contact:
Priority: unspecified    
Version: rawhideCC: josdekloe, python-sig, quantum.analyst
Target Milestone: ---   
Target Release: ---   
Hardware: Unspecified   
OS: Unspecified   
URL: https://koschei.fedoraproject.org/package/python-cartopy
Whiteboard:
Fixed In Version: Doc Type: If docs needed, set a value
Doc Text:
Story Points: ---
Clone Of: Environment:
Last Closed: 2021-02-03 06:37:01 UTC Type: Bug
Regression: --- Mount Type: ---
Documentation: --- CRM:
Verified Versions: Category: ---
oVirt Team: --- RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: --- Target Upstream Version:
Embargoed:
Bug Depends On:    
Bug Blocks: 1868278, 1890881    

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.