diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml new file mode 100644 index 0000000..98af427 --- /dev/null +++ b/.github/workflows/build.yml @@ -0,0 +1,38 @@ +# For more information see: https://docs.github.com/en/actions/guides/building-and-testing-python + +name: Build and test + +on: + push: + branches: '**' + pull_request: + branches: [ master ] + +jobs: + build: + runs-on: ubuntu-latest + strategy: + matrix: + python-version: [2.7, 3.5, 3.7, 3.9, pypy3] + # don't cancel every other job if one fails + fail-fast: false + + steps: + - uses: actions/checkout@v2 + - name: Set up Python ${{ matrix.python-version }} + uses: actions/setup-python@v2 + with: + python-version: ${{ matrix.python-version }} + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install pytest wheel + pip install -e . + - name: Set up pokedex + run: pokedex setup -v + - name: Test with pytest + run: pytest + - name: Dump database and check for differences + run: | + pokedex dump + git --no-pager diff --exit-code pokedex/data/csv/ diff --git a/conftest.py b/conftest.py index a1d0c76..86e4bcd 100644 --- a/conftest.py +++ b/conftest.py @@ -21,6 +21,9 @@ def pytest_runtest_setup(item): if 'slow' in item.keywords and not item.config.getvalue('all'): pytest.skip("skipping slow tests") +def pytest_configure(config): + config.addinivalue_line("markers", "slow: marks tests as slow (require --all to run)") + @pytest.fixture(scope="module") def session(request): import pokedex.db diff --git a/pokedex/db/load.py b/pokedex/db/load.py index b787672..631fc9b 100644 --- a/pokedex/db/load.py +++ b/pokedex/db/load.py @@ -441,10 +441,12 @@ def dump(session, tables=[], directory=None, verbose=False, langs=None): # CSV module only works with bytes on 2 and only works with text on 3! if six.PY3: - writer = csv.writer(open(filename, 'w', newline='', encoding="utf8"), lineterminator='\n') + csvfile = open(filename, 'w', newline='', encoding="utf8") + writer = csv.writer(csvfile, lineterminator='\n') columns = [col.name for col in table.columns] else: - writer = csv.writer(open(filename, 'wb'), lineterminator='\n') + csvfile = open(filename, 'wb') + writer = csv.writer(csvfile, lineterminator='\n') columns = [col.name.encode('utf8') for col in table.columns] # For name tables, always dump rows for official languages, as well as @@ -491,4 +493,5 @@ def dump(session, tables=[], directory=None, verbose=False, langs=None): writer.writerow(csvs) + csvfile.close() print_done() diff --git a/pokedex/db/markdown.py b/pokedex/db/markdown.py index 115faa4..4873118 100644 --- a/pokedex/db/markdown.py +++ b/pokedex/db/markdown.py @@ -11,17 +11,14 @@ which case it is replaced by the name of the thing linked to. """ from __future__ import absolute_import +import sys import re import markdown import six from sqlalchemy.orm.session import object_session -try: - # Markdown 2.1+ - from markdown.util import etree, AtomicString -except ImportError: - # Old Markdown - from markdown import etree, AtomicString +from markdown.util import etree, AtomicString + @six.python_2_unicode_compatible class MarkdownString(object): @@ -66,8 +63,7 @@ class MarkdownString(object): extension = self.session.markdown_extension md = markdown.Markdown( - extensions=['extra', extension], - safe_mode='escape', + extensions=['markdown.extensions.extra', EscapeHtml(), extension], output_format='xhtml1', ) @@ -164,7 +160,10 @@ class PokedexLinkPattern(markdown.inlinepatterns.Pattern): Handles matches using factory """ - regex = u'(?x) \\[ ([^]]*) \\] \\{ ([-a-z0-9]+) : ([-a-z0-9 ]+) \\}' + if sys.version_info >= (3, 6): + regex = u'(?x: \\[ ([^]]*) \\] \\{ ([-a-z0-9]+) : ([-a-z0-9 ]+) \\} )' + else: + regex = u'(?x) \\[ ([^]]*) \\] \\{ ([-a-z0-9]+) : ([-a-z0-9 ]+) \\}' def __init__(self, factory, session, string_language=None, game_language=None): markdown.inlinepatterns.Pattern.__init__(self, self.regex) @@ -228,6 +227,17 @@ class PokedexLinkPattern(markdown.inlinepatterns.Pattern): el.text = AtomicString(label or name) return el +class EscapeHtml(markdown.Extension): + u"""Markdown extension which escapes raw html elements. + + This is the recommended replacement for safe_mode='escape', + which was deprecated in Markdown 2.5. + See https://python-markdown.github.io/change_log/release-2.5/ + """ + def extendMarkdown(self, md, md_globals): + del md.preprocessors['html_block'] + del md.inlinePatterns['html'] + class PokedexLinkExtension(markdown.Extension): u"""Markdown extension that translates the syntax used in effect text: diff --git a/setup.py b/setup.py index 0dfc0f7..16ac667 100644 --- a/setup.py +++ b/setup.py @@ -11,7 +11,7 @@ setup( install_requires=[ 'SQLAlchemy>=1.0,<1.4', 'whoosh>=2.5,<2.7', - 'markdown==2.4.1', + 'markdown>=2.4.1,<=2.6.11', 'construct==2.5.3', 'six>=1.9.0', ], @@ -22,8 +22,10 @@ setup( }, classifiers=[ "Programming Language :: Python :: 2.7", - "Programming Language :: Python :: 3.4", "Programming Language :: Python :: 3.5", + "Programming Language :: Python :: 3.6", "Programming Language :: Python :: 3.7", + "Programming Language :: Python :: 3.8", + "Programming Language :: Python :: 3.9", ] )