summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWaylan Limberg <waylan.limberg@icloud.com>2022-05-24 13:12:24 -0400
committerGitHub <noreply@github.com>2022-05-24 13:12:24 -0400
commitcebe1de23631a300167445bbb152c31615de9faf (patch)
treed41dd68ec4195ebb879880e0ec5697e1b6cf5395
parente958ec4141be98c7d04622f5f2cad5e60e765e53 (diff)
downloadpython-markdown-cebe1de23631a300167445bbb152c31615de9faf.tar.gz
Drop support for PY36
Python dropped support on 2021-12-23. Our policy (#760) is to drop support on the next point release after Python does. * Remove py36 tests * Test multiple recent versions of pypy * Remove pep562 backport
-rw-r--r--.coveragerc1
-rw-r--r--.github/workflows/tox.yml14
-rw-r--r--docs/change_log/release-3.4.md2
-rw-r--r--markdown/__init__.py8
-rw-r--r--markdown/__meta__.py2
-rw-r--r--markdown/pep562.py245
-rw-r--r--markdown/util.py10
-rwxr-xr-xsetup.py3
-rw-r--r--tox.ini3
9 files changed, 14 insertions, 274 deletions
diff --git a/.coveragerc b/.coveragerc
index c28a02a..c785d90 100644
--- a/.coveragerc
+++ b/.coveragerc
@@ -3,4 +3,3 @@ omit=
*site-packages*
tests/*
markdown/test_tools.py
- markdown/pep562.py
diff --git a/.github/workflows/tox.yml b/.github/workflows/tox.yml
index 08cbb49..e2004ad 100644
--- a/.github/workflows/tox.yml
+++ b/.github/workflows/tox.yml
@@ -20,10 +20,8 @@ jobs:
fail-fast: false
max-parallel: 4
matrix:
- tox-env: [py36, py37, py38, py39, py310, pypy3, pygments]
+ tox-env: [py37, py38, py39, py310, pypy37, pypy38, pypy39, pygments]
include:
- - tox-env: py36
- python-version: '3.6'
- tox-env: py37
python-version: '3.7'
- tox-env: py38
@@ -32,8 +30,12 @@ jobs:
python-version: '3.9'
- tox-env: py310
python-version: '3.10'
- - tox-env: pypy3
- python-version: pypy3
+ - tox-env: pypy37
+ python-version: pypy-3.7
+ - tox-env: pypy38
+ python-version: pypy-3.8
+ - tox-env: pypy39
+ python-version: pypy-3.9
- tox-env: pygments
python-version: '3.7'
@@ -43,7 +45,7 @@ jobs:
steps:
- uses: actions/checkout@v2
- name: Setup Python ${{ matrix.python-version }}
- uses: actions/setup-python@v2
+ uses: actions/setup-python@v3
with:
python-version: ${{ matrix.python-version }}
- name: Install dependencies
diff --git a/docs/change_log/release-3.4.md b/docs/change_log/release-3.4.md
index 7abdf5d..eb36b40 100644
--- a/docs/change_log/release-3.4.md
+++ b/docs/change_log/release-3.4.md
@@ -2,7 +2,7 @@ title: Release Notes for v3.4
# Python-Markdown 3.4 Release Notes
-Python-Markdown version 3.4 supports Python versions 3.6, 3.7, 3.8, 3.9, 3.10 and
+Python-Markdown version 3.4 supports Python versions 3.7, 3.8, 3.9, 3.10 and
PyPy3.
## Backwards-incompatible changes
diff --git a/markdown/__init__.py b/markdown/__init__.py
index e05af10..7760a0c 100644
--- a/markdown/__init__.py
+++ b/markdown/__init__.py
@@ -27,8 +27,6 @@ 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 .util import PY37 # noqa: E402
-from .pep562 import Pep562 # noqa: E402
from .__meta__ import __version__, __version_info__ # noqa: E402
import warnings # noqa: E402
@@ -51,11 +49,7 @@ def __getattr__(name):
warnings.warn(
"'{}' is deprecated. Use '{}' instead.".format(name, deprecated[0]),
category=DeprecationWarning,
- stacklevel=(3 if PY37 else 4)
+ stacklevel=(3 if (3, 7) <= sys.version_info else 4)
)
return deprecated[1]
raise AttributeError("module '{}' has no attribute '{}'".format(__name__, name))
-
-
-if not PY37:
- Pep562(__name__)
diff --git a/markdown/__meta__.py b/markdown/__meta__.py
index 84884b6..92dd5cf 100644
--- a/markdown/__meta__.py
+++ b/markdown/__meta__.py
@@ -26,7 +26,7 @@ License: BSD (see LICENSE.md for details).
# (1, 2, 0, 'beta', 2) => "1.2b2"
# (1, 2, 0, 'rc', 4) => "1.2rc4"
# (1, 2, 0, 'final', 0) => "1.2"
-__version_info__ = (3, 3, 7, 'final', 0)
+__version_info__ = (3, 4, 0, 'dev', 0)
def _get_version(version_info):
diff --git a/markdown/pep562.py b/markdown/pep562.py
deleted file mode 100644
index b130d3b..0000000
--- a/markdown/pep562.py
+++ /dev/null
@@ -1,245 +0,0 @@
-"""
-Backport of PEP 562.
-
-https://pypi.org/search/?q=pep562
-
-Licensed under MIT
-Copyright (c) 2018 Isaac Muse <isaacmuse@gmail.com>
-
-Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
-documentation files (the "Software"), to deal in the Software without restriction, including without limitation
-the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software,
-and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all copies or substantial portions
-of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
-TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
-CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
-IN THE SOFTWARE.
-"""
-import sys
-from collections import namedtuple
-import re
-
-__all__ = ('Pep562',)
-
-RE_VER = re.compile(
- r'''(?x)
- (?P<major>\d+)(?:\.(?P<minor>\d+))?(?:\.(?P<micro>\d+))?
- (?:(?P<type>a|b|rc)(?P<pre>\d+))?
- (?:\.post(?P<post>\d+))?
- (?:\.dev(?P<dev>\d+))?
- '''
-)
-
-REL_MAP = {
- ".dev": "",
- ".dev-alpha": "a",
- ".dev-beta": "b",
- ".dev-candidate": "rc",
- "alpha": "a",
- "beta": "b",
- "candidate": "rc",
- "final": ""
-}
-
-DEV_STATUS = {
- ".dev": "2 - Pre-Alpha",
- ".dev-alpha": "2 - Pre-Alpha",
- ".dev-beta": "2 - Pre-Alpha",
- ".dev-candidate": "2 - Pre-Alpha",
- "alpha": "3 - Alpha",
- "beta": "4 - Beta",
- "candidate": "4 - Beta",
- "final": "5 - Production/Stable"
-}
-
-PRE_REL_MAP = {"a": 'alpha', "b": 'beta', "rc": 'candidate'}
-
-
-class Version(namedtuple("Version", ["major", "minor", "micro", "release", "pre", "post", "dev"])):
- """
- Get the version (PEP 440).
-
- A biased approach to the PEP 440 semantic version.
-
- Provides a tuple structure which is sorted for comparisons `v1 > v2` etc.
- (major, minor, micro, release type, pre-release build, post-release build, development release build)
- Release types are named in is such a way they are comparable with ease.
- Accessors to check if a development, pre-release, or post-release build. Also provides accessor to get
- development status for setup files.
-
- How it works (currently):
-
- - You must specify a release type as either `final`, `alpha`, `beta`, or `candidate`.
- - To define a development release, you can use either `.dev`, `.dev-alpha`, `.dev-beta`, or `.dev-candidate`.
- The dot is used to ensure all development specifiers are sorted before `alpha`.
- You can specify a `dev` number for development builds, but do not have to as implicit development releases
- are allowed.
- - You must specify a `pre` value greater than zero if using a prerelease as this project (not PEP 440) does not
- allow implicit prereleases.
- - You can optionally set `post` to a value greater than zero to make the build a post release. While post releases
- are technically allowed in prereleases, it is strongly discouraged, so we are rejecting them. It should be
- noted that we do not allow `post0` even though PEP 440 does not restrict this. This project specifically
- does not allow implicit post releases.
- - It should be noted that we do not support epochs `1!` or local versions `+some-custom.version-1`.
-
- Acceptable version releases:
-
- ```
- Version(1, 0, 0, "final") 1.0
- Version(1, 2, 0, "final") 1.2
- Version(1, 2, 3, "final") 1.2.3
- Version(1, 2, 0, ".dev-alpha", pre=4) 1.2a4
- Version(1, 2, 0, ".dev-beta", pre=4) 1.2b4
- Version(1, 2, 0, ".dev-candidate", pre=4) 1.2rc4
- Version(1, 2, 0, "final", post=1) 1.2.post1
- Version(1, 2, 3, ".dev") 1.2.3.dev0
- Version(1, 2, 3, ".dev", dev=1) 1.2.3.dev1
- ```
-
- """
-
- def __new__(cls, major, minor, micro, release="final", pre=0, post=0, dev=0):
- """Validate version info."""
-
- # Ensure all parts are positive integers.
- for value in (major, minor, micro, pre, post):
- if not (isinstance(value, int) and value >= 0):
- raise ValueError("All version parts except 'release' should be integers.")
-
- if release not in REL_MAP:
- raise ValueError("'{}' is not a valid release type.".format(release))
-
- # Ensure valid pre-release (we do not allow implicit pre-releases).
- if ".dev-candidate" < release < "final":
- if pre == 0:
- raise ValueError("Implicit pre-releases not allowed.")
- elif dev:
- raise ValueError("Version is not a development release.")
- elif post:
- raise ValueError("Post-releases are not allowed with pre-releases.")
-
- # Ensure valid development or development/pre release
- elif release < "alpha":
- if release > ".dev" and pre == 0:
- raise ValueError("Implicit pre-release not allowed.")
- elif post:
- raise ValueError("Post-releases are not allowed with pre-releases.")
-
- # Ensure a valid normal release
- else:
- if pre:
- raise ValueError("Version is not a pre-release.")
- elif dev:
- raise ValueError("Version is not a development release.")
-
- return super().__new__(cls, major, minor, micro, release, pre, post, dev)
-
- def _is_pre(self):
- """Is prerelease."""
-
- return self.pre > 0
-
- def _is_dev(self):
- """Is development."""
-
- return bool(self.release < "alpha")
-
- def _is_post(self):
- """Is post."""
-
- return self.post > 0
-
- def _get_dev_status(self): # pragma: no cover
- """Get development status string."""
-
- return DEV_STATUS[self.release]
-
- def _get_canonical(self):
- """Get the canonical output string."""
-
- # Assemble major, minor, micro version and append `pre`, `post`, or `dev` if needed..
- if self.micro == 0:
- ver = "{}.{}".format(self.major, self.minor)
- else:
- ver = "{}.{}.{}".format(self.major, self.minor, self.micro)
- if self._is_pre():
- ver += '{}{}'.format(REL_MAP[self.release], self.pre)
- if self._is_post():
- ver += ".post{}".format(self.post)
- if self._is_dev():
- ver += ".dev{}".format(self.dev)
-
- return ver
-
-
-def parse_version(ver, pre=False):
- """Parse version into a comparable Version tuple."""
-
- m = RE_VER.match(ver)
-
- # Handle major, minor, micro
- major = int(m.group('major'))
- minor = int(m.group('minor')) if m.group('minor') else 0
- micro = int(m.group('micro')) if m.group('micro') else 0
-
- # Handle pre releases
- if m.group('type'):
- release = PRE_REL_MAP[m.group('type')]
- pre = int(m.group('pre'))
- else:
- release = "final"
- pre = 0
-
- # Handle development releases
- dev = m.group('dev') if m.group('dev') else 0
- if m.group('dev'):
- dev = int(m.group('dev'))
- release = '.dev-' + release if pre else '.dev'
- else:
- dev = 0
-
- # Handle post
- post = int(m.group('post')) if m.group('post') else 0
-
- return Version(major, minor, micro, release, pre, post, dev)
-
-
-class Pep562:
- """
- Backport of PEP 562 <https://pypi.org/search/?q=pep562>.
-
- Wraps the module in a class that exposes the mechanics to override `__dir__` and `__getattr__`.
- The given module will be searched for overrides of `__dir__` and `__getattr__` and use them when needed.
- """
-
- def __init__(self, name):
- """Acquire `__getattr__` and `__dir__`, but only replace module for versions less than Python 3.7."""
-
- self._module = sys.modules[name]
- self._get_attr = getattr(self._module, '__getattr__', None)
- self._get_dir = getattr(self._module, '__dir__', None)
- sys.modules[name] = self
-
- def __dir__(self):
- """Return the overridden `dir` if one was provided, else apply `dir` to the module."""
-
- return self._get_dir() if self._get_dir else dir(self._module)
-
- def __getattr__(self, name):
- """Attempt to retrieve the attribute from the module, and if missing, use the overridden function if present."""
-
- try:
- return getattr(self._module, name)
- except AttributeError:
- if self._get_attr:
- return self._get_attr(name)
- raise
-
-
-__version_info__ = Version(1, 0, 0, "final")
-__version__ = __version_info__._get_canonical()
diff --git a/markdown/util.py b/markdown/util.py
index a6a32bf..6d3a195 100644
--- a/markdown/util.py
+++ b/markdown/util.py
@@ -27,10 +27,6 @@ from collections import namedtuple
from functools import wraps, lru_cache
from itertools import count
-from .pep562 import Pep562
-
-PY37 = (3, 7) <= sys.version_info
-
# TODO: Remove deprecated variables in a future release.
__deprecated__ = {
@@ -462,11 +458,7 @@ def __getattr__(name):
warnings.warn(
"'{}' is deprecated. Use '{}' instead.".format(name, deprecated[0]),
category=DeprecationWarning,
- stacklevel=(3 if PY37 else 4)
+ stacklevel=(3 if (3, 7) <= sys.version_info else 4)
)
return deprecated[1]
raise AttributeError("module '{}' has no attribute '{}'".format(__name__, name))
-
-
-if not PY37:
- Pep562(__name__)
diff --git a/setup.py b/setup.py
index 24b01f6..c6eb6af 100755
--- a/setup.py
+++ b/setup.py
@@ -73,7 +73,7 @@ setup(
maintainer_email='python.markdown@gmail.com',
license='BSD License',
packages=['markdown', 'markdown.extensions'],
- python_requires='>=3.6',
+ python_requires='>=3.7',
install_requires=["importlib-metadata>=4.4;python_version<'3.10'"],
extras_require={
'testing': [
@@ -113,7 +113,6 @@ setup(
'Operating System :: OS Independent',
'Programming Language :: Python',
'Programming Language :: Python :: 3',
- 'Programming Language :: Python :: 3.6',
'Programming Language :: Python :: 3.7',
'Programming Language :: Python :: 3.8',
'Programming Language :: Python :: 3.9',
diff --git a/tox.ini b/tox.ini
index 62523f9..0c76754 100644
--- a/tox.ini
+++ b/tox.ini
@@ -1,5 +1,5 @@
[tox]
-envlist = py36, py37, py38, py39, py310, pypy3, pygments, flake8, checkspelling, pep517check, checklinks
+envlist = py{37, 38, 39, 310}, pypy{37, 38, 39}, pygments, flake8, checkspelling, pep517check, checklinks
isolated_build = True
[testenv]
@@ -41,4 +41,3 @@ skip_install = true
[flake8]
max-line-length = 119
-exclude=markdown/pep562.py