Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package python-docstring-to-markdown for 
openSUSE:Factory checked in at 2024-04-07 22:11:42
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-docstring-to-markdown (Old)
 and      /work/SRC/openSUSE:Factory/.python-docstring-to-markdown.new.1905 
(New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "python-docstring-to-markdown"

Sun Apr  7 22:11:42 2024 rev:6 rq:1165868 version:0.15

Changes:
--------
--- 
/work/SRC/openSUSE:Factory/python-docstring-to-markdown/python-docstring-to-markdown.changes
        2023-11-26 19:37:24.542395753 +0100
+++ 
/work/SRC/openSUSE:Factory/.python-docstring-to-markdown.new.1905/python-docstring-to-markdown.changes
      2024-04-07 22:13:58.308107118 +0200
@@ -1,0 +2,8 @@
+Sat Apr  6 19:10:13 UTC 2024 - Dirk Müller <dmuel...@suse.com>
+
+- update to 0.15:
+  * Fix multi-line links and incorrect dunder escapes in code
+- update to 0.14:
+  * Add plain text and cPython docstring support
+
+-------------------------------------------------------------------

Old:
----
  docstring-to-markdown-0.13-gh.tar.gz

New:
----
  docstring-to-markdown-0.15-gh.tar.gz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ python-docstring-to-markdown.spec ++++++
--- /var/tmp/diff_new_pack.iuZ50x/_old  2024-04-07 22:13:58.728122522 +0200
+++ /var/tmp/diff_new_pack.iuZ50x/_new  2024-04-07 22:13:58.728122522 +0200
@@ -1,7 +1,7 @@
 #
 # spec file for package python-docstring-to-markdown
 #
-# Copyright (c) 2023 SUSE LLC
+# Copyright (c) 2024 SUSE LLC
 #
 # All modifications and additions to the file contributed by third parties
 # remain the property of their copyright owners, unless otherwise agreed
@@ -19,7 +19,7 @@
 %{?sle15_python_module_pythons}
 
 Name:           python-docstring-to-markdown
-Version:        0.13
+Version:        0.15
 Release:        0
 Summary:        On the fly conversion of Python docstrings to markdown
 License:        LGPL-2.1-only

++++++ docstring-to-markdown-0.13-gh.tar.gz -> 
docstring-to-markdown-0.15-gh.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/docstring-to-markdown-0.13/.github/workflows/tests.yml 
new/docstring-to-markdown-0.15/.github/workflows/tests.yml
--- old/docstring-to-markdown-0.13/.github/workflows/tests.yml  2023-10-11 
21:43:03.000000000 +0200
+++ new/docstring-to-markdown-0.15/.github/workflows/tests.yml  2024-02-21 
14:50:11.000000000 +0100
@@ -12,9 +12,6 @@
       matrix:
         os: [ubuntu-latest]
         python-version: [3.7, 3.8, 3.9, '3.10', '3.11']
-        include:
-          - os: ubuntu-20.04
-            python-version: 3.6
     runs-on: ${{ matrix.os }}
     steps:
     - uses: actions/checkout@v2
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/docstring-to-markdown-0.13/README.md 
new/docstring-to-markdown-0.15/README.md
--- old/docstring-to-markdown-0.13/README.md    2023-10-11 21:43:03.000000000 
+0200
+++ new/docstring-to-markdown-0.15/README.md    2024-02-21 14:50:11.000000000 
+0100
@@ -6,7 +6,7 @@
 
 On the fly conversion of Python docstrings to markdown
 
-- Python 3.6+
+- Python 3.6+ (tested on 3.7 up to 3.11)
 - can recognise reStructuredText and convert multiple of its features to 
Markdown
 - since v0.13 includes initial support for Google-formatted docstrings
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/docstring-to-markdown-0.13/docstring_to_markdown/__init__.py 
new/docstring-to-markdown-0.15/docstring_to_markdown/__init__.py
--- old/docstring-to-markdown-0.13/docstring_to_markdown/__init__.py    
2023-10-11 21:43:03.000000000 +0200
+++ new/docstring-to-markdown-0.15/docstring_to_markdown/__init__.py    
2024-02-21 14:50:11.000000000 +0100
@@ -1,7 +1,9 @@
+from .cpython import cpython_to_markdown
 from .google import google_to_markdown, looks_like_google
+from .plain import looks_like_plain_text, plain_text_to_markdown
 from .rst import looks_like_rst, rst_to_markdown
 
-__version__ = "0.13"
+__version__ = "0.15"
 
 
 class UnknownFormatError(Exception):
@@ -15,4 +17,11 @@
     if looks_like_google(docstring):
         return google_to_markdown(docstring)
 
+    if looks_like_plain_text(docstring):
+        return plain_text_to_markdown(docstring)
+
+    cpython = cpython_to_markdown(docstring)
+    if cpython:
+        return cpython
+
     raise UnknownFormatError()
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/docstring-to-markdown-0.13/docstring_to_markdown/_utils.py 
new/docstring-to-markdown-0.15/docstring_to_markdown/_utils.py
--- old/docstring-to-markdown-0.13/docstring_to_markdown/_utils.py      
1970-01-01 01:00:00.000000000 +0100
+++ new/docstring-to-markdown-0.15/docstring_to_markdown/_utils.py      
2024-02-21 14:50:11.000000000 +0100
@@ -0,0 +1,5 @@
+from re import sub
+
+
+def escape_markdown(text: str) -> str:
+    return sub(r'([\\#*_[\]])', r'\\\1', text)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/docstring-to-markdown-0.13/docstring_to_markdown/cpython.py 
new/docstring-to-markdown-0.15/docstring_to_markdown/cpython.py
--- old/docstring-to-markdown-0.13/docstring_to_markdown/cpython.py     
1970-01-01 01:00:00.000000000 +0100
+++ new/docstring-to-markdown-0.15/docstring_to_markdown/cpython.py     
2024-02-21 14:50:11.000000000 +0100
@@ -0,0 +1,37 @@
+from typing import Union, List
+from re import fullmatch
+
+from ._utils import escape_markdown
+
+def _is_cpython_signature_line(line: str) -> bool:
+    """CPython uses signature lines in the following format:
+
+    str(bytes_or_buffer[, encoding[, errors]]) -> str
+    """
+    return fullmatch(r'\w+\(\S*(, \S+)*(\[, \S+\])*\)\s--?>\s.+', line) is not 
None
+
+
+def cpython_to_markdown(text: str) -> Union[str, None]:
+    signature_lines: List[str] = []
+    other_lines: List[str] = []
+    for line in text.splitlines():
+        if not other_lines and _is_cpython_signature_line(line):
+            signature_lines.append(line)
+        elif not signature_lines:
+            return None
+        elif line.startswith('    '):
+            signature_lines.append(line)
+        else:
+            other_lines.append(line)
+    return '\n'.join([
+        '```',
+        '\n'.join(signature_lines),
+        '```',
+        escape_markdown('\n'.join(other_lines))
+    ])
+
+def looks_like_cpython(text: str) -> bool:
+    return cpython_to_markdown(text) is not None
+
+
+__all__ = ['looks_like_cpython', 'cpython_to_markdown']
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/docstring-to-markdown-0.13/docstring_to_markdown/plain.py 
new/docstring-to-markdown-0.15/docstring_to_markdown/plain.py
--- old/docstring-to-markdown-0.13/docstring_to_markdown/plain.py       
1970-01-01 01:00:00.000000000 +0100
+++ new/docstring-to-markdown-0.15/docstring_to_markdown/plain.py       
2024-02-21 14:50:11.000000000 +0100
@@ -0,0 +1,27 @@
+from re import fullmatch
+from ._utils import escape_markdown
+
+
+def looks_like_plain_text(value: str) -> bool:
+    """Check if given string has plain text following English syntax without 
need for escaping.
+
+    Accepts:
+    - words without numbers
+    - full stop, bangs and question marks at the end of a word if followed by 
a space or end of string
+    - commas, colons and semicolons if after a word and followed by a space
+    - dashes between words (like in `e-mail`)
+    - double and single quotes if proceeded with a space and followed by a 
word, or if proceeded by a word and followed by a space (or end of string); 
single quotes are also allowed in between two words
+    - parentheses if opening preceded by space and closing followed by space 
or end
+
+    Does not accept:
+    - square brackets (used in markdown a lot)
+    """
+    if '_' in value:
+        return False
+    return 
fullmatch(r"((\w[\.!\?\)'\"](\s|$))|(\w[,:;]\s)|(\w[-']\w)|(\w\s['\"\(])|\w|\s)+",
 value) is not None
+
+
+def plain_text_to_markdown(text: str) -> str:
+    return escape_markdown(text)
+
+__all__ = ['looks_like_plain_text', 'plain_text_to_markdown']
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/docstring-to-markdown-0.13/docstring_to_markdown/rst.py 
new/docstring-to-markdown-0.15/docstring_to_markdown/rst.py
--- old/docstring-to-markdown-0.13/docstring_to_markdown/rst.py 2023-10-11 
21:43:03.000000000 +0200
+++ new/docstring-to-markdown-0.15/docstring_to_markdown/rst.py 2024-02-21 
14:50:11.000000000 +0100
@@ -1,13 +1,13 @@
 from abc import ABC, abstractmethod
 from enum import IntEnum, auto
 from types import SimpleNamespace
-from typing import Union, List, Dict
+from typing import Callable, Match, Union, List, Dict
 import re
 
 
 class Directive:
     def __init__(
-        self, pattern: str, replacement: str,
+        self, pattern: str, replacement: Union[str, Callable[[Match], str]],
         name: Union[str, None] = None,
         flags: int = 0
     ):
@@ -249,7 +249,7 @@
     ),
     Directive(
         pattern=r'`(?P<label>[^<`]+?)(\n?)<(?P<url>[^>`]+)>`_+',
-        replacement=r'[\g<label>](\g<url>)'
+        replacement=lambda m: '[' + m.group('label') + '](' + re.sub(r"\s+", 
"", m.group('url')) + ')'
     ),
     Directive(
         pattern=r':mod:`(?P<label>[^`]+)`',
@@ -316,7 +316,7 @@
 
 ESCAPING_RULES: List[Directive] = [
     Directive(
-        pattern=r'__(?P<text>\S+)__',
+        pattern=r'(?<!`)__(?P<text>\S+)__(?!`)',
         replacement=r'\_\_\g<text>\_\_'
     )
 ]
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/docstring-to-markdown-0.13/setup.cfg 
new/docstring-to-markdown-0.15/setup.cfg
--- old/docstring-to-markdown-0.13/setup.cfg    2023-10-11 21:43:03.000000000 
+0200
+++ new/docstring-to-markdown-0.15/setup.cfg    2024-02-21 14:50:11.000000000 
+0100
@@ -37,7 +37,7 @@
 addopts =
     --pyargs tests
     --cov docstring_to_markdown
-    --cov-fail-under=98
+    --cov-fail-under=99
     --cov-report term-missing:skip-covered
     -p no:warnings
     --flake8
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/docstring-to-markdown-0.13/tests/test_convert.py 
new/docstring-to-markdown-0.15/tests/test_convert.py
--- old/docstring-to-markdown-0.13/tests/test_convert.py        1970-01-01 
01:00:00.000000000 +0100
+++ new/docstring-to-markdown-0.15/tests/test_convert.py        2024-02-21 
14:50:11.000000000 +0100
@@ -0,0 +1,57 @@
+from docstring_to_markdown import convert, UnknownFormatError
+import pytest
+
+CPYTHON = """\
+bool(x) -> bool
+
+Returns True when the argument x is true, False otherwise.\
+"""
+
+
+CPYTHON_MD = """\
+```
+bool(x) -> bool
+```
+
+Returns True when the argument x is true, False otherwise.\
+"""
+
+GOOGLE = """Do **something**.
+
+Args:
+    a: some arg
+    b: some arg
+"""
+
+GOOGLE_MD = """Do **something**.
+
+#### Args
+
+- `a`: some arg
+- `b`: some arg
+"""
+
+
+RST = "Please see `this link<https://example.com>`__."
+RST_MD = "Please see [this link](https://example.com)."
+
+
+def test_convert_cpython():
+    assert convert(CPYTHON) == CPYTHON_MD
+
+
+def test_convert_plain_text():
+    assert convert('This is a sentence.') == 'This is a sentence.'
+
+
+def test_convert_google():
+    assert convert(GOOGLE) == GOOGLE_MD
+
+
+def test_convert_rst():
+    assert convert(RST) == RST_MD
+
+
+def test_unknown_format():
+    with pytest.raises(UnknownFormatError):
+        convert('ARGS [arg1, arg2] RETURNS: str OR None')
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/docstring-to-markdown-0.13/tests/test_cpython.py 
new/docstring-to-markdown-0.15/tests/test_cpython.py
--- old/docstring-to-markdown-0.13/tests/test_cpython.py        1970-01-01 
01:00:00.000000000 +0100
+++ new/docstring-to-markdown-0.15/tests/test_cpython.py        2024-02-21 
14:50:11.000000000 +0100
@@ -0,0 +1,103 @@
+import pytest
+from docstring_to_markdown.cpython import looks_like_cpython, 
cpython_to_markdown
+
+BOOL = """\
+bool(x) -> bool
+
+Returns True when the argument x is true, False otherwise.\
+"""
+
+BOOL_MD = """\
+```
+bool(x) -> bool
+```
+
+Returns True when the argument x is true, False otherwise.\
+"""
+
+BYTES = """\
+bytes(iterable_of_ints) -> bytes
+bytes(string, encoding[, errors]) -> bytes
+bytes(bytes_or_buffer) -> immutable copy of bytes_or_buffer
+bytes(int) -> bytes object of size given by the parameter initialized with 
null bytes
+bytes() -> empty bytes object
+
+Construct an immutable array of bytes from:
+  - an iterable yielding integers in range(256)
+  - a text string encoded using the specified encoding
+  - any object implementing the buffer API.
+  - an integer\
+"""
+
+COLLECTIONS_DEQUEUE = """\
+deque([iterable[, maxlen]]) --> deque object
+
+A list-like sequence optimized for data accesses near its endpoints.\
+"""
+
+DICT = """\
+dict() -> new empty dictionary
+dict(mapping) -> new dictionary initialized from a mapping object's
+    (key, value) pairs
+dict(iterable) -> new dictionary initialized as if via:
+    d = {}
+    for k, v in iterable:
+        d[k] = v
+dict(**kwargs) -> new dictionary initialized with the name=value pairs
+    in the keyword argument list.  For example:  dict(one=1, two=2)\
+"""
+
+STR = """\
+str(object='') -> str
+str(bytes_or_buffer[, encoding[, errors]]) -> str
+
+Create a new string object from the given object. If encoding or
+errors is specified, then the object must expose a data buffer
+that will be decoded using the given encoding and error handler.
+Otherwise, returns the result of object.__str__() (if defined)
+or repr(object).\
+"""
+
+STR_MD = """\
+```
+str(object='') -> str
+str(bytes_or_buffer[, encoding[, errors]]) -> str
+```
+
+Create a new string object from the given object. If encoding or
+errors is specified, then the object must expose a data buffer
+that will be decoded using the given encoding and error handler.
+Otherwise, returns the result of object.\\_\\_str\\_\\_() (if defined)
+or repr(object).\
+"""
+
+
+@pytest.mark.parametrize("text", [BYTES, STR, DICT, BOOL, COLLECTIONS_DEQUEUE])
+def test_accepts_cpython_docstrings(text):
+    assert looks_like_cpython(text) is True
+
+
+@pytest.mark.parametrize("text", [
+    "[link label](https://link)",
+    "![image label](https://source)",
+    "Some **bold** text",
+    "More __bold__ text",
+    "Some *italic* text",
+    "More _italic_ text",
+    "This is a sentence.",
+    "Exclamation!",
+    "Can I ask a question?",
+    "Let's send an e-mail",
+    "Parentheses (are) fine (really)",
+    "Double \"quotes\" and single 'quotes'"
+])
+def test_rejects_markdown_and_plain_text(text):
+    assert looks_like_cpython(text) is False
+
+
+def test_conversion_bool():
+    assert cpython_to_markdown(BOOL) == BOOL_MD
+
+
+def test_conversion_str():
+    assert cpython_to_markdown(STR) == STR_MD
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/docstring-to-markdown-0.13/tests/test_plain.py 
new/docstring-to-markdown-0.15/tests/test_plain.py
--- old/docstring-to-markdown-0.13/tests/test_plain.py  1970-01-01 
01:00:00.000000000 +0100
+++ new/docstring-to-markdown-0.15/tests/test_plain.py  2024-02-21 
14:50:11.000000000 +0100
@@ -0,0 +1,42 @@
+import pytest
+from docstring_to_markdown.plain import looks_like_plain_text, 
plain_text_to_markdown
+
+
+@pytest.mark.parametrize("text", [
+    "This is a sentence.",
+    "Exclamation!",
+    "Can I ask a question?",
+    "Let's send an e-mail",
+    "Parentheses (are) fine (really)",
+    "Double \"quotes\" and single 'quotes'"
+])
+def test_accepts_english(text):
+    assert looks_like_plain_text(text) is True
+
+
+@pytest.mark.parametrize("text", [
+    "[link label](https://link)",
+    "![image label](https://source)",
+    "Some **bold** text",
+    "More __bold__ text",
+    "Some *italic* text",
+    "More _italic_ text"
+])
+def test_rejects_markdown(text):
+    assert looks_like_plain_text(text) is False
+
+
+@pytest.mark.parametrize("text", [
+    "def test():",
+    "print(123)",
+    "func(arg)",
+    "2 + 2",
+    "var['test']",
+    "x = 'test'"
+])
+def test_rejects_code(text):
+    assert looks_like_plain_text(text) is False
+
+
+def test_conversion():
+    assert plain_text_to_markdown("test") == "test"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/docstring-to-markdown-0.13/tests/test_rst.py 
new/docstring-to-markdown-0.15/tests/test_rst.py
--- old/docstring-to-markdown-0.13/tests/test_rst.py    2023-10-11 
21:43:03.000000000 +0200
+++ new/docstring-to-markdown-0.15/tests/test_rst.py    2024-02-21 
14:50:11.000000000 +0100
@@ -78,6 +78,17 @@
     "[this 
link](https://pandas.pydata.org/pandas-docs/stable/user_guide/timeseries.html#offset-aliases)."
 )
 
+RST_LINK_MULTILINE_EXAMPLE = """
+See
+`strftime documentation
+<https://docs.python.org/3/library/datetime.html
+#strftime-and-strptime-behavior>`_ for more.
+"""
+RST_LINK_MULTILINE_MARKDOWN = """
+See
+[strftime 
documentation](https://docs.python.org/3/library/datetime.html#strftime-and-strptime-behavior)
 for more.
+"""
+
 RST_REF_EXAMPLE = """See :ref:`here <timeseries.offset_aliases>` for a list of 
frequency aliases."""
 RST_REF_MARKDOWN = """See here: `timeseries.offset_aliases` for a list of 
frequency aliases."""
 
@@ -686,6 +697,10 @@
         'rst': RST_LINK_EXAMPLE,
         'md': RST_LINK_EXAMPLE_MARKDOWN
     },
+    'converts multi-line links': {
+        'rst': RST_LINK_MULTILINE_EXAMPLE,
+        'md': RST_LINK_MULTILINE_MARKDOWN
+    },
     'changes highlight': {
         'rst': RST_HIGHLIGHTED_BLOCK,
         'md': RST_HIGHLIGHTED_BLOCK_MARKDOWN
@@ -764,6 +779,10 @@
         'rst': '__init__',
         'md': r'\_\_init\_\_'
     },
+    'does not escape dunders in code': {
+        'rst': '`__init__`',
+        'md': '`__init__`'
+    },
     'converts bibliographic references': {
         'rst': REFERENCES,
         'md': REFERENCES_MARKDOWN

Reply via email to