Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 18 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,13 @@

# Notice

This module, by default installs and uses [text-unidecode](https://github.com/kmike/text-unidecode) _(GPL & Perl Artistic)_ for its decoding needs.
This module, by default installs and uses [anyascii](https://github.com/anyascii/anyascii) _(ISC License)_ for its decoding needs. This is a permissive, non-GPL alternative that works well for most use cases.

However, there is an alternative decoding package called [Unidecode](https://github.com/avian2/unidecode) _(GPL)_. It can be installed as `python-slugify[unidecode]` for those who prefer it. `Unidecode` is believed to be more [advanced](https://github.com/un33k/python-slugify/wiki/Python-Slugify-Wiki#notes-on-unidecode).
However, there are alternative decoding packages available:
- [Unidecode](https://github.com/avian2/unidecode) _(GPL)_ - Can be installed as `python-slugify[unidecode]`. Believed to be more [advanced](https://github.com/un33k/python-slugify/wiki/Python-Slugify-Wiki#notes-on-unidecode).
- [text-unidecode](https://github.com/kmike/text-unidecode) _(GPL & Perl Artistic)_ - Can be installed as `python-slugify[text-unidecode]`.

The library will automatically use `unidecode` or `text-unidecode` (in that order) if either is installed, falling back to `anyascii` if neither is available.

### `Official` Support Matrix

Expand All @@ -26,11 +30,16 @@ However, there is an alternative decoding package called [Unidecode](https://git

# How to install

pip install python-slugify
```bash
# Default installation (uses anyascii - non-GPL)
pip install python-slugify

# OR
# With optional GPL-licensed Unidecode (more advanced)
pip install python-slugify[unidecode]

pip install python-slugify[unidecode]
# With optional text-unidecode (GPL or Perl Artistic)
pip install python-slugify[text-unidecode]
```

# Options

Expand Down Expand Up @@ -199,9 +208,10 @@ Please read the ([wiki](https://github.com/un33k/python-slugify/wiki/Python-Slug

Released under a ([MIT](LICENSE)) license.

### Notes on GPL dependencies
Though the dependencies may be GPL licensed, `python-slugify` itself is not considered a derivative work and will remain under the MIT license.
If you wish to avoid installation of any GPL licensed packages, please note that the default dependency `text-unidecode` explicitly lets you choose to use the [Artistic License](https://opensource.org/license/artistic-perl-1-0-2/) instead. Use without concern.
### Notes on dependencies
The default dependency, `anyascii`, uses the permissive ISC License (similar to MIT), so there are no licensing concerns.

If you choose to install the optional GPL-licensed packages (`unidecode` or `text-unidecode`), please note that `python-slugify` itself is not considered a derivative work and will remain under the MIT license.

# Version

Expand Down
7 changes: 5 additions & 2 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,11 @@
python_requires = ">=3.7"
here = os.path.abspath(os.path.dirname(__file__))

install_requires = ['text-unidecode>=1.3']
extras_requires = {'unidecode': ['Unidecode>=1.1.1']}
install_requires = ['anyascii>=0.3.0']
extras_requires = {
'unidecode': ['Unidecode>=1.1.1'],
'text-unidecode': ['text-unidecode>=1.3']
}
test_requires = []

about = {}
Expand Down
21 changes: 18 additions & 3 deletions slugify/slugify.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,25 @@

try:
import unidecode
_DECODER = 'unidecode'
except ImportError:
import text_unidecode as unidecode

__all__ = ['slugify', 'smart_truncate']
try:
import text_unidecode as unidecode
_DECODER = 'text_unidecode'
except ImportError:
from anyascii import anyascii
# Create a wrapper module to match unidecode's API
class _AnyasciiWrapper:
@staticmethod
def unidecode(text):
return anyascii(text)
unidecode = _AnyasciiWrapper()
_DECODER = 'anyascii'

__all__ = ['slugify', 'smart_truncate', 'SLUGIFY_DECODER']

# Export the decoder being used for user reference
SLUGIFY_DECODER = _DECODER


CHAR_ENTITY_PATTERN = re.compile(r'&(%s);' % '|'.join(name2codepoint))
Expand Down
13 changes: 11 additions & 2 deletions test.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
from slugify import PRE_TRANSLATIONS
from slugify import slugify
from slugify import smart_truncate
from slugify import SLUGIFY_DECODER
from slugify.__main__ import slugify_params, parse_args


Expand Down Expand Up @@ -34,7 +35,11 @@ def test_non_word_characters(self):
def test_phonetic_conversion_of_eastern_scripts(self):
txt = '影師嗎'
r = slugify(txt)
self.assertEqual(r, "ying-shi-ma")
# anyascii produces different (but valid) output
if SLUGIFY_DECODER == 'anyascii':
self.assertEqual(r, "yingshima")
else:
self.assertEqual(r, "ying-shi-ma")

def test_accented_text(self):
txt = '𝐚́́𝕒́àáâäãąā'
Expand All @@ -57,7 +62,11 @@ def test_accented_text_with_non_word_characters(self):
def test_cyrillic_text(self):
txt = 'Компьютер'
r = slugify(txt)
self.assertEqual(r, "kompiuter")
# anyascii produces different (but valid) output
if SLUGIFY_DECODER == 'anyascii':
self.assertEqual(r, "kompyuter")
else:
self.assertEqual(r, "kompiuter")

def test_max_length(self):
txt = 'jaja---lol-méméméoo--a'
Expand Down