Skip to content

Commit

Permalink
Merge pull request #1043 from sphinx-contrib/support-upcoming-sphinx-…
Browse files Browse the repository at this point in the history
…warnerr-changes

Support upcoming Sphinx warning-error changes
  • Loading branch information
jdknight authored Oct 6, 2024
2 parents 33305fd + bb45ff3 commit 8d2b4df
Show file tree
Hide file tree
Showing 8 changed files with 45 additions and 36 deletions.
1 change: 1 addition & 0 deletions sphinxcontrib/confluencebuilder/logger.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ def __init__(self):
self.messagelog = deque(maxlen=10)
self.verbosity = 0
self.warningiserror = False
self._exception_on_warning = False
self._warncount = 0

# fail silently if mocked application is missing something
Expand Down
7 changes: 2 additions & 5 deletions sphinxcontrib/confluencebuilder/publisher.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
https://docs.atlassian.com/confluence/REST/latest/
"""

from sphinx.util.logging import skip_warningiserror
from sphinxcontrib.confluencebuilder.config.exceptions import ConfluenceConfigError
from sphinxcontrib.confluencebuilder.debug import PublishDebug
from sphinxcontrib.confluencebuilder.exceptions import ConfluenceBadApiError
Expand Down Expand Up @@ -870,8 +869,7 @@ def store_attachment(self, page_id, name, data, mimetype, hash_, force=False):
# entry was created with corrupted data (i.e. can we query
# for an existing attachment). If we find it, re-attempt
# to publish the attachment.
with skip_warningiserror():
logger.warn('attachment failure (503); retrying...')
logger.info('attachment failure (503); retrying...')
time.sleep(0.5)
_, attachment = self.get_attachment(page_id, name)

Expand Down Expand Up @@ -1282,8 +1280,7 @@ def _update_page_properties(self, page_id, properties):
raise

# retry on conflict
with skip_warningiserror():
logger.warn('property update conflict; retrying...')
logger.info('property update conflict; retrying...')

attempt += 1
else:
Expand Down
13 changes: 5 additions & 8 deletions sphinxcontrib/confluencebuilder/rest.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
from email.utils import parsedate_tz
from functools import wraps
from requests.adapters import HTTPAdapter
from sphinx.util.logging import skip_warningiserror
from sphinxcontrib.confluencebuilder.debug import PublishDebug
from sphinxcontrib.confluencebuilder.exceptions import ConfluenceAuthenticationFailedUrlError
from sphinxcontrib.confluencebuilder.exceptions import ConfluenceBadApiError
Expand Down Expand Up @@ -131,10 +130,9 @@ def _wrapper(self, *args, **kwargs):
delay += random.uniform(0.0, 0.5) # noqa: S311

# wait the calculated delay before retrying again
with skip_warningiserror():
reported_delay = math.ceil(delay)
logger.warn('unexpected rest response detected; '
f'retrying in {reported_delay} seconds...')
reported_delay = math.ceil(delay)
logger.info('unexpected rest response detected; '
f'retrying in {reported_delay} seconds...')
time.sleep(delay)
attempt += 1

Expand Down Expand Up @@ -197,9 +195,8 @@ def _wrapper(self, *args, **kwargs):
delay += random.uniform(0.3, 1.3) # noqa: S311

# wait the calculated delay before retrying again
with skip_warningiserror():
logger.warn('rate-limit response detected; '
f'waiting {math.ceil(delay)} seconds...')
logger.info('rate-limit response detected; '
f'waiting {math.ceil(delay)} seconds...')
time.sleep(delay)
self.last_retry = delay
attempt += 1
Expand Down
31 changes: 21 additions & 10 deletions tests/lib/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
from contextlib import suppress
from copy import deepcopy
from pathlib import Path
from sphinx import version_info as sphinx_version_info
from sphinx.application import Sphinx
from sphinx.util.console import color_terminal
from sphinx.util.console import nocolor
Expand Down Expand Up @@ -618,18 +619,28 @@ def prepare_sphinx(src_dir, config=None, out_dir=None, extra_config=None,

doctrees_dir = out_dir / '.doctrees'

sphinx_args = {
'confoverrides': conf, # load provided configuration (volatile)
'status': sts, # status output
'warning': sys.stderr, # warnings output
'warningiserror': warnerr, # treat warnings as errors
'verbosity': verbosity, # verbosity
}

# As of Sphinx v8.1.x, warnings will no longer generate exceptions by
# default. Force enable them as we rely on these exception events for
# various unit tests.
if sphinx_version_info >= (8, 1, 0):
sphinx_args['exception_on_warning'] = warnerr

with docutils_namespace():
app = Sphinx(
str(src_dir), # output for document sources
conf_dir, # configuration directory
str(out_dir), # output for generated documents
str(doctrees_dir), # output for doctree files
builder, # builder to execute
confoverrides=conf, # load provided configuration (volatile)
status=sts, # status output
warning=sys.stderr, # warnings output
warningiserror=warnerr, # treat warnings as errors
verbosity=verbosity) # verbosity
str(src_dir), # output for document sources
conf_dir, # configuration directory
str(out_dir), # output for generated documents
str(doctrees_dir), # output for doctree files
builder, # builder to execute
**sphinx_args) # verbosity

yield app

Expand Down
8 changes: 5 additions & 3 deletions tests/unit-tests/test_config_checks.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,11 +42,12 @@ def _prepare_valid_publish(self):
'https://intranet-wiki.example.com/'
self.config['confluence_space_key'] = 'DUMMY'

def _try_config(self, config=None, edefs=None, dataset=None):
def _try_config(self, config=None, edefs=None, relax=None, dataset=None):
config = config if config else self.minimal_config
dataset = dataset if dataset else self.dataset

with prepare_sphinx(dataset, config=config, extra_config=edefs) as app:
with prepare_sphinx(dataset,
config=config, extra_config=edefs, relax=relax) as app:
env = BuildEnvironment(app)
builder = ConfluenceBuilder(app, env)

Expand Down Expand Up @@ -508,7 +509,8 @@ def mock_transform(lang):
return 'default'

self.config['confluence_lang_overrides'] = mock_transform
self._try_config()
self._try_config(relax=True)
# relax: since using transform is deprecated and will generate a warning

self.config['confluence_lang_overrides'] = 'invalid'
with self.assertRaises(ConfluenceConfigError):
Expand Down
3 changes: 2 additions & 1 deletion tests/unit-tests/test_sphinx_codeblock_highlight.py
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,8 @@ def test_override_lang_method(lang):
config['confluence_lang_overrides'] = test_override_lang_method

out_dir = self.build(self.dataset, config=config,
filenames=['code-block-highlight'])
filenames=['code-block-highlight'], relax=True)
# relax: since using transform is deprecated and will generate a warning

with parse('code-block-highlight', out_dir) as data:
expected = [
Expand Down
11 changes: 7 additions & 4 deletions tests/unit-tests/test_titles.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
# SPDX-License-Identifier: BSD-2-Clause
# Copyright Sphinx Confluence Builder Contributors (AUTHORS)

from sphinx.util.logging import skip_warningiserror
from sphinxcontrib.confluencebuilder.std.confluence import CONFLUENCE_MAX_TITLE_LEN
from sphinxcontrib.confluencebuilder.logger import ConfluenceLogger as logger
from sphinxcontrib.confluencebuilder.state import ConfluenceState
from sphinxcontrib.confluencebuilder.std.confluence import CONFLUENCE_MAX_TITLE_LEN
from tests.lib import MockedConfig
import unittest

Expand All @@ -13,9 +13,12 @@ def setUp(self):
ConfluenceState.reset()
self.config = MockedConfig()

# force (re-)initialize of logger to avoid logger being already
# configured with a warning-exception filter in a previous test
logger.initialize(preload=True)

def _register_title(self, title):
with skip_warningiserror():
return ConfluenceState.register_title('mock', title, self.config)
return ConfluenceState.register_title('mock', title, self.config)

def test_titles_maximum_checks_default(self):
t0 = self._register_title('S' * (CONFLUENCE_MAX_TITLE_LEN - 1))
Expand Down
7 changes: 2 additions & 5 deletions tests/unit-tests/test_unknown_node.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
from docutils import nodes
from docutils.parsers.rst import Directive
from sphinx.errors import SphinxWarning
from sphinx.util.logging import skip_warningiserror
from tests.lib.testcase import ConfluenceTestCase
from tests.lib.testcase import setup_builder

Expand Down Expand Up @@ -36,11 +35,9 @@ def test_unknown_node_default_completion(self):
# node to completion. A document should be built with the missing
# component, and no errors should result from this attempt.

with self.prepare(self.dataset) as app:
with self.prepare(self.dataset, relax=True) as app:
self._setup_app(app)

with skip_warningiserror():
app.build()
app.build()

@setup_builder('confluence')
def test_unknown_node_default_warning(self):
Expand Down

0 comments on commit 8d2b4df

Please sign in to comment.