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
10 changes: 8 additions & 2 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,7 +1,13 @@
# Packaging
*.egg-info/
*.pyc
.tox
__pycache__/
dist/*
docs/_build/*
build

# Testing
.tox
__pycache__/

# Ctags
tags
1 change: 0 additions & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
language: python
python:
- 2.7
- 3.6
- 3.7
- 3.8
Expand Down
2 changes: 1 addition & 1 deletion README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ purl - A simple Python URL class
================================

A simple, immutable URL class with a clean API for interrogation and
manipulation. Supports Pythons 2.7, 3.3, 3.4, 3.5, 3.6, 3.7, 3.8 and pypy.
manipulation. Supports Pythons 3.3, 3.4, 3.5, 3.6, 3.7, 3.8 and pypy.

Also supports template URLs as per `RFC 6570`_

Expand Down
11 changes: 3 additions & 8 deletions makefile
Original file line number Diff line number Diff line change
@@ -1,20 +1,15 @@
install:
pip install -r requirements.txt
python setup.py develop
flit install --symlink

test:
pytest

package: clean
# Test these packages in a fresh virtualenvs:
# $ pip install --no-index dist/purl-0.8.tar.gz
# $ pip install --use-wheel --no-index --find-links dist purl
./setup.py sdist
./setup.py bdist_wheel
flit build

release:
./setup.py sdist upload
./setup.py bdist_wheel upload
flit publish
git push --tags

clean:
Expand Down
10 changes: 6 additions & 4 deletions purl/__init__.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
from .url import URL # noqa
from .template import expand, Template # noqa
""""An immutable URL class for easy URL-building and manipulation"""
# flake8: noqa
from .url import URL
from .template import expand, Template

__version__ = '1.5'
__version__ = "1.5"

__all__ = ['URL', 'expand', 'Template']
__all__ = ["URL", "expand", "Template"]
12 changes: 5 additions & 7 deletions purl/template.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,7 @@
import re
import functools

try:
from urllib.parse import quote
except ImportError:
# Python 2
from urllib import quote
from urllib.parse import quote

from . import url

Expand Down Expand Up @@ -123,8 +119,8 @@ def _format_default(explode, separator, escape, key, value):
return escaped_value


# Modifer functions
# -----------------
# Modifier functions
# ------------------
# These are responsible for modifying the variable before formatting

_identity = lambda x: x
Expand Down Expand Up @@ -209,6 +205,8 @@ def _replace(variables, match):
replacement = format_fn(
explode, separator_char, escape_fn, key, variable)
replacements.append(replacement)

if not replacements:
return ''

return prefix_char + separator_char.join(replacements)
37 changes: 10 additions & 27 deletions purl/url.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,8 @@
from __future__ import unicode_literals

try:
from urllib.parse import parse_qs, urlencode, urlparse, quote, unquote
except ImportError:
from urllib import urlencode, quote, unquote
from urlparse import parse_qs, urlparse
from urllib.parse import parse_qs, urlencode, urlparse, quote, unquote
from collections import namedtuple

import six


# To minimise memory consumption, we use a namedtuple to store all instance
Expand All @@ -23,25 +18,21 @@ def to_unicode(string):
"""
Ensure a passed string is unicode
"""
if isinstance(string, six.binary_type):
return string.decode('utf8')
if isinstance(string, six.text_type):
return string
if six.PY2:
return unicode(string)
return str(string)
if isinstance(string, bytes):
string = string.decode("utf8")
else:
string = str(string)
return string


def to_utf8(string):
"""
Encode a string as a UTF8 bytestring. This function could be passed a
bytestring or unicode string so must distinguish between the two.
"""
if isinstance(string, six.text_type):
return string.encode('utf8')
if isinstance(string, six.binary_type):
return string
return str(string)
if not isinstance(string, bytes):
string = str(string).encode("utf8")
return string


def dict_to_unicode(raw_dict):
Expand Down Expand Up @@ -72,9 +63,7 @@ def unicode_quote_path_segment(string):
def unicode_unquote(string):
if string is None:
return None
if six.PY3:
return unquote(string)
return to_unicode(unquote(to_utf8(string)))
return unquote(string)


def unicode_urlencode(query, doseq=True):
Expand Down Expand Up @@ -485,12 +474,6 @@ def query_params(self, value=None):
return URL._mutate(self, query=unicode_urlencode(value, doseq=True))
query = '' if self._tuple.query is None else self._tuple.query

# In Python 2.6, urlparse needs a bytestring so we encode and then
# decode the result.
if not six.PY3:
result = parse_qs(to_utf8(query), True)
return dict_to_unicode(result)

return parse_qs(query, True)

def remove_query_param(self, key, value=None):
Expand Down
13 changes: 13 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
[build-system]
requires = ["flit_core >=2,<4"]
build-backend = "flit_core.buildapi"

[tool.flit.metadata]
module = "purl"
author = "David Winterbottom"
author-email = "david.winterbottom@gmail.com"
home-page = "https://github.com/codeinthehole/purl"
classifiers = [ "License :: OSI Approved :: MIT License",]
description-file = "README.rst"
requires-python = ">=3.6"

9 changes: 4 additions & 5 deletions requirements.txt
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
# Packaging
pip==19.0.3
setuptools==40.8.0
wheel==0.33.1
pip==21.1.1
flit==3.2.0

# Testing
pytest
tox==3.7.0
pytest==6.2.4
tox==3.23.1
33 changes: 0 additions & 33 deletions setup.py

This file was deleted.

Loading