summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWaylan Limberg <waylan.limberg@icloud.com>2022-05-27 09:13:09 -0400
committerGitHub <noreply@github.com>2022-05-27 09:13:09 -0400
commita767b2daaad78ba32d45a4f1dabb7c5e218f030a (patch)
tree0a395d3751ed27fdbebc1c64a565384e5048b3cb
parentdc434df776fe9af36fe07c4e782e51035ce30e1f (diff)
downloadpython-markdown-a767b2daaad78ba32d45a4f1dabb7c5e218f030a.tar.gz
Remove previously deprecated objects
This completely removes all objects which were deprecated in version 3.0 (this change will be included in version 3.4). Given the time that has passed, and the fact that older unmaintained extensions are not likely to support the new minimum Python version, this is little concern about breaking older extensions.
-rw-r--r--docs/change_log/release-3.4.md28
-rw-r--r--markdown/__init__.py31
-rw-r--r--markdown/blockparser.py6
-rw-r--r--markdown/core.py2
-rw-r--r--markdown/extensions/__init__.py21
-rw-r--r--markdown/extensions/smarty.py8
-rw-r--r--markdown/inlinepatterns.py6
-rw-r--r--markdown/treeprocessors.py6
-rw-r--r--markdown/util.py106
-rw-r--r--tests/test_apis.py114
10 files changed, 36 insertions, 292 deletions
diff --git a/docs/change_log/release-3.4.md b/docs/change_log/release-3.4.md
index a795734..ade0ff8 100644
--- a/docs/change_log/release-3.4.md
+++ b/docs/change_log/release-3.4.md
@@ -30,6 +30,34 @@ markdown.markdown(src, extensions=[TableExtension(use_align_attribute=True)])
In addition, tests were moved to the modern test environment.
+### Previously deprecated objects have been removed
+
+Various objects were deprecated in version 3.0 and began raising deprecation
+warnings (see the [version 3.0 release notes] for details). Any of those object
+which remained in version 3.3 have been removed from the codebase in version 3.4
+and will now raise errors. A summary of the objects are provided below.
+
+[version 3.0 release notes]: release-3.0.md
+
+| Deprecated Object | Replacement Object |
+|----------------------------------------|-------------------------------------|
+| `markdown.version` | `markdown.__version__` |
+| `markdown.version_info` | `markdown.__version_info__` |
+| `markdown.util.etree` | `xml.etree.ElementTree` |
+| `markdown.util.string_type` | `str` |
+| `markdown.util.text_type` | `str` |
+| `markdown.util.int2str` | `chr` |
+| `markdown.util.iterrange` | `range` |
+| `markdown.util.isBlockLevel` | `markdown.Markdown.is_block_level` |
+| `markdown.util.Processor().markdown` | `markdown.util.Processor().md` |
+| `markdown.util.Registry().__setitem__` | `markdown.util.Registry().register` |
+| `markdown.util.Registry().__delitem__` |`markdown.util.Registry().deregister`|
+| `markdown.util.Registry().add` | `markdown.util.Registry().register` |
+
+In addition, the `md_globals` parameter of
+`Markdown.extensions.Extension.extendMarkdown()` is no longer recognized as a
+valid parameter and will raise an error if provided.
+
## New features
The following new features have been included in the 3.4 release:
diff --git a/markdown/__init__.py b/markdown/__init__.py
index 7760a0c..d88b1e9 100644
--- a/markdown/__init__.py
+++ b/markdown/__init__.py
@@ -19,37 +19,10 @@ Copyright 2004 Manfred Stienstra (the original version)
License: BSD (see LICENSE.md for details).
"""
-import sys
-
-# TODO: Remove this check at some point in the future.
-# (also remove flake8's 'ignore E402' comments below)
-if sys.version_info[0] < 3: # pragma: no cover
- raise ImportError('A recent version of Python 3 is required.')
-
-from .core import Markdown, markdown, markdownFromFile # noqa: E402
-from .__meta__ import __version__, __version_info__ # noqa: E402
-import warnings # noqa: E402
+from .core import Markdown, markdown, markdownFromFile
+from .__meta__ import __version__, __version_info__ # noqa
# For backward compatibility as some extensions expect it...
from .extensions import Extension # noqa
__all__ = ['Markdown', 'markdown', 'markdownFromFile']
-
-__deprecated__ = {
- "version": ("__version__", __version__),
- "version_info": ("__version_info__", __version_info__)
-}
-
-
-def __getattr__(name):
- """Get attribute."""
-
- deprecated = __deprecated__.get(name)
- if deprecated:
- warnings.warn(
- "'{}' is deprecated. Use '{}' instead.".format(name, deprecated[0]),
- category=DeprecationWarning,
- stacklevel=(3 if (3, 7) <= sys.version_info else 4)
- )
- return deprecated[1]
- raise AttributeError("module '{}' has no attribute '{}'".format(__name__, name))
diff --git a/markdown/blockparser.py b/markdown/blockparser.py
index 39219fd..b0ca4b1 100644
--- a/markdown/blockparser.py
+++ b/markdown/blockparser.py
@@ -69,12 +69,6 @@ class BlockParser:
self.state = State()
self.md = md
- @property
- @util.deprecated("Use 'md' instead.")
- def markdown(self):
- # TODO: remove this later
- return self.md
-
def parseDocument(self, lines):
""" Parse a markdown document into an ElementTree.
diff --git a/markdown/core.py b/markdown/core.py
index 3ed674a..f6a171c 100644
--- a/markdown/core.py
+++ b/markdown/core.py
@@ -122,7 +122,7 @@ class Markdown:
if isinstance(ext, str):
ext = self.build_extension(ext, configs.get(ext, {}))
if isinstance(ext, Extension):
- ext._extendMarkdown(self)
+ ext.extendMarkdown(self)
logger.debug(
'Successfully loaded extension "%s.%s".'
% (ext.__class__.__module__, ext.__class__.__name__)
diff --git a/markdown/extensions/__init__.py b/markdown/extensions/__init__.py
index 4712e25..2d8d72a 100644
--- a/markdown/extensions/__init__.py
+++ b/markdown/extensions/__init__.py
@@ -19,7 +19,6 @@ Copyright 2004 Manfred Stienstra (the original version)
License: BSD (see LICENSE.md for details).
"""
-import warnings
from ..util import parseBoolValue
@@ -70,24 +69,6 @@ class Extension:
for key, value in items:
self.setConfig(key, value)
- def _extendMarkdown(self, *args):
- """ Private wrapper around extendMarkdown. """
- md = args[0]
- try:
- self.extendMarkdown(md)
- except TypeError as e:
- if "missing 1 required positional argument" in str(e):
- # Must be a 2.x extension. Pass in a dumby md_globals.
- self.extendMarkdown(md, {})
- warnings.warn(
- "The 'md_globals' parameter of '{}.{}.extendMarkdown' is "
- "deprecated.".format(self.__class__.__module__, self.__class__.__name__),
- category=DeprecationWarning,
- stacklevel=2
- )
- else:
- raise
-
def extendMarkdown(self, md):
"""
Add the various processors and patterns to the Markdown Instance.
@@ -98,8 +79,6 @@ class Extension:
* md: The Markdown instance.
- * md_globals: Global variables in the markdown module namespace.
-
"""
raise NotImplementedError(
'Extension "%s.%s" must define an "extendMarkdown"'
diff --git a/markdown/extensions/smarty.py b/markdown/extensions/smarty.py
index 894805f..c4bfd58 100644
--- a/markdown/extensions/smarty.py
+++ b/markdown/extensions/smarty.py
@@ -83,7 +83,7 @@ smartypants.py license:
from . import Extension
from ..inlinepatterns import HtmlInlineProcessor, HTML_RE
from ..treeprocessors import InlineProcessor
-from ..util import Registry, deprecated
+from ..util import Registry
# Constants for quote education.
@@ -155,12 +155,6 @@ class SubstituteTextPattern(HtmlInlineProcessor):
self.replace = replace
self.md = md
- @property
- @deprecated("Use 'md' instead.")
- def markdown(self):
- # TODO: remove this later
- return self.md
-
def handleMatch(self, m, data):
result = ''
for part in self.replace:
diff --git a/markdown/inlinepatterns.py b/markdown/inlinepatterns.py
index eb74f49..eb313bd 100644
--- a/markdown/inlinepatterns.py
+++ b/markdown/inlinepatterns.py
@@ -211,12 +211,6 @@ class Pattern: # pragma: no cover
self.md = md
- @property
- @util.deprecated("Use 'md' instead.")
- def markdown(self):
- # TODO: remove this later
- return self.md
-
def getCompiledRegExp(self):
""" Return a compiled regular expression. """
return self.compiled_re
diff --git a/markdown/treeprocessors.py b/markdown/treeprocessors.py
index 99490bf..7767347 100644
--- a/markdown/treeprocessors.py
+++ b/markdown/treeprocessors.py
@@ -75,12 +75,6 @@ class InlineProcessor(Treeprocessor):
self.inlinePatterns = md.inlinePatterns
self.ancestors = []
- @property
- @util.deprecated("Use 'md' instead.")
- def markdown(self):
- # TODO: remove this later
- return self.md
-
def __makePlaceholder(self, type):
""" Generate a placeholder """
id = "%04d" % len(self.stashed_nodes)
diff --git a/markdown/util.py b/markdown/util.py
index 6d3a195..e6b08e5 100644
--- a/markdown/util.py
+++ b/markdown/util.py
@@ -22,22 +22,11 @@ License: BSD (see LICENSE.md for details).
import re
import sys
import warnings
-import xml.etree.ElementTree
from collections import namedtuple
from functools import wraps, lru_cache
from itertools import count
-# TODO: Remove deprecated variables in a future release.
-__deprecated__ = {
- 'etree': ('xml.etree.ElementTree', xml.etree.ElementTree),
- 'string_type': ('str', str),
- 'text_type': ('str', str),
- 'int2str': ('chr', chr),
- 'iterrange': ('range', range)
-}
-
-
"""
Constants you might want to modify
-----------------------------------------------------------------------------
@@ -121,15 +110,6 @@ def deprecated(message, stacklevel=2):
return wrapper
-@deprecated("Use 'Markdown.is_block_level' instead.")
-def isBlockLevel(tag):
- """Check if the tag is a block level HTML tag."""
- if isinstance(tag, str):
- return tag.lower().rstrip('/') in BLOCK_LEVEL_ELEMENTS
- # Some ElementTree tags are not strings, so return False.
- return False
-
-
def parseBoolValue(value, fail_on_errors=True, preserve_none=False):
"""Parses a string representing bool value. If parsing was successful,
returns True or False. If preserve_none=True, returns True, False,
@@ -191,12 +171,6 @@ class Processor:
def __init__(self, md=None):
self.md = md
- @property
- @deprecated("Use 'md' instead.")
- def markdown(self):
- # TODO: remove this later
- return self.md
-
class HtmlStash:
"""
@@ -382,83 +356,3 @@ class Registry:
if not self._is_sorted:
self._priority.sort(key=lambda item: item.priority, reverse=True)
self._is_sorted = True
-
- # Deprecated Methods which provide a smooth transition from OrderedDict
-
- @deprecated('Use the `register` method instead.')
- def __setitem__(self, key, value):
- """ Register item with priority 5 less than lowest existing priority. """
- if isinstance(key, str):
- if key in self:
- # Key already exists, replace without altering priority
- self._data[key] = value
- return
- if len(self) == 0:
- # This is the first item. Set priority to 50.
- priority = 50
- else:
- self._sort()
- priority = self._priority[-1].priority - 5
- self.register(value, key, priority)
- else:
- raise TypeError
-
- @deprecated('Use the `deregister` method instead.')
- def __delitem__(self, key):
- """ Deregister an item by name. """
- if key in self:
- self.deregister(key)
- else:
- raise KeyError('Cannot delete key {}, not registered.'.format(key))
-
- @deprecated('Use the `register` method instead.')
- def add(self, key, value, location):
- """ Register a key by location. """
- if len(self) == 0:
- # This is the first item. Set priority to 50.
- priority = 50
- elif location == '_begin':
- self._sort()
- # Set priority 5 greater than highest existing priority
- priority = self._priority[0].priority + 5
- elif location == '_end':
- self._sort()
- # Set priority 5 less than lowest existing priority
- priority = self._priority[-1].priority - 5
- elif location.startswith('<') or location.startswith('>'):
- # Set priority halfway between existing priorities.
- i = self.get_index_for_name(location[1:])
- if location.startswith('<'):
- after = self._priority[i].priority
- if i > 0:
- before = self._priority[i-1].priority
- else:
- # Location is first item`
- before = after + 10
- else:
- # location.startswith('>')
- before = self._priority[i].priority
- if i < len(self) - 1:
- after = self._priority[i+1].priority
- else:
- # location is last item
- after = before - 10
- priority = before - ((before - after) / 2)
- else:
- raise ValueError('Not a valid location: "%s". Location key '
- 'must start with a ">" or "<".' % location)
- self.register(value, key, priority)
-
-
-def __getattr__(name):
- """Get attribute."""
-
- deprecated = __deprecated__.get(name)
- if deprecated:
- warnings.warn(
- "'{}' is deprecated. Use '{}' instead.".format(name, deprecated[0]),
- category=DeprecationWarning,
- stacklevel=(3 if (3, 7) <= sys.version_info else 4)
- )
- return deprecated[1]
- raise AttributeError("module '{}' has no attribute '{}'".format(__name__, name))
diff --git a/tests/test_apis.py b/tests/test_apis.py
index efdc383..1a38be6 100644
--- a/tests/test_apis.py
+++ b/tests/test_apis.py
@@ -316,50 +316,16 @@ class RegistryTests(unittest.TestCase):
r = markdown.util.Registry()
with self.assertRaises(TypeError):
r[0] = 'a'
- # TODO: restore this when deprecated __setitem__ is removed.
- # with self.assertRaises(TypeError):
- # r['a'] = 'a'
- # TODO: remove this when deprecated __setitem__ is removed.
- with warnings.catch_warnings(record=True) as w:
- warnings.simplefilter("always")
-
- r['a'] = Item('a')
- self.assertEqual(list(r), ['a'])
- r['b'] = Item('b')
- self.assertEqual(list(r), ['a', 'b'])
- r['a'] = Item('a1')
- self.assertEqual(list(r), ['a1', 'b'])
-
- # Check the warnings
- self.assertEqual(len(w), 3)
- self.assertTrue(all(issubclass(x.category, DeprecationWarning) for x in w))
+ with self.assertRaises(TypeError):
+ r['a'] = 'a'
def testRegistryDelItem(self):
r = markdown.util.Registry()
r.register(Item('a'), 'a', 20)
- with self.assertRaises(KeyError):
+ with self.assertRaises(TypeError):
del r[0]
- # TODO: restore this when deprecated __del__ is removed.
- # with self.assertRaises(TypeError):
- # del r['a']
- # TODO: remove this when deprecated __del__ is removed.
- with warnings.catch_warnings(record=True) as w:
- warnings.simplefilter("always")
-
- r.register(Item('b'), 'b', 15)
- r.register(Item('c'), 'c', 10)
- del r['b']
- self.assertEqual(list(r), ['a', 'c'])
+ with self.assertRaises(TypeError):
del r['a']
- self.assertEqual(list(r), ['c'])
- with self.assertRaises(KeyError):
- del r['badname']
- del r['c']
- self.assertEqual(list(r), [])
-
- # Check the warnings
- self.assertEqual(len(w), 4)
- self.assertTrue(all(issubclass(x.category, DeprecationWarning) for x in w))
def testRegistrySlice(self):
r = markdown.util.Registry()
@@ -390,39 +356,6 @@ class RegistryTests(unittest.TestCase):
self.assertEqual(len(r), 2)
self.assertEqual(list(r), ['b2', 'a'])
- def testRegistryDeprecatedAdd(self):
- with warnings.catch_warnings(record=True) as w:
- warnings.simplefilter("always")
-
- r = markdown.util.Registry()
- # Add first item
- r.add('c', Item('c'), '_begin')
- self.assertEqual(list(r), ['c'])
- # Added to beginning
- r.add('b', Item('b'), '_begin')
- self.assertEqual(list(r), ['b', 'c'])
- # Add before first item
- r.add('a', Item('a'), '<b')
- self.assertEqual(list(r), ['a', 'b', 'c'])
- # Add before non-first item
- r.add('a1', Item('a1'), '<b')
- self.assertEqual(list(r), ['a', 'a1', 'b', 'c'])
- # Add after non-last item
- r.add('b1', Item('b1'), '>b')
- self.assertEqual(list(r), ['a', 'a1', 'b', 'b1', 'c'])
- # Add after last item
- r.add('d', Item('d'), '>c')
- self.assertEqual(list(r), ['a', 'a1', 'b', 'b1', 'c', 'd'])
- # Add to end
- r.add('e', Item('e'), '_end')
- self.assertEqual(list(r), ['a', 'a1', 'b', 'b1', 'c', 'd', 'e'])
- with self.assertRaises(ValueError):
- r.add('f', Item('f'), 'badlocation')
-
- # Check the warnings
- self.assertEqual(len(w), 8)
- self.assertTrue(all(issubclass(x.category, DeprecationWarning) for x in w))
-
class TestErrors(unittest.TestCase):
""" Test Error Reporting. """
@@ -1022,42 +955,3 @@ Some +test+ and a [+link+](http://test.com)
self.md.reset()
self.assertEqual(self.md.convert(test), result)
-
-
-class TestGeneralDeprecations(unittest.TestCase):
- """Test general deprecations."""
-
- def test_version_deprecation(self):
- """Test that version is deprecated."""
-
- with warnings.catch_warnings(record=True) as w:
- # Cause all warnings to always be triggered.
- warnings.simplefilter("always")
- # Trigger a warning.
- version = markdown.version
- # Verify some things
- self.assertEqual(len(w), 1)
- self.assertTrue(issubclass(w[-1].category, DeprecationWarning))
- self.assertEqual(version, markdown.__version__)
-
- def test_version_info_deprecation(self):
- """Test that version info is deprecated."""
-
- with warnings.catch_warnings(record=True) as w:
- # Cause all warnings to always be triggered.
- warnings.simplefilter("always")
- # Trigger a warning.
- version_info = markdown.version_info
- # Verify some things
- self.assertEqual(len(w), 1)
- self.assertTrue(issubclass(w[-1].category, DeprecationWarning))
- self.assertEqual(version_info, markdown.__version_info__)
-
- def test_deprecation_wrapper_dir(self):
- """Tests the `__dir__` attribute of the class as it replaces the module's."""
-
- dir_attr = dir(markdown)
- self.assertNotIn('version', dir_attr)
- self.assertIn('__version__', dir_attr)
- self.assertNotIn('version_info', dir_attr)
- self.assertIn('__version_info__', dir_attr)