pax_global_header 0000666 0000000 0000000 00000000064 13612537675 0014531 g ustar 00root root 0000000 0000000 52 comment=84dfb21578171be009b0d6a6e85758645e1e4c7c
validators-0.14.2/ 0000775 0000000 0000000 00000000000 13612537675 0013765 5 ustar 00root root 0000000 0000000 validators-0.14.2/.gitignore 0000664 0000000 0000000 00000000507 13612537675 0015757 0 ustar 00root root 0000000 0000000 *.py[cod]
# C extensions
*.so
# Packages
*.egg
*.egg-info
dist
build
eggs
parts
bin
var
sdist
develop-eggs
.installed.cfg
lib
lib64
__pycache__
docs/_build
# Installer logs
pip-log.txt
# Unit test / coverage reports
.coverage
.tox
nosetests.xml
# Translations
*.mo
# Mr Developer
.mr.developer.cfg
.project
.pydevproject
validators-0.14.2/.isort.cfg 0000664 0000000 0000000 00000000200 13612537675 0015654 0 ustar 00root root 0000000 0000000 [settings]
known_first_party=sqlalchemy_utils,tests
line_length=79
multi_line_output=3
not_skip=__init__.py
order_by_type=false
validators-0.14.2/.travis.yml 0000664 0000000 0000000 00000000673 13612537675 0016104 0 ustar 00root root 0000000 0000000 language: python
matrix:
include:
- python: 2.7
- python: 3.4
- python: 3.5
- python: 3.6
- python: 3.7
dist: xenial
sudo: true
- python: pypy
- python: pypy3
install:
- pip install -e ".[test]"
script:
- isort --recursive --diff validators tests && isort --recursive --check-only validators tests
- flake8 validators tests
- py.test --doctest-glob="*.rst" --doctest-modules --ignore=setup.py
validators-0.14.2/CHANGES.rst 0000664 0000000 0000000 00000010126 13612537675 0015567 0 ustar 00root root 0000000 0000000 Changelog
---------
0.14.2 (2020-01-24)
^^^^^^^^^^^^^^^^^^^
- Made domain validation case-insensitive (#136, pull request courtesy ehmkah)
0.14.1 (2019-12-04)
^^^^^^^^^^^^^^^^^^^
- Updated domain validator regex to not allow numeric only TLDs (#133, pull request courtesy jmeridth)
- Allow for idna encoded domains (#133, pull request courtesy jmeridth)
0.14.0 (2019-08-21)
^^^^^^^^^^^^^^^^^^^
- Added new validators ``ipv4_cidr``, ``ipv6_cidr`` (#117, pull request courtesy woodruffw)
0.13.0 (2019-05-20)
^^^^^^^^^^^^^^^^^^^
- Added new validator: ``es_doi``, ``es_nif``, ``es_cif``, ``es_nie`` (#121, pull request courtesy kingbuzzman)
0.12.6 (2019-05-08)
^^^^^^^^^^^^^^^^^^^
- Fixed domain validator for single character domains (#118, pull request courtesy kingbuzzman)
0.12.5 (2019-04-15)
^^^^^^^^^^^^^^^^^^^
- Fixed py37 support (#113, pull request courtesy agiletechnologist)
0.12.4 (2019-01-02)
^^^^^^^^^^^^^^^^^^^
- Use inspect.getfullargspec() in py3 (#110, pull request courtesy riconnon)
0.12.3 (2018-11-13)
^^^^^^^^^^^^^^^^^^^
- Added `allow_temporal_ssn` parameter to fi_ssn validator (#97, pull request courtesy quantus)
- Remove py33 support
0.12.2 (2018-06-03)
^^^^^^^^^^^^^^^^^^^
- Fixed IPv4 formatted IP address returning True on ipv6 (#85, pull request courtesy johndlong)
- Fixed IPv6 address parsing (#83, pull request courtesy JulianKahnert)
- Fixed domain validator for international domains and certain edge cases (#76, pull request courtesy Ni-Knight)
0.12.1 (2018-01-30)
^^^^^^^^^^^^^^^^^^^
- Fixed IDNA encoded TLDs in domain validator (#75, pull request courtesy piewpiew)
- Fixed URL validator for URLs with invalid characters in userinfo part (#69, pull request courtesy timb07)
0.12.0 (2017-06-03)
^^^^^^^^^^^^^^^^^^^
- Added hash validators for md5, sha1, sha224, sha256 and sha512
- Made ipv6 validator support IPv4-mapped IPv6 addresses
0.11.3 (2017-03-27)
^^^^^^^^^^^^^^^^^^^
- Fixed URL validator for URLs containing localhost (#51, pull request courtesy vladimirdotk)
0.11.2 (2017-01-08)
^^^^^^^^^^^^^^^^^^^
- Fixed URL validator for urls with query parameters but without path (#44, pull request courtesy zjjw)
0.11.1 (2016-11-19)
^^^^^^^^^^^^^^^^^^^
- Fixed pyp2rpm build problem (#37, pull request courtesy BOPOHA)
0.11.0 (2016-08-30)
^^^^^^^^^^^^^^^^^^^
- Fixed public url validation (#29)
- Made URL validator case insensitive (#27)
- Drop Python 2.6 support
0.10.3 (2016-06-13)
^^^^^^^^^^^^^^^^^^^
- Added ``public`` parameter to url validator (#26, pull request courtesy Iconceicao)
0.10.2 (2016-06-11)
^^^^^^^^^^^^^^^^^^^
- Fixed various URL validation issues
0.10.1 (2016-04-09)
^^^^^^^^^^^^^^^^^^^
- Fixed domain name validation for numeric domain names (#21, pull request courtesy shaunpud)
- Fixed IBAN validation for Norwegian and Belgian IBANs (#17, pull request courtesy mboelens91)
0.10.0 (2016-01-09)
^^^^^^^^^^^^^^^^^^^
- Added support for internationalized domain names in ``domain`` validator
0.9.0 (2015-10-10)
^^^^^^^^^^^^^^^^^^
- Added new validator: ``domain``
- Added flake8 and isort checks in travis config
0.8.0 (2015-06-24)
^^^^^^^^^^^^^^^^^^
- Added new validator: ``iban``
0.7.0 (2014-09-07)
^^^^^^^^^^^^^^^^^^
- Fixed errors in code examples.
- Fixed ``TypeError`` when using ``between`` validator with ``datetime`` objects
like in the code example.
- Changed validators to always return ``True`` instead of a truthy object when
the validation succeeds.
- Fixed ``truthy`` validator to work like it's name suggests. Previously it
worked like ``falsy``.
0.6.0 (2014-06-25)
^^^^^^^^^^^^^^^^^^
- Added new validator: ``slug``
0.5.0 (2013-10-31)
^^^^^^^^^^^^^^^^^^
- Renamed ``finnish_business_id`` to ``fi_business_id``
- Added new validator: ``fi_ssn``
0.4.0 (2013-10-29)
^^^^^^^^^^^^^^^^^^
- Added new validator: ``finnish_business_id``
0.3.0 (2013-10-27)
^^^^^^^^^^^^^^^^^^
- ``number_range`` -> ``between``
0.2.0 (2013-10-22)
^^^^^^^^^^^^^^^^^^
- Various new validators: ``ipv4``, ``ipv6``, ``length``, ``number_range``,
``mac_address``, ``url``, ``uuid``
0.1.0 (2013-10-18)
^^^^^^^^^^^^^^^^^^
- Initial public release
validators-0.14.2/LICENSE 0000664 0000000 0000000 00000002101 13612537675 0014764 0 ustar 00root root 0000000 0000000 The MIT License (MIT)
Copyright (c) 2013-2014 Konsta Vesterinen
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.
validators-0.14.2/MANIFEST.in 0000664 0000000 0000000 00000000301 13612537675 0015515 0 ustar 00root root 0000000 0000000 include CHANGES.rst LICENSE README.rst
recursive-include tests *
recursive-exclude tests *.pyc
recursive-include docs *
recursive-exclude docs *.pyc
prune docs/_build
exclude docs/_themes/.git
validators-0.14.2/README.rst 0000664 0000000 0000000 00000002015 13612537675 0015452 0 ustar 00root root 0000000 0000000 validators
==========
|Build Status| |Version Status| |Downloads|
Python data validation for Humans.
Python has all kinds of data validation tools, but every one of them seems to
require defining a schema or form. I wanted to create a simple validation
library where validating a simple value does not require defining a form or a
schema.
.. code-block:: python
>>> import validators
>>> validators.email('someone@example.com')
True
Resources
---------
- `Documentation `_
- `Issue Tracker `_
- `Code `_
.. |Build Status| image:: https://travis-ci.org/kvesteri/validators.svg?branch=master
:target: https://travis-ci.org/kvesteri/validators
.. |Version Status| image:: https://img.shields.io/pypi/v/validators.svg
:target: https://pypi.python.org/pypi/validators/
.. |Downloads| image:: https://img.shields.io/pypi/dm/validators.svg
:target: https://pypi.python.org/pypi/validators/
validators-0.14.2/docs/ 0000775 0000000 0000000 00000000000 13612537675 0014715 5 ustar 00root root 0000000 0000000 validators-0.14.2/docs/Makefile 0000664 0000000 0000000 00000015172 13612537675 0016363 0 ustar 00root root 0000000 0000000 # Makefile for Sphinx documentation
#
# You can set these variables from the command line.
SPHINXOPTS =
SPHINXBUILD = sphinx-build
PAPER =
BUILDDIR = _build
# User-friendly check for sphinx-build
ifeq ($(shell which $(SPHINXBUILD) >/dev/null 2>&1; echo $$?), 1)
$(error The '$(SPHINXBUILD)' command was not found. Make sure you have Sphinx installed, then set the SPHINXBUILD environment variable to point to the full path of the '$(SPHINXBUILD)' executable. Alternatively you can add the directory with the executable to your PATH. If you don't have Sphinx installed, grab it from http://sphinx-doc.org/)
endif
# Internal variables.
PAPEROPT_a4 = -D latex_paper_size=a4
PAPEROPT_letter = -D latex_paper_size=letter
ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) .
# the i18n builder cannot share the environment and doctrees with the others
I18NSPHINXOPTS = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) .
.PHONY: help clean html dirhtml singlehtml pickle json htmlhelp qthelp devhelp epub latex latexpdf text man changes linkcheck doctest gettext
help:
@echo "Please use \`make ' where is one of"
@echo " html to make standalone HTML files"
@echo " dirhtml to make HTML files named index.html in directories"
@echo " singlehtml to make a single large HTML file"
@echo " pickle to make pickle files"
@echo " json to make JSON files"
@echo " htmlhelp to make HTML files and a HTML help project"
@echo " qthelp to make HTML files and a qthelp project"
@echo " devhelp to make HTML files and a Devhelp project"
@echo " epub to make an epub"
@echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter"
@echo " latexpdf to make LaTeX files and run them through pdflatex"
@echo " latexpdfja to make LaTeX files and run them through platex/dvipdfmx"
@echo " text to make text files"
@echo " man to make manual pages"
@echo " texinfo to make Texinfo files"
@echo " info to make Texinfo files and run them through makeinfo"
@echo " gettext to make PO message catalogs"
@echo " changes to make an overview of all changed/added/deprecated items"
@echo " xml to make Docutils-native XML files"
@echo " pseudoxml to make pseudoxml-XML files for display purposes"
@echo " linkcheck to check all external links for integrity"
@echo " doctest to run all doctests embedded in the documentation (if enabled)"
clean:
rm -rf $(BUILDDIR)/*
html:
$(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html
@echo
@echo "Build finished. The HTML pages are in $(BUILDDIR)/html."
dirhtml:
$(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml
@echo
@echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml."
singlehtml:
$(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml
@echo
@echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml."
pickle:
$(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle
@echo
@echo "Build finished; now you can process the pickle files."
json:
$(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json
@echo
@echo "Build finished; now you can process the JSON files."
htmlhelp:
$(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp
@echo
@echo "Build finished; now you can run HTML Help Workshop with the" \
".hhp project file in $(BUILDDIR)/htmlhelp."
qthelp:
$(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp
@echo
@echo "Build finished; now you can run "qcollectiongenerator" with the" \
".qhcp project file in $(BUILDDIR)/qthelp, like this:"
@echo "# qcollectiongenerator $(BUILDDIR)/qthelp/validators.qhcp"
@echo "To view the help file:"
@echo "# assistant -collectionFile $(BUILDDIR)/qthelp/validators.qhc"
devhelp:
$(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp
@echo
@echo "Build finished."
@echo "To view the help file:"
@echo "# mkdir -p $$HOME/.local/share/devhelp/validators"
@echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/validators"
@echo "# devhelp"
epub:
$(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub
@echo
@echo "Build finished. The epub file is in $(BUILDDIR)/epub."
latex:
$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
@echo
@echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex."
@echo "Run \`make' in that directory to run these through (pdf)latex" \
"(use \`make latexpdf' here to do that automatically)."
latexpdf:
$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
@echo "Running LaTeX files through pdflatex..."
$(MAKE) -C $(BUILDDIR)/latex all-pdf
@echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex."
latexpdfja:
$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
@echo "Running LaTeX files through platex and dvipdfmx..."
$(MAKE) -C $(BUILDDIR)/latex all-pdf-ja
@echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex."
text:
$(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text
@echo
@echo "Build finished. The text files are in $(BUILDDIR)/text."
man:
$(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man
@echo
@echo "Build finished. The manual pages are in $(BUILDDIR)/man."
texinfo:
$(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo
@echo
@echo "Build finished. The Texinfo files are in $(BUILDDIR)/texinfo."
@echo "Run \`make' in that directory to run these through makeinfo" \
"(use \`make info' here to do that automatically)."
info:
$(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo
@echo "Running Texinfo files through makeinfo..."
make -C $(BUILDDIR)/texinfo info
@echo "makeinfo finished; the Info files are in $(BUILDDIR)/texinfo."
gettext:
$(SPHINXBUILD) -b gettext $(I18NSPHINXOPTS) $(BUILDDIR)/locale
@echo
@echo "Build finished. The message catalogs are in $(BUILDDIR)/locale."
changes:
$(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes
@echo
@echo "The overview file is in $(BUILDDIR)/changes."
linkcheck:
$(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck
@echo
@echo "Link check complete; look for any errors in the above output " \
"or in $(BUILDDIR)/linkcheck/output.txt."
doctest:
$(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest
@echo "Testing of doctests in the sources finished, look at the " \
"results in $(BUILDDIR)/doctest/output.txt."
xml:
$(SPHINXBUILD) -b xml $(ALLSPHINXOPTS) $(BUILDDIR)/xml
@echo
@echo "Build finished. The XML files are in $(BUILDDIR)/xml."
pseudoxml:
$(SPHINXBUILD) -b pseudoxml $(ALLSPHINXOPTS) $(BUILDDIR)/pseudoxml
@echo
@echo "Build finished. The pseudo-XML files are in $(BUILDDIR)/pseudoxml."
validators-0.14.2/docs/conf.py 0000664 0000000 0000000 00000020645 13612537675 0016223 0 ustar 00root root 0000000 0000000 # -*- coding: utf-8 -*-
#
# validators documentation build configuration file, created by
# sphinx-quickstart on Mon Oct 21 12:30:12 2013.
#
# This file is execfile()d with the current directory set to its
# containing dir.
#
# Note that not all possible configuration values are present in this
# autogenerated file.
#
# All configuration values have a default; values that are commented out
# serve to show the default.
import sys
import os
# If extensions (or modules to document with autodoc) are in another directory,
# add these directories to sys.path here. If the directory is relative to the
# documentation root, use os.path.abspath to make it absolute, like shown here.
sys.path.insert(0, os.path.abspath('..'))
from validators import __version__
# -- General configuration ------------------------------------------------
# If your documentation needs a minimal Sphinx version, state it here.
#needs_sphinx = '1.0'
# Add any Sphinx extension module names here, as strings. They can be
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
# ones.
extensions = [
'sphinx.ext.autodoc',
'sphinx.ext.doctest',
'sphinx.ext.intersphinx',
'sphinx.ext.todo',
'sphinx.ext.coverage',
'sphinx.ext.pngmath',
'sphinx.ext.mathjax',
'sphinx.ext.ifconfig',
'sphinx.ext.viewcode',
]
# Add any paths that contain templates here, relative to this directory.
templates_path = ['_templates']
# The suffix of source filenames.
source_suffix = '.rst'
# The encoding of source files.
#source_encoding = 'utf-8-sig'
# The master toctree document.
master_doc = 'index'
# General information about the project.
project = u'validators'
copyright = u'2013-2014, Konsta Vesterinen'
# The version info for the project you're documenting, acts as replacement for
# |version| and |release|, also used in various other places throughout the
# built documents.
#
# The short X.Y version.
version = __version__
# The full version, including alpha/beta/rc tags.
release = version
# The language for content autogenerated by Sphinx. Refer to documentation
# for a list of supported languages.
#language = None
# There are two options for replacing |today|: either, you set today to some
# non-false value, then it is used:
#today = ''
# Else, today_fmt is used as the format for a strftime call.
#today_fmt = '%B %d, %Y'
# List of patterns, relative to source directory, that match files and
# directories to ignore when looking for source files.
exclude_patterns = ['_build']
# The reST default role (used for this markup: `text`) to use for all
# documents.
#default_role = None
# If true, '()' will be appended to :func: etc. cross-reference text.
#add_function_parentheses = True
# If true, the current module name will be prepended to all description
# unit titles (such as .. function::).
#add_module_names = True
# If true, sectionauthor and moduleauthor directives will be shown in the
# output. They are ignored by default.
#show_authors = False
# The name of the Pygments (syntax highlighting) style to use.
pygments_style = 'sphinx'
# A list of ignored prefixes for module index sorting.
#modindex_common_prefix = []
# If true, keep warnings as "system message" paragraphs in the built documents.
#keep_warnings = False
# -- Options for HTML output ----------------------------------------------
# The theme to use for HTML and HTML Help pages. See the documentation for
# a list of builtin themes.
html_theme = 'default'
# Theme options are theme-specific and customize the look and feel of a theme
# further. For a list of options available for each theme, see the
# documentation.
#html_theme_options = {}
# Add any paths that contain custom themes here, relative to this directory.
#html_theme_path = []
# The name for this set of Sphinx documents. If None, it defaults to
# " v documentation".
#html_title = None
# A shorter title for the navigation bar. Default is the same as html_title.
#html_short_title = None
# The name of an image file (relative to this directory) to place at the top
# of the sidebar.
#html_logo = None
# The name of an image file (within the static path) to use as favicon of the
# docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32
# pixels large.
#html_favicon = None
# Add any paths that contain custom static files (such as style sheets) here,
# relative to this directory. They are copied after the builtin static files,
# so a file named "default.css" will overwrite the builtin "default.css".
html_static_path = ['_static']
# Add any extra paths that contain custom files (such as robots.txt or
# .htaccess) here, relative to this directory. These files are copied
# directly to the root of the documentation.
#html_extra_path = []
# If not '', a 'Last updated on:' timestamp is inserted at every page bottom,
# using the given strftime format.
#html_last_updated_fmt = '%b %d, %Y'
# If true, SmartyPants will be used to convert quotes and dashes to
# typographically correct entities.
#html_use_smartypants = True
# Custom sidebar templates, maps document names to template names.
#html_sidebars = {}
# Additional templates that should be rendered to pages, maps page names to
# template names.
#html_additional_pages = {}
# If false, no module index is generated.
#html_domain_indices = True
# If false, no index is generated.
#html_use_index = True
# If true, the index is split into individual pages for each letter.
#html_split_index = False
# If true, links to the reST sources are added to the pages.
#html_show_sourcelink = True
# If true, "Created using Sphinx" is shown in the HTML footer. Default is True.
#html_show_sphinx = True
# If true, "(C) Copyright ..." is shown in the HTML footer. Default is True.
#html_show_copyright = True
# If true, an OpenSearch description file will be output, and all pages will
# contain a tag referring to it. The value of this option must be the
# base URL from which the finished HTML is served.
#html_use_opensearch = ''
# This is the file name suffix for HTML files (e.g. ".xhtml").
#html_file_suffix = None
# Output file base name for HTML help builder.
htmlhelp_basename = 'validatorsdoc'
# -- Options for LaTeX output ---------------------------------------------
latex_elements = {
# The paper size ('letterpaper' or 'a4paper').
#'papersize': 'letterpaper',
# The font size ('10pt', '11pt' or '12pt').
#'pointsize': '10pt',
# Additional stuff for the LaTeX preamble.
#'preamble': '',
}
# Grouping the document tree into LaTeX files. List of tuples
# (source start file, target name, title,
# author, documentclass [howto, manual, or own class]).
latex_documents = [
('index', 'validators.tex', u'validators Documentation',
u'Konsta Vesterinen', 'manual'),
]
# The name of an image file (relative to this directory) to place at the top of
# the title page.
#latex_logo = None
# For "manual" documents, if this is true, then toplevel headings are parts,
# not chapters.
#latex_use_parts = False
# If true, show page references after internal links.
#latex_show_pagerefs = False
# If true, show URL addresses after external links.
#latex_show_urls = False
# Documents to append as an appendix to all manuals.
#latex_appendices = []
# If false, no module index is generated.
#latex_domain_indices = True
# -- Options for manual page output ---------------------------------------
# One entry per manual page. List of tuples
# (source start file, name, description, authors, manual section).
man_pages = [
('index', 'validators', u'validators Documentation',
[u'Konsta Vesterinen'], 1)
]
# If true, show URL addresses after external links.
#man_show_urls = False
# -- Options for Texinfo output -------------------------------------------
# Grouping the document tree into Texinfo files. List of tuples
# (source start file, target name, title, author,
# dir menu entry, description, category)
texinfo_documents = [
('index', 'validators', u'validators Documentation',
u'Konsta Vesterinen', 'validators', 'One line description of project.',
'Miscellaneous'),
]
# Documents to append as an appendix to all manuals.
#texinfo_appendices = []
# If false, no module index is generated.
#texinfo_domain_indices = True
# How to display URL addresses: 'footnote', 'no', or 'inline'.
#texinfo_show_urls = 'footnote'
# If true, do not generate a @detailmenu in the "Top" node's menu.
#texinfo_no_detailmenu = False
# Example configuration for intersphinx: refer to the Python standard library.
intersphinx_mapping = {'http://docs.python.org/': None}
validators-0.14.2/docs/index.rst 0000664 0000000 0000000 00000006471 13612537675 0016566 0 ustar 00root root 0000000 0000000 validators
==========
Python Data Validation for Humans™.
Why?
====
Python has all kinds of validation tools, but every one of them requires
defining a schema. I wanted to create a simple validation library where
validating a simple value does not require defining a form or a schema.
Apparently `some other guys have felt the same way`_.
.. _some other guys have felt the same way:
http://opensourcehacker.com/2011/07/07/generic-python-validation-frameworks/
Often I've had for example a case where I just wanted to check if given string
is an email. With ``validators`` this use case becomes as easy as::
>>> import validators
>>> validators.email('someone@example.com')
True
Installation
============
You can install ``validators`` using pip::
pip install validators
Currently ``validators`` supports python versions 2.7, 3.3, 3.4, 3.5, 3.6, 3.7
and PyPy.
Basic validators
================
Each validator in ``validators`` is a simple function that takes the value to
validate and possibly some additional key-value arguments. Each function returns
``True`` when validation succeeds and
:class:`~validators.utils.ValidationFailure` object when validation fails.
:class:`~validators.utils.ValidationFailure` class implements ``__bool__``
method so you can easily check if validation failed::
>>> if not validators.email('some_bogus_email@@@'):
... # Do something here
... pass
:class:`~validators.utils.ValidationFailure` object also holds all the arguments
passed to original function::
>>> result = validators.between(3, min=5)
>>> result.value
3
>>> result.min
5
between
-------
.. module:: validators.between
.. autofunction:: between
domain
------
.. module:: validators.domain
.. autofunction:: domain
email
-----
.. module:: validators.email
.. autofunction:: email
iban
----
.. module:: validators.iban
.. autofunction:: iban
ipv4
----
.. module:: validators.ip_address
.. autofunction:: ipv4
ipv6
----
.. autofunction:: ipv6
length
------
.. module:: validators.length
.. autofunction:: length
mac_address
-----------
.. module:: validators.mac_address
.. autofunction:: mac_address
md5
-----------
.. module:: validators.hashes
.. autofunction:: md5
sha1
-----------
.. module:: validators.hashes
.. autofunction:: sha1
sha224
-----------
.. module:: validators.hashes
.. autofunction:: sha224
sha256
-----------
.. module:: validators.hashes
.. autofunction:: sha256
sha512
-----------
.. module:: validators.hashes
.. autofunction:: sha512
slug
----
.. module:: validators.slug
.. autofunction:: slug
truthy
------
.. module:: validators.truthy
.. autofunction:: truthy
url
---
.. module:: validators.url
.. autofunction:: url
uuid
----
.. module:: validators.uuid
.. autofunction:: uuid
i18n validators
===============
Spanish
-------
.. module:: validators.i18n.es
es_doi
^^^^^^
.. autofunction:: es_doi
es_nif
^^^^^^
.. autofunction:: es_nif
es_nie
^^^^^^
.. autofunction:: es_nie
es_cif
^^^^^^
.. autofunction:: es_cif
Finnish
-------
.. module:: validators.i18n.fi
fi_business_id
^^^^^^^^^^^^^^
.. autofunction:: fi_business_id
fi_ssn
^^^^^^
.. autofunction:: fi_ssn
Internals
=========
validator
---------
.. module:: validators.utils
.. autoclass:: ValidationFailure
.. autofunction:: validator
validators-0.14.2/docs/make.bat 0000664 0000000 0000000 00000015065 13612537675 0016331 0 ustar 00root root 0000000 0000000 @ECHO OFF
REM Command file for Sphinx documentation
if "%SPHINXBUILD%" == "" (
set SPHINXBUILD=sphinx-build
)
set BUILDDIR=_build
set ALLSPHINXOPTS=-d %BUILDDIR%/doctrees %SPHINXOPTS% .
set I18NSPHINXOPTS=%SPHINXOPTS% .
if NOT "%PAPER%" == "" (
set ALLSPHINXOPTS=-D latex_paper_size=%PAPER% %ALLSPHINXOPTS%
set I18NSPHINXOPTS=-D latex_paper_size=%PAPER% %I18NSPHINXOPTS%
)
if "%1" == "" goto help
if "%1" == "help" (
:help
echo.Please use `make ^` where ^ is one of
echo. html to make standalone HTML files
echo. dirhtml to make HTML files named index.html in directories
echo. singlehtml to make a single large HTML file
echo. pickle to make pickle files
echo. json to make JSON files
echo. htmlhelp to make HTML files and a HTML help project
echo. qthelp to make HTML files and a qthelp project
echo. devhelp to make HTML files and a Devhelp project
echo. epub to make an epub
echo. latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter
echo. text to make text files
echo. man to make manual pages
echo. texinfo to make Texinfo files
echo. gettext to make PO message catalogs
echo. changes to make an overview over all changed/added/deprecated items
echo. xml to make Docutils-native XML files
echo. pseudoxml to make pseudoxml-XML files for display purposes
echo. linkcheck to check all external links for integrity
echo. doctest to run all doctests embedded in the documentation if enabled
goto end
)
if "%1" == "clean" (
for /d %%i in (%BUILDDIR%\*) do rmdir /q /s %%i
del /q /s %BUILDDIR%\*
goto end
)
%SPHINXBUILD% 2> nul
if errorlevel 9009 (
echo.
echo.The 'sphinx-build' command was not found. Make sure you have Sphinx
echo.installed, then set the SPHINXBUILD environment variable to point
echo.to the full path of the 'sphinx-build' executable. Alternatively you
echo.may add the Sphinx directory to PATH.
echo.
echo.If you don't have Sphinx installed, grab it from
echo.http://sphinx-doc.org/
exit /b 1
)
if "%1" == "html" (
%SPHINXBUILD% -b html %ALLSPHINXOPTS% %BUILDDIR%/html
if errorlevel 1 exit /b 1
echo.
echo.Build finished. The HTML pages are in %BUILDDIR%/html.
goto end
)
if "%1" == "dirhtml" (
%SPHINXBUILD% -b dirhtml %ALLSPHINXOPTS% %BUILDDIR%/dirhtml
if errorlevel 1 exit /b 1
echo.
echo.Build finished. The HTML pages are in %BUILDDIR%/dirhtml.
goto end
)
if "%1" == "singlehtml" (
%SPHINXBUILD% -b singlehtml %ALLSPHINXOPTS% %BUILDDIR%/singlehtml
if errorlevel 1 exit /b 1
echo.
echo.Build finished. The HTML pages are in %BUILDDIR%/singlehtml.
goto end
)
if "%1" == "pickle" (
%SPHINXBUILD% -b pickle %ALLSPHINXOPTS% %BUILDDIR%/pickle
if errorlevel 1 exit /b 1
echo.
echo.Build finished; now you can process the pickle files.
goto end
)
if "%1" == "json" (
%SPHINXBUILD% -b json %ALLSPHINXOPTS% %BUILDDIR%/json
if errorlevel 1 exit /b 1
echo.
echo.Build finished; now you can process the JSON files.
goto end
)
if "%1" == "htmlhelp" (
%SPHINXBUILD% -b htmlhelp %ALLSPHINXOPTS% %BUILDDIR%/htmlhelp
if errorlevel 1 exit /b 1
echo.
echo.Build finished; now you can run HTML Help Workshop with the ^
.hhp project file in %BUILDDIR%/htmlhelp.
goto end
)
if "%1" == "qthelp" (
%SPHINXBUILD% -b qthelp %ALLSPHINXOPTS% %BUILDDIR%/qthelp
if errorlevel 1 exit /b 1
echo.
echo.Build finished; now you can run "qcollectiongenerator" with the ^
.qhcp project file in %BUILDDIR%/qthelp, like this:
echo.^> qcollectiongenerator %BUILDDIR%\qthelp\validators.qhcp
echo.To view the help file:
echo.^> assistant -collectionFile %BUILDDIR%\qthelp\validators.ghc
goto end
)
if "%1" == "devhelp" (
%SPHINXBUILD% -b devhelp %ALLSPHINXOPTS% %BUILDDIR%/devhelp
if errorlevel 1 exit /b 1
echo.
echo.Build finished.
goto end
)
if "%1" == "epub" (
%SPHINXBUILD% -b epub %ALLSPHINXOPTS% %BUILDDIR%/epub
if errorlevel 1 exit /b 1
echo.
echo.Build finished. The epub file is in %BUILDDIR%/epub.
goto end
)
if "%1" == "latex" (
%SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex
if errorlevel 1 exit /b 1
echo.
echo.Build finished; the LaTeX files are in %BUILDDIR%/latex.
goto end
)
if "%1" == "latexpdf" (
%SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex
cd %BUILDDIR%/latex
make all-pdf
cd %BUILDDIR%/..
echo.
echo.Build finished; the PDF files are in %BUILDDIR%/latex.
goto end
)
if "%1" == "latexpdfja" (
%SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex
cd %BUILDDIR%/latex
make all-pdf-ja
cd %BUILDDIR%/..
echo.
echo.Build finished; the PDF files are in %BUILDDIR%/latex.
goto end
)
if "%1" == "text" (
%SPHINXBUILD% -b text %ALLSPHINXOPTS% %BUILDDIR%/text
if errorlevel 1 exit /b 1
echo.
echo.Build finished. The text files are in %BUILDDIR%/text.
goto end
)
if "%1" == "man" (
%SPHINXBUILD% -b man %ALLSPHINXOPTS% %BUILDDIR%/man
if errorlevel 1 exit /b 1
echo.
echo.Build finished. The manual pages are in %BUILDDIR%/man.
goto end
)
if "%1" == "texinfo" (
%SPHINXBUILD% -b texinfo %ALLSPHINXOPTS% %BUILDDIR%/texinfo
if errorlevel 1 exit /b 1
echo.
echo.Build finished. The Texinfo files are in %BUILDDIR%/texinfo.
goto end
)
if "%1" == "gettext" (
%SPHINXBUILD% -b gettext %I18NSPHINXOPTS% %BUILDDIR%/locale
if errorlevel 1 exit /b 1
echo.
echo.Build finished. The message catalogs are in %BUILDDIR%/locale.
goto end
)
if "%1" == "changes" (
%SPHINXBUILD% -b changes %ALLSPHINXOPTS% %BUILDDIR%/changes
if errorlevel 1 exit /b 1
echo.
echo.The overview file is in %BUILDDIR%/changes.
goto end
)
if "%1" == "linkcheck" (
%SPHINXBUILD% -b linkcheck %ALLSPHINXOPTS% %BUILDDIR%/linkcheck
if errorlevel 1 exit /b 1
echo.
echo.Link check complete; look for any errors in the above output ^
or in %BUILDDIR%/linkcheck/output.txt.
goto end
)
if "%1" == "doctest" (
%SPHINXBUILD% -b doctest %ALLSPHINXOPTS% %BUILDDIR%/doctest
if errorlevel 1 exit /b 1
echo.
echo.Testing of doctests in the sources finished, look at the ^
results in %BUILDDIR%/doctest/output.txt.
goto end
)
if "%1" == "xml" (
%SPHINXBUILD% -b xml %ALLSPHINXOPTS% %BUILDDIR%/xml
if errorlevel 1 exit /b 1
echo.
echo.Build finished. The XML files are in %BUILDDIR%/xml.
goto end
)
if "%1" == "pseudoxml" (
%SPHINXBUILD% -b pseudoxml %ALLSPHINXOPTS% %BUILDDIR%/pseudoxml
if errorlevel 1 exit /b 1
echo.
echo.Build finished. The pseudo-XML files are in %BUILDDIR%/pseudoxml.
goto end
)
:end
validators-0.14.2/setup.py 0000664 0000000 0000000 00000004032 13612537675 0015476 0 ustar 00root root 0000000 0000000 # -*- coding: utf-8 -*-
"""
validators
----------
Python Data Validation for Humans™.
"""
from setuptools import setup, find_packages
import os
import re
import sys
PY3 = sys.version_info[0] == 3
HERE = os.path.dirname(os.path.abspath(__file__))
def get_version():
filename = os.path.join(HERE, 'validators', '__init__.py')
with open(filename) as f:
contents = f.read()
pattern = r"^__version__ = '(.*?)'$"
return re.search(pattern, contents, re.MULTILINE).group(1)
extras_require = {
'test': [
'pytest>=2.2.3',
'flake8>=2.4.0',
'isort>=4.2.2'
],
}
install_requires = [
'six>=1.4.0',
'decorator>=3.4.0',
]
setup(
name='validators',
version=get_version(),
url='https://github.com/kvesteri/validators',
license='MIT',
author='Konsta Vesterinen',
author_email='konsta@fastmonkeys.com',
description='Python Data Validation for Humans™.',
long_description=__doc__,
packages=find_packages('.', exclude=['tests', 'tests.*']),
zip_safe=False,
include_package_data=True,
platforms='any',
install_requires=install_requires,
build_requires=install_requires,
extras_require=extras_require,
classifiers=[
'Environment :: Web Environment',
'Intended Audience :: Developers',
'License :: OSI Approved :: MIT License',
'Operating System :: OS Independent',
'Programming Language :: Python',
'Programming Language :: Python :: 2',
'Programming Language :: Python :: 2.7',
'Programming Language :: Python :: 3',
'Programming Language :: Python :: 3.4',
'Programming Language :: Python :: 3.5',
'Programming Language :: Python :: 3.6',
'Programming Language :: Python :: 3.7',
'Programming Language :: Python :: Implementation :: CPython',
'Programming Language :: Python :: Implementation :: PyPy',
'Topic :: Internet :: WWW/HTTP :: Dynamic Content',
'Topic :: Software Development :: Libraries :: Python Modules'
]
)
validators-0.14.2/tests/ 0000775 0000000 0000000 00000000000 13612537675 0015127 5 ustar 00root root 0000000 0000000 validators-0.14.2/tests/__init__.py 0000664 0000000 0000000 00000000000 13612537675 0017226 0 ustar 00root root 0000000 0000000 validators-0.14.2/tests/i18n/ 0000775 0000000 0000000 00000000000 13612537675 0015706 5 ustar 00root root 0000000 0000000 validators-0.14.2/tests/i18n/__init__.py 0000664 0000000 0000000 00000000000 13612537675 0020005 0 ustar 00root root 0000000 0000000 validators-0.14.2/tests/i18n/test_es.py 0000664 0000000 0000000 00000004117 13612537675 0017731 0 ustar 00root root 0000000 0000000 # -*- coding: utf-8 -*-
import pytest
from validators import ValidationFailure
from validators.i18n.es import es_cif, es_doi, es_nie, es_nif
@pytest.mark.parametrize(('value',), [
('B25162520',),
('U4839822F',),
('B96817697',),
('P7067074J',),
('Q7899705C',),
('C75098681',),
('G76061860',),
('C71345375',),
('G20558169',),
('U5021960I',),
])
def test_returns_true_on_valid_cif(value):
assert es_cif(value)
@pytest.mark.parametrize(('value',), [
('12345',),
('ABCDEFGHI',),
('Z5021960I',),
])
def test_returns_false_on_invalid_cif(value):
result = es_cif(value)
assert isinstance(result, ValidationFailure)
@pytest.mark.parametrize(('value',), [
('X0095892M',),
('X8868108K',),
('X2911154K',),
('Y2584969J',),
('X7536157T',),
('Y5840388N',),
('Z2915723H',),
('Y4002236C',),
('X7750702R',),
('Y0408759V',),
])
def test_returns_true_on_valid_nie(value):
assert es_nie(value)
@pytest.mark.parametrize(('value',), [
('K0000023T',),
('L0000024R',),
('M0000025W',),
('00000026A',),
('00000027G',),
('00000028M',),
('00000029Y',),
('00000030F',),
('00000031P',),
('00000032D',),
('00000033X',),
('00000034B',),
('00000035N',),
('00000036J',),
('00000037Z',),
('00000038S',),
('00000039Q',),
('00000040V',),
('00000041H',),
('00000042L',),
('00000043C',),
('00000044K',),
('00000045E',),
])
def test_returns_true_on_valid_nif(value):
assert es_nif(value)
@pytest.mark.parametrize(('value',), [
('12345',),
('X0000000T',),
('00000000T',),
('00000001R',),
])
def test_returns_false_on_invalid_nif(value):
result = es_nif(value)
assert isinstance(result, ValidationFailure)
@pytest.mark.parametrize(('value',), [
# CIFs
('B25162520',),
('U4839822F',),
('B96817697',),
# NIEs
('X0095892M',),
('X8868108K',),
('X2911154K',),
# NIFs
('26643189N',),
('07060225F',),
('49166693F',),
])
def test_returns_true_on_valid_doi(value):
assert es_doi(value)
validators-0.14.2/tests/i18n/test_fi.py 0000664 0000000 0000000 00000002722 13612537675 0017720 0 ustar 00root root 0000000 0000000 # -*- coding: utf-8 -*-
import pytest
from validators import ValidationFailure
from validators.i18n.fi import fi_business_id, fi_ssn
@pytest.mark.parametrize(('value',), [
('2336509-6',), # Supercell
('0112038-9',), # Fast Monkeys
('2417581-7',), # Nokia
])
def test_returns_true_on_valid_business_id(value):
assert fi_business_id(value)
@pytest.mark.parametrize(('value',), [
(None,),
('',),
('1233312312',),
('1333333-8',),
('1231233-9',),
])
def test_returns_failed_validation_on_invalid_email(value):
assert isinstance(fi_business_id(value), ValidationFailure)
@pytest.mark.parametrize(('value',), [
('010190-002R',),
('010101-0101',),
('010101+0101',),
('010101A0101',),
('010190-900P',),
])
def test_returns_true_on_valid_ssn(value):
assert fi_ssn(value)
@pytest.mark.parametrize(('value',), [
(None,),
('',),
('010190-001P',), # Too low serial
('010190-000N',), # Too low serial
('000190-0023',), # Invalid day
('010090-002X',), # Invalid month
('010190-002r',), # Invalid checksum
('101010-0102',),
('10a010-0101',),
('101010-0\xe401',),
('101010b0101',)
])
def test_returns_failed_validation_on_invalid_ssn(value):
assert isinstance(fi_ssn(value), ValidationFailure)
def test_returns_failed_validation_on_temporal_ssn_when_not_allowed():
assert isinstance(
fi_ssn('010190-900P', allow_temporal_ssn=False),
ValidationFailure
)
validators-0.14.2/tests/test_between.py 0000664 0000000 0000000 00000001537 13612537675 0020177 0 ustar 00root root 0000000 0000000 # -*- coding: utf-8 -*-
import pytest
import validators
@pytest.mark.parametrize(('value', 'min', 'max'), [
(12, 11, 13),
(12, None, 14),
(12, 11, None),
(12, 12, 12)
])
def test_returns_true_on_valid_range(value, min, max):
assert validators.between(value, min=min, max=max)
@pytest.mark.parametrize(('value', 'min', 'max'), [
(12, 13, 12),
(12, None, None),
])
def test_raises_assertion_error_for_invalid_args(value, min, max):
with pytest.raises(AssertionError):
assert validators.between(value, min=min, max=max)
@pytest.mark.parametrize(('value', 'min', 'max'), [
(12, 13, 14),
(12, None, 11),
(12, 13, None)
])
def test_returns_failed_validation_on_invalid_range(value, min, max):
result = validators.between(value, min=min, max=max)
assert isinstance(result, validators.ValidationFailure)
validators-0.14.2/tests/test_domain.py 0000664 0000000 0000000 00000001623 13612537675 0020011 0 ustar 00root root 0000000 0000000 # -*- coding: utf-8 -*-
import pytest
from validators import domain, ValidationFailure
@pytest.mark.parametrize('value', [
'example.com',
'xn----gtbspbbmkef.xn--p1ai',
'underscore_subdomain.example.com',
'something.versicherung',
'someThing.versicherung',
'11.com',
'3.cn',
'a.cn',
'sub1.sub2.sample.co.uk',
'somerandomexample.xn--fiqs8s',
'kräuter.com',
'über.com'
])
def test_returns_true_on_valid_domain(value):
assert domain(value)
@pytest.mark.parametrize('value', [
'example.com/',
'example.com:4444',
'example.-com',
'example.',
'-example.com',
'example-.com',
'_example.com',
'example_.com',
'example',
'a......b.com',
'a.123',
'123.123',
'123.123.123',
'123.123.123.123'
])
def test_returns_failed_validation_on_invalid_domain(value):
assert isinstance(domain(value), ValidationFailure)
validators-0.14.2/tests/test_email.py 0000664 0000000 0000000 00000002262 13612537675 0017631 0 ustar 00root root 0000000 0000000 # -*- coding: utf-8 -*-
import pytest
from validators import email, ValidationFailure
@pytest.mark.parametrize(('value', 'whitelist'), [
('email@here.com', None),
('weirder-email@here.and.there.com', None),
('email@[127.0.0.1]', None),
('example@valid-----hyphens.com', None),
('example@valid-with-hyphens.com', None),
('test@domain.with.idn.tld.उदाहरण.परीक्षा', None),
('email@localhost', None),
('email@localdomain', ['localdomain']),
('"test@test"@example.com', None),
('"\\\011"@here.com', None),
])
def test_returns_true_on_valid_email(value, whitelist):
assert email(value, whitelist=whitelist)
@pytest.mark.parametrize(('value',), [
(None,),
('',),
('abc',),
('abc@',),
('abc@bar',),
('a @x.cz',),
('abc@.com',),
('something@@somewhere.com',),
('email@127.0.0.1',),
('example@invalid-.com',),
('example@-invalid.com',),
('example@inv-.alid-.com',),
('example@inv-.-alid.com',),
# Quoted-string format (CR not allowed)
('"\\\012"@here.com',),
])
def test_returns_failed_validation_on_invalid_email(value):
assert isinstance(email(value), ValidationFailure)
validators-0.14.2/tests/test_extremes.py 0000664 0000000 0000000 00000001456 13612537675 0020402 0 ustar 00root root 0000000 0000000 # -*- coding: utf-8 -*-
import pytest
from validators import Max, Min
@pytest.mark.parametrize(('value',), [
(None,),
('',),
(12,),
(Min,),
])
def test_max_is_greater_than_every_other_value(value):
assert value < Max
assert Max > value
def test_max_is_not_greater_than_itself():
assert not (Max < Max)
def test_other_comparison_methods_for_max():
assert Max <= Max
assert Max == Max
assert not (Max != Max)
@pytest.mark.parametrize(('value',), [
(None,),
('',),
(12,),
(Max,),
])
def test_min_is_smaller_than_every_other_value(value):
assert value > Min
def test_min_is_not_greater_than_itself():
assert not (Min < Min)
def test_other_comparison_methods_for_min():
assert Min <= Min
assert Min == Min
assert not (Min != Min)
validators-0.14.2/tests/test_iban.py 0000664 0000000 0000000 00000000734 13612537675 0017455 0 ustar 00root root 0000000 0000000 # -*- coding: utf-8 -*-
import pytest
import validators
@pytest.mark.parametrize('value', [
'GB82WEST12345698765432',
'NO9386011117947'
])
def test_returns_true_on_valid_iban(value):
assert validators.iban(value)
@pytest.mark.parametrize('value', [
'GB81WEST12345698765432',
'NO9186011117947'
])
def test_returns_failed_validation_on_invalid_iban(value):
result = validators.iban(value)
assert isinstance(result, validators.ValidationFailure)
validators-0.14.2/tests/test_ipv4.py 0000664 0000000 0000000 00000001071 13612537675 0017421 0 ustar 00root root 0000000 0000000 # -*- coding: utf-8 -*-
import pytest
from validators import ipv4, ipv6, ValidationFailure
@pytest.mark.parametrize(('address',), [
('127.0.0.1',),
('123.5.77.88',),
('12.12.12.12',),
])
def test_returns_true_on_valid_ipv4_address(address):
assert ipv4(address)
assert not ipv6(address)
@pytest.mark.parametrize(('address',), [
('abc.0.0.1',),
('1278.0.0.1',),
('127.0.0.abc',),
('900.200.100.75',),
])
def test_returns_failed_validation_on_invalid_ipv4_address(address):
assert isinstance(ipv4(address), ValidationFailure)
validators-0.14.2/tests/test_ipv4_cidr.py 0000664 0000000 0000000 00000001114 13612537675 0020420 0 ustar 00root root 0000000 0000000 # -*- coding: utf-8 -*-
import pytest
from validators import ipv4_cidr, ipv6_cidr, ValidationFailure
@pytest.mark.parametrize(('cidr',), [
('127.0.0.1/0',),
('123.5.77.88/8',),
('12.12.12.12/32',),
])
def test_returns_true_on_valid_ipv4_cidr(cidr):
assert ipv4_cidr(cidr)
assert not ipv6_cidr(cidr)
@pytest.mark.parametrize(('cidr',), [
('abc.0.0.1',),
('1.1.1.1',),
('1.1.1.1/-1',),
('1.1.1.1/33',),
('1.1.1.1/foo',),
])
def test_returns_failed_validation_on_invalid_ipv4_cidr(cidr):
assert isinstance(ipv4_cidr(cidr), ValidationFailure)
validators-0.14.2/tests/test_ipv6.py 0000664 0000000 0000000 00000001204 13612537675 0017421 0 ustar 00root root 0000000 0000000 # -*- coding: utf-8 -*-
import pytest
from validators import ipv4, ipv6, ValidationFailure
@pytest.mark.parametrize(('address',), [
('::1',),
('dead:beef:0:0:0:0:42:1',),
('abcd:ef::42:1',),
('0:0:0:0:0:ffff:1.2.3.4',),
('::192.168.30.2',),
])
def test_returns_true_on_valid_ipv6_address(address):
assert ipv6(address)
assert not ipv4(address)
@pytest.mark.parametrize(('address',), [
('abc.0.0.1',),
('abcd:1234::123::1',),
('1:2:3:4:5:6:7:8:9',),
('abcd::1ffff',),
])
def test_returns_failed_validation_on_invalid_ipv6_address(address):
assert isinstance(ipv6(address), ValidationFailure)
validators-0.14.2/tests/test_ipv6_cidr.py 0000664 0000000 0000000 00000001345 13612537675 0020430 0 ustar 00root root 0000000 0000000 # -*- coding: utf-8 -*-
import pytest
from validators import ipv4_cidr, ipv6_cidr, ValidationFailure
@pytest.mark.parametrize(('cidr',), [
('::1/0',),
('dead:beef:0:0:0:0:42:1/8',),
('abcd:ef::42:1/32',),
('0:0:0:0:0:ffff:1.2.3.4/64',),
('::192.168.30.2/128',),
])
def test_returns_true_on_valid_ipv6_cidr(cidr):
assert ipv6_cidr(cidr)
assert not ipv4_cidr(cidr)
@pytest.mark.parametrize(('cidr',), [
('abc.0.0.1',),
('abcd:1234::123::1',),
('1:2:3:4:5:6:7:8:9',),
('abcd::1ffff',),
('1.1.1.1',),
('::1',),
('::1/129',),
('::1/-1',),
('::1/foo',),
])
def test_returns_failed_validation_on_invalid_ipv6_cidr(cidr):
assert isinstance(ipv6_cidr(cidr), ValidationFailure)
validators-0.14.2/tests/test_length.py 0000664 0000000 0000000 00000001734 13612537675 0020026 0 ustar 00root root 0000000 0000000 # -*- coding: utf-8 -*-
import pytest
import validators
@pytest.mark.parametrize(('value', 'min', 'max'), [
('password', 2, 10),
('password', None, 10),
('password', 2, None),
('password', 8, 8)
])
def test_returns_true_on_valid_length(value, min, max):
assert validators.length(value, min=min, max=max)
@pytest.mark.parametrize(('value', 'min', 'max'), [
('something', 13, 12),
('something', -1, None),
('something', -1, None),
('something', -3, -2)
])
def test_raises_assertion_error_for_invalid_args(value, min, max):
with pytest.raises(AssertionError):
assert validators.length(value, min=min, max=max)
@pytest.mark.parametrize(('value', 'min', 'max'), [
('something', 13, 14),
('something', None, 6),
('something', 13, None)
])
def test_returns_failed_validation_on_invalid_range(value, min, max):
assert isinstance(
validators.length(value, min=min, max=max),
validators.ValidationFailure
)
validators-0.14.2/tests/test_mac_address.py 0000664 0000000 0000000 00000001031 13612537675 0021000 0 ustar 00root root 0000000 0000000 # -*- coding: utf-8 -*-
import pytest
from validators import mac_address, ValidationFailure
@pytest.mark.parametrize(('address',), [
('01:23:45:67:ab:CD',),
])
def test_returns_true_on_valid_mac_address(address):
assert mac_address(address)
@pytest.mark.parametrize(('address',), [
('00:00:00:00:00',),
('01:23:45:67:89:',),
('01:23:45:67:89:gh',),
('123:23:45:67:89:00',),
])
def test_returns_failed_validation_on_invalid_mac_address(address):
assert isinstance(mac_address(address), ValidationFailure)
validators-0.14.2/tests/test_md5.py 0000664 0000000 0000000 00000001067 13612537675 0017231 0 ustar 00root root 0000000 0000000 # -*- coding: utf-8 -*-
import pytest
import validators
@pytest.mark.parametrize('value', [
'd41d8cd98f00b204e9800998ecf8427e',
'D41D8CD98F00B204E9800998ECF8427E'
])
def test_returns_true_on_valid_md5(value):
assert validators.md5(value)
@pytest.mark.parametrize('value', [
'z41d8cd98f00b204e9800998ecf8427e',
'z8cd98f00b204e9800998ecf8427e',
'z4aaaa1d8cd98f00b204e9800998ecf8427e'
])
def test_returns_failed_validation_on_invalid_md5(value):
result = validators.md5(value)
assert isinstance(result, validators.ValidationFailure)
validators-0.14.2/tests/test_sha1.py 0000664 0000000 0000000 00000001142 13612537675 0017372 0 ustar 00root root 0000000 0000000 # -*- coding: utf-8 -*-
import pytest
import validators
@pytest.mark.parametrize('value', [
'da39a3ee5e6b4b0d3255bfef95601890afd80709',
'DA39A3EE5E6B4B0D3255BFEF95601890AFD80709'
])
def test_returns_true_on_valid_sha1(value):
assert validators.sha1(value)
@pytest.mark.parametrize('value', [
'za39a3ee5e6b4b0d3255bfef95601890afd80709',
'da39e5e6b4b0d3255bfef95601890afd80709',
'daaaa39a3ee5e6b4b0d3255bfef95601890afd80709'
])
def test_returns_failed_validation_on_invalid_sha1(value):
result = validators.sha1(value)
assert isinstance(result, validators.ValidationFailure)
validators-0.14.2/tests/test_sha224.py 0000664 0000000 0000000 00000001272 13612537675 0017545 0 ustar 00root root 0000000 0000000 # -*- coding: utf-8 -*-
import pytest
import validators
@pytest.mark.parametrize('value', [
'd14a028c2a3a2bc9476102bb288234c415a2b01f828ea62ac5b3e42f',
'D14A028C2A3A2BC9476102BB288234C415A2B01F828EA62AC5B3E42F'
])
def test_returns_true_on_valid_sha224(value):
assert validators.sha224(value)
@pytest.mark.parametrize('value', [
'z14a028c2a3a2bc9476102bb288234c415a2b01f828ea62ac5b3e42f',
'd028c2a3a2bc9476102bb288234c415a2b01f828ea62ac5b3e42f',
'daaa14a028c2a3a2bc9476102bb288234c415a2b01f828ea62ac5b3e42f'
])
def test_returns_failed_validation_on_invalid_sha224(value):
result = validators.sha224(value)
assert isinstance(result, validators.ValidationFailure)
validators-0.14.2/tests/test_sha256.py 0000664 0000000 0000000 00000001344 13612537675 0017552 0 ustar 00root root 0000000 0000000 # -*- coding: utf-8 -*-
import pytest
import validators
@pytest.mark.parametrize('value', [
'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855',
'E3B0C44298FC1C149AFBF4C8996FB92427AE41E4649B934CA495991B7852B855'
])
def test_returns_true_on_valid_sha256(value):
assert validators.sha256(value)
@pytest.mark.parametrize('value', [
'z3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855',
'ec44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855',
'eaaaa3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855',
])
def test_returns_failed_validation_on_invalid_sha256(value):
result = validators.sha256(value)
assert isinstance(result, validators.ValidationFailure)
validators-0.14.2/tests/test_sha512.py 0000664 0000000 0000000 00000002252 13612537675 0017544 0 ustar 00root root 0000000 0000000 # -*- coding: utf-8 -*-
import pytest
import validators
@pytest.mark.parametrize('value', [
(
'cf83e1357eefb8bdf1542850d66d8007d620e4050b5715dc83f4a921d36ce9ce47d0d'
'13c5d85f2b0ff8318d2877eec2f63b931bd47417a81a538327af927da3e'
),
(
'CF83E1357EEFB8BDF1542850D66D8007D620E4050B5715DC83F4A921D36CE9CE47D0D'
'13C5D85F2B0FF8318D2877EEC2F63B931BD47417A81A538327AF927DA3E'
)
])
def test_returns_true_on_valid_sha512(value):
assert validators.sha512(value)
@pytest.mark.parametrize('value', [
(
'zf83e1357eefb8bdf1542850d66d8007d620e4050b5715dc83f4a921d36ce9ce47d0d'
'13c5d85f2b0ff8318d2877eec2f63b931bd47417a81a538327af927da3e'
),
(
'cf8357eefb8bdf1542850d66d8007d620e4050b5715dc83f4a921d36ce9ce47d0d13c'
'5d85f2b0ff8318d2877eec2f63b931bd47417a81a538327af927da3e'
),
(
'cf8aaaa3e1357eefb8bdf1542850d66d8007d620e4050b5715dc83f4a921d36ce9ce4'
'7d0d13c5d85f2b0ff8318d2877eec2f63b931bd47417a81a538327af927da3e'
)
])
def test_returns_failed_validation_on_invalid_sha512(value):
result = validators.sha512(value)
assert isinstance(result, validators.ValidationFailure)
validators-0.14.2/tests/test_slug.py 0000664 0000000 0000000 00000000736 13612537675 0017520 0 ustar 00root root 0000000 0000000 # -*- coding: utf-8 -*-
import pytest
from validators import slug, ValidationFailure
@pytest.mark.parametrize('value', [
'123-12312-asdasda',
'123____123',
'dsadasd-dsadas',
])
def test_returns_true_on_valid_slug(value):
assert slug(value)
@pytest.mark.parametrize('value', [
'some.slug',
'1231321%',
' 21312',
'123asda&',
])
def test_returns_failed_validation_on_invalid_slug(value):
assert isinstance(slug(value), ValidationFailure)
validators-0.14.2/tests/test_url.py 0000664 0000000 0000000 00000010657 13612537675 0017353 0 ustar 00root root 0000000 0000000 # -*- coding: utf-8 -*-
import pytest
from validators import url, ValidationFailure
@pytest.mark.parametrize('address', [
u'http://foobar.dk',
u'http://foobar.museum/foobar',
u'http://fo.com',
u'http://FOO.com',
u'http://foo.com/blah_blah',
u'http://foo.com/blah_blah/',
u'http://foo.com/blah_blah_(wikipedia)',
u'http://foo.com/blah_blah_(wikipedia)_(again)',
u'http://www.example.com/wpstyle/?p=364',
u'https://www.example.com/foo/?bar=baz&inga=42&quux',
u'https://www.example.com?bar=baz',
u'http://✪df.ws/123',
u'http://userid:password@example.com:8080',
u'http://userid:password@example.com:8080/',
u'http://userid@example.com',
u'http://userid@example.com/',
u'http://userid@example.com:8080',
u'http://userid@example.com:8080/',
u'http://userid:password@example.com',
u'http://userid:password@example.com/',
u'http://142.42.1.1/',
u'http://142.42.1.1:8080/',
u'http://➡.ws/䨹',
u'http://⌘.ws',
u'http://⌘.ws/',
u'http://foo.com/blah_(wikipedia)#cite-1',
u'http://foo.com/blah_(wikipedia)_blah#cite-1',
u'http://foo.com/unicode_(✪)_in_parens',
u'http://foo.com/(something)?after=parens',
u'http://☺.damowmow.com/',
u'http://code.google.com/events/#&product=browser',
u'http://j.mp',
u'ftp://foo.bar/baz',
u'http://foo.bar/?q=Test%20URL-encoded%20stuff',
u'http://مثال.إختبار',
u'http://例子.测试',
u'http://उदाहरण.परीक्षा',
u'http://-.~_!$&\'()*+,;=:%40:80%2f::::::@example.com',
u'http://1337.net',
u'http://a.b-c.de',
u'http://223.255.255.254',
u'http://10.1.1.1',
u'http://10.1.1.254',
u'http://127.0.0.1:8080',
u'http://127.0.10.150',
u'http://localhost',
u'http://localhost:8000',
u'http://[FEDC:BA98:7654:3210:FEDC:BA98:7654:3210]:80/index.html',
u'http://[1080:0:0:0:8:800:200C:417A]/index.html',
u'http://[3ffe:2a00:100:7031::1]',
u'http://[1080::8:800:200C:417A]/foo',
u'http://[::192.9.5.5]/ipng',
u'http://[::FFFF:129.144.52.38]:80/index.html',
u'http://[2010:836B:4179::836B:4179]',
])
def test_returns_true_on_valid_url(address):
assert url(address)
@pytest.mark.parametrize('address, public', [
(u'http://foo.bar', True),
(u'http://username:password@example.com:4010/', False),
(u'http://username:password@112.168.10.10:4010/', True),
(u'http://username:password@192.168.10.10:4010/', False),
(u'http://10.0.10.1', False),
(u'http://127.0.0.1', False),
])
def test_returns_true_on_valid_public_url(address, public):
assert url(address, public=public)
@pytest.mark.parametrize('address', [
'http://foobar',
'foobar.dk',
'http://127.0.0/asdf',
'http://foobar.d',
'http://foobar.12',
'http://foobar',
'htp://foobar.com',
'http://foobar..com',
'http://fo..com',
'http://',
'http://.',
'http://..',
'http://../',
'http://?',
'http://??',
'http://??/',
'http://#',
'http://##',
'http://##/',
'http://foo.bar?q=Spaces should be encoded',
'//',
'//a',
'///a',
'///',
'http:///a',
'foo.com',
'rdar://1234',
'h://test',
'http:// shouldfail.com',
':// should fail',
'http://foo.bar/foo(bar)baz quux',
'ftps://foo.bar/',
'http://-error-.invalid/',
'http://a.b--c.de/',
'http://-a.b.co',
'http://a.b-.co',
'http://0.0.0.0',
'http://10.1.1.0',
'http://10.1.1.255',
'http://224.1.1.1',
'http://1.1.1.1.1',
'http://123.123.123',
'http://3628126748',
'http://.www.foo.bar/',
'http://www.foo.bar./',
'http://.www.foo.bar./',
'http://127.12.0.260',
'http://example.com/">user@example.com',
'http://[2010:836B:4179::836B:4179',
'http://2010:836B:4179::836B:4179',
'http://2010:836B:4179::836B:4179:80/index.html',
])
def test_returns_failed_validation_on_invalid_url(address):
assert isinstance(url(address), ValidationFailure)
@pytest.mark.parametrize('address, public', [
(u'http://username:password@192.168.10.10:4010/', True),
(u'http://10.0.10.1', True),
(u'http://127.0.0.1', True),
(u'foo://127.0.0.1', True),
(u'http://username:password@127.0.0.1:8080', True),
(u'http://localhost', True),
(u'http://localhost:8000', True),
])
def test_returns_failed_validation_on_invalid_public_url(address, public):
assert isinstance(url(address, public=public), ValidationFailure)
validators-0.14.2/tests/test_uuid.py 0000664 0000000 0000000 00000001131 13612537675 0017502 0 ustar 00root root 0000000 0000000 # -*- coding: utf-8 -*-
import pytest
from validators import uuid, ValidationFailure
@pytest.mark.parametrize(('value',), [
('2bc1c94f-0deb-43e9-92a1-4775189ec9f8',),
])
def test_returns_true_on_valid_mac_address(value):
assert uuid(value)
@pytest.mark.parametrize(('value',), [
('2bc1c94f-deb-43e9-92a1-4775189ec9f8',),
('2bc1c94f-0deb-43e9-92a1-4775189ec9f',),
('gbc1c94f-0deb-43e9-92a1-4775189ec9f8',),
('2bc1c94f 0deb-43e9-92a1-4775189ec9f8',),
])
def test_returns_failed_validation_on_invalid_mac_address(value):
assert isinstance(uuid(value), ValidationFailure)
validators-0.14.2/tests/test_validation_failure.py 0000664 0000000 0000000 00000001135 13612537675 0022401 0 ustar 00root root 0000000 0000000 import six
import validators
obj_repr = (
"ValidationFailure(func=between"
)
class TestValidationFailure(object):
def setup_method(self, method):
self.obj = validators.between(3, min=4, max=5)
def test_boolean_coerce(self):
assert not bool(self.obj)
assert not self.obj
def test_repr(self):
assert obj_repr in repr(self.obj)
def test_unicode(self):
assert obj_repr in six.text_type(self.obj)
def test_arguments_as_properties(self):
assert self.obj.value == 3
assert self.obj.min == 4
assert self.obj.max == 5
validators-0.14.2/validators/ 0000775 0000000 0000000 00000000000 13612537675 0016135 5 ustar 00root root 0000000 0000000 validators-0.14.2/validators/__init__.py 0000664 0000000 0000000 00000001465 13612537675 0020254 0 ustar 00root root 0000000 0000000 from .between import between
from .domain import domain
from .email import email
from .extremes import Max, Min
from .hashes import md5, sha1, sha224, sha256, sha512
from .i18n import fi_business_id, fi_ssn
from .iban import iban
from .ip_address import ipv4, ipv4_cidr, ipv6, ipv6_cidr
from .length import length
from .mac_address import mac_address
from .slug import slug
from .truthy import truthy
from .url import url
from .utils import ValidationFailure, validator
from .uuid import uuid
__all__ = ('between', 'domain', 'email', 'Max', 'Min', 'md5', 'sha1', 'sha224',
'sha256', 'sha512', 'fi_business_id', 'fi_ssn', 'iban', 'ipv4',
'ipv4_cidr', 'ipv6', 'ipv6_cidr', 'length', 'mac_address', 'slug',
'truthy', 'url', 'ValidationFailure', 'validator', 'uuid')
__version__ = '0.14.2'
validators-0.14.2/validators/between.py 0000664 0000000 0000000 00000003050 13612537675 0020136 0 ustar 00root root 0000000 0000000 from .extremes import Max, Min
from .utils import validator
@validator
def between(value, min=None, max=None):
"""
Validate that a number is between minimum and/or maximum value.
This will work with any comparable type, such as floats, decimals and dates
not just integers.
This validator is originally based on `WTForms NumberRange validator`_.
.. _WTForms NumberRange validator:
https://github.com/wtforms/wtforms/blob/master/wtforms/validators.py
Examples::
>>> from datetime import datetime
>>> between(5, min=2)
True
>>> between(13.2, min=13, max=14)
True
>>> between(500, max=400)
ValidationFailure(func=between, args=...)
>>> between(
... datetime(2000, 11, 11),
... min=datetime(1999, 11, 11)
... )
True
:param min:
The minimum required value of the number. If not provided, minimum
value will not be checked.
:param max:
The maximum value of the number. If not provided, maximum value
will not be checked.
.. versionadded:: 0.2
"""
if min is None and max is None:
raise AssertionError(
'At least one of `min` or `max` must be specified.'
)
if min is None:
min = Min
if max is None:
max = Max
try:
min_gt_max = min > max
except TypeError:
min_gt_max = max < min
if min_gt_max:
raise AssertionError('`min` cannot be more than `max`.')
return min <= value and max >= value
validators-0.14.2/validators/domain.py 0000664 0000000 0000000 00000002566 13612537675 0017767 0 ustar 00root root 0000000 0000000 import re
import six
from .utils import validator
if six.PY3:
text_type = str
unicode = str
else:
text_type = unicode
pattern = re.compile(
r'^(?:[a-zA-Z0-9]' # First character of the domain
r'(?:[a-zA-Z0-9-_]{0,61}[A-Za-z0-9])?\.)' # Sub domain + hostname
r'+[A-Za-z0-9][A-Za-z0-9-_]{0,61}' # First 61 characters of the gTLD
r'[A-Za-z]$' # Last character of the gTLD
)
def to_unicode(obj, charset='utf-8', errors='strict'):
if obj is None:
return None
if not isinstance(obj, bytes):
return text_type(obj)
return obj.decode(charset, errors)
@validator
def domain(value):
"""
Return whether or not given value is a valid domain.
If the value is valid domain name this function returns ``True``, otherwise
:class:`~validators.utils.ValidationFailure`.
Examples::
>>> domain('example.com')
True
>>> domain('example.com/')
ValidationFailure(func=domain, ...)
Supports IDN domains as well::
>>> domain('xn----gtbspbbmkef.xn--p1ai')
True
.. versionadded:: 0.9
.. versionchanged:: 0.10
Added support for internationalized domain name (IDN) validation.
:param value: domain string to validate
"""
try:
return pattern.match(to_unicode(value).encode('idna').decode('ascii'))
except UnicodeError:
return False
validators-0.14.2/validators/email.py 0000664 0000000 0000000 00000003571 13612537675 0017604 0 ustar 00root root 0000000 0000000 import re
from .utils import validator
user_regex = re.compile(
# dot-atom
r"(^[-!#$%&'*+/=?^_`{}|~0-9A-Z]+"
r"(\.[-!#$%&'*+/=?^_`{}|~0-9A-Z]+)*$"
# quoted-string
r'|^"([\001-\010\013\014\016-\037!#-\[\]-\177]|'
r"""\\[\001-\011\013\014\016-\177])*"$)""",
re.IGNORECASE
)
domain_regex = re.compile(
# domain
r'(?:[A-Z0-9](?:[A-Z0-9-]{0,61}[A-Z0-9])?\.)+'
r'(?:[A-Z]{2,6}\.?|[A-Z0-9-]{2,}\.?$)'
# literal form, ipv4 address (SMTP 4.1.3)
r'|^\[(25[0-5]|2[0-4]\d|[0-1]?\d?\d)'
r'(\.(25[0-5]|2[0-4]\d|[0-1]?\d?\d)){3}\]$',
re.IGNORECASE)
domain_whitelist = ['localhost']
@validator
def email(value, whitelist=None):
"""
Validate an email address.
This validator is based on `Django's email validator`_. Returns
``True`` on success and :class:`~validators.utils.ValidationFailure`
when validation fails.
Examples::
>>> email('someone@example.com')
True
>>> email('bogus@@')
ValidationFailure(func=email, ...)
.. _Django's email validator:
https://github.com/django/django/blob/master/django/core/validators.py
.. versionadded:: 0.1
:param value: value to validate
:param whitelist: domain names to whitelist
:copyright: (c) Django Software Foundation and individual contributors.
:license: BSD
"""
if whitelist is None:
whitelist = domain_whitelist
if not value or '@' not in value:
return False
user_part, domain_part = value.rsplit('@', 1)
if not user_regex.match(user_part):
return False
if domain_part not in whitelist and not domain_regex.match(domain_part):
# Try for possible IDN domain-part
try:
domain_part = domain_part.encode('idna').decode('ascii')
return domain_regex.match(domain_part)
except UnicodeError:
return False
return True
validators-0.14.2/validators/extremes.py 0000664 0000000 0000000 00000001737 13612537675 0020353 0 ustar 00root root 0000000 0000000 from functools import total_ordering
@total_ordering
class Min(object):
"""
An object that is less than any other object (except itself).
Inspired by https://pypi.python.org/pypi/Extremes
Examples::
>>> import sys
>>> Min < -sys.maxint
True
>>> Min < None
True
>>> Min < ''
True
.. versionadded:: 0.2
"""
def __lt__(self, other):
if other is Min:
return False
return True
@total_ordering
class Max(object):
"""
An object that is greater than any other object (except itself).
Inspired by https://pypi.python.org/pypi/Extremes
Examples::
>>> import sys
>>> Max > Min
True
>>> Max > sys.maxint
True
>>> Max > 99999999999999999
True
.. versionadded:: 0.2
"""
def __gt__(self, other):
if other is Max:
return False
return True
Min = Min()
Max = Max()
validators-0.14.2/validators/hashes.py 0000664 0000000 0000000 00000004703 13612537675 0017766 0 ustar 00root root 0000000 0000000 import re
from .utils import validator
md5_regex = re.compile(
r"^[0-9a-f]{32}$",
re.IGNORECASE
)
sha1_regex = re.compile(
r"^[0-9a-f]{40}$",
re.IGNORECASE
)
sha224_regex = re.compile(
r"^[0-9a-f]{56}$",
re.IGNORECASE
)
sha256_regex = re.compile(
r"^[0-9a-f]{64}$",
re.IGNORECASE
)
sha512_regex = re.compile(
r"^[0-9a-f]{128}$",
re.IGNORECASE
)
@validator
def md5(value):
"""
Return whether or not given value is a valid MD5 hash.
Examples::
>>> md5('d41d8cd98f00b204e9800998ecf8427e')
True
>>> md5('900zz11')
ValidationFailure(func=md5, args={'value': '900zz11'})
:param value: MD5 string to validate
"""
return md5_regex.match(value)
@validator
def sha1(value):
"""
Return whether or not given value is a valid SHA1 hash.
Examples::
>>> sha1('da39a3ee5e6b4b0d3255bfef95601890afd80709')
True
>>> sha1('900zz11')
ValidationFailure(func=sha1, args={'value': '900zz11'})
:param value: SHA1 string to validate
"""
return sha1_regex.match(value)
@validator
def sha224(value):
"""
Return whether or not given value is a valid SHA224 hash.
Examples::
>>> sha224('d14a028c2a3a2bc9476102bb288234c415a2b01f828ea62ac5b3e42f')
True
>>> sha224('900zz11')
ValidationFailure(func=sha224, args={'value': '900zz11'})
:param value: SHA224 string to validate
"""
return sha224_regex.match(value)
@validator
def sha256(value):
"""
Return whether or not given value is a valid SHA256 hash.
Examples::
>>> sha256(
... 'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b'
... '855'
... )
True
>>> sha256('900zz11')
ValidationFailure(func=sha256, args={'value': '900zz11'})
:param value: SHA256 string to validate
"""
return sha256_regex.match(value)
@validator
def sha512(value):
"""
Return whether or not given value is a valid SHA512 hash.
Examples::
>>> sha512(
... 'cf83e1357eefb8bdf1542850d66d8007d620e4050b5715dc83f4a921d36ce'
... '9ce47d0d13c5d85f2b0ff8318d2877eec2f63b931bd47417a81a538327af9'
... '27da3e'
... )
True
>>> sha512('900zz11')
ValidationFailure(func=sha512, args={'value': '900zz11'})
:param value: SHA512 string to validate
"""
return sha512_regex.match(value)
validators-0.14.2/validators/i18n/ 0000775 0000000 0000000 00000000000 13612537675 0016714 5 ustar 00root root 0000000 0000000 validators-0.14.2/validators/i18n/__init__.py 0000664 0000000 0000000 00000000225 13612537675 0021024 0 ustar 00root root 0000000 0000000 # TODO: remove, let the user import it if they really want it
from .fi import fi_business_id, fi_ssn # noqa
__all__ = ('fi_business_id', 'fi_ssn')
validators-0.14.2/validators/i18n/es.py 0000664 0000000 0000000 00000011630 13612537675 0017676 0 ustar 00root root 0000000 0000000 # -*- coding: utf-8 -*-
from validators.utils import validator
__all__ = ('es_cif', 'es_nif', 'es_nie', 'es_doi',)
def nif_nie_validation(doi, number_by_letter, special_cases):
"""
Validate if the doi is a NIF or a NIE.
:param doi: DOI to validate.
:return: boolean if it's valid.
"""
doi = doi.upper()
if doi in special_cases:
return False
table = 'TRWAGMYFPDXBNJZSQVHLCKE'
if len(doi) != 9:
return False
control = doi[8]
# If it is not a DNI, convert the first letter to the corresponding
# digit
numbers = number_by_letter.get(doi[0], doi[0]) + doi[1:8]
return numbers.isdigit() and control == table[int(numbers) % 23]
@validator
def es_cif(doi):
"""
Validate a Spanish CIF.
Each company in Spain prior to 2008 had a distinct CIF and has been
discontinued. For more information see `wikipedia.org/cif`_.
The new replacement is to use NIF for absolutely everything. The issue is
that there are "types" of NIFs now: company, person[citizen vs recident]
all distinguished by the first character of the DOI. For this reason we
will continue to call CIF NIFs that are used for companies.
This validator is based on `generadordni.es`_.
.. _generadordni.es:
https://generadordni.es/
.. _wikipedia.org/cif:
https://es.wikipedia.org/wiki/C%C3%B3digo_de_identificaci%C3%B3n_fiscal
Examples::
>>> es_cif('B25162520')
True
>>> es_cif('B25162529')
ValidationFailure(func=es_cif, args=...)
.. versionadded:: 0.13.0
:param doi: DOI to validate
"""
doi = doi.upper()
if len(doi) != 9:
return False
table = 'JABCDEFGHI'
first_chr = doi[0]
doi_body = doi[1:8]
control = doi[8]
if not doi_body.isdigit():
return False
odd_result = 0
even_result = 0
for index, char in enumerate(doi_body):
if index % 2 == 0:
# Multiply each each odd position doi digit by 2 and sum it all
# together
odd_result += sum(map(int, str(int(char) * 2)))
else:
even_result += int(char)
res = (10 - (even_result + odd_result) % 10) % 10
if first_chr in 'ABEH': # Number type
return str(res) == control
elif first_chr in 'PSQW': # Letter type
return table[res] == control
elif first_chr not in 'CDFGJNRUV':
return False
return control == str(res) or control == table[res]
@validator
def es_nif(doi):
"""
Validate a Spanish NIF.
Each entity, be it person or company in Spain has a distinct NIF. Since
we've designated CIF to be a company NIF, this NIF is only for person.
For more information see `wikipedia.org/nif`_.
This validator is based on `generadordni.es`_.
.. _generadordni.es:
https://generadordni.es/
.. _wikipedia.org/nif:
https://es.wikipedia.org/wiki/N%C3%BAmero_de_identificaci%C3%B3n_fiscal
Examples::
>>> es_nif('26643189N')
True
>>> es_nif('26643189X')
ValidationFailure(func=es_nif, args=...)
.. versionadded:: 0.13.0
:param doi: DOI to validate
"""
number_by_letter = {'L': '0', 'M': '0', 'K': '0'}
special_cases = ['X0000000T', '00000000T', '00000001R']
return nif_nie_validation(doi, number_by_letter, special_cases)
@validator
def es_nie(doi):
"""
Validate a Spanish NIE.
The NIE is a tax identification number in Spain, known in Spanish as the
NIE, or more formally the Número de identidad de extranjero. For more
information see `wikipedia.org/nie`_.
This validator is based on `generadordni.es`_.
.. _generadordni.es:
https://generadordni.es/
.. _wikipedia.org/nie:
https://es.wikipedia.org/wiki/N%C3%BAmero_de_identidad_de_extranjero
Examples::
>>> es_nie('X0095892M')
True
>>> es_nie('X0095892X')
ValidationFailure(func=es_nie, args=...)
.. versionadded:: 0.13.0
:param doi: DOI to validate
"""
number_by_letter = {'X': '0', 'Y': '1', 'Z': '2'}
special_cases = ['X0000000T']
# NIE must must start with X Y or Z
if not doi or doi[0] not in number_by_letter.keys():
return False
return nif_nie_validation(doi, number_by_letter, special_cases)
@validator
def es_doi(doi):
"""
Validate a Spanish DOI.
A DOI in spain is all NIF / CIF / NIE / DNI -- a digital ID. For more
information see `wikipedia.org/doi`_.
This validator is based on `generadordni.es`_.
.. _generadordni.es:
https://generadordni.es/
.. _wikipedia.org/doi:
https://es.wikipedia.org/wiki/Identificador_de_objeto_digital
Examples::
>>> es_doi('X0095892M')
True
>>> es_doi('X0095892X')
ValidationFailure(func=es_doi, args=...)
.. versionadded:: 0.13.0
:param doi: DOI to validate
"""
return es_nie(doi) or es_nif(doi) or es_cif(doi)
validators-0.14.2/validators/i18n/fi.py 0000664 0000000 0000000 00000004727 13612537675 0017676 0 ustar 00root root 0000000 0000000 import re
from validators.utils import validator
business_id_pattern = re.compile(r'^[0-9]{7}-[0-9]$')
ssn_checkmarks = '0123456789ABCDEFHJKLMNPRSTUVWXY'
ssn_pattern = re.compile(
r"""^
(?P(0[1-9]|[1-2]\d|3[01])
(0[1-9]|1[012])
(\d{{2}}))
[A+-]
(?P(\d{{3}}))
(?P[{checkmarks}])$""".format(checkmarks=ssn_checkmarks),
re.VERBOSE
)
@validator
def fi_business_id(business_id):
"""
Validate a Finnish Business ID.
Each company in Finland has a distinct business id. For more
information see `Finnish Trade Register`_
.. _Finnish Trade Register:
http://en.wikipedia.org/wiki/Finnish_Trade_Register
Examples::
>>> fi_business_id('0112038-9') # Fast Monkeys Ltd
True
>>> fi_business_id('1234567-8') # Bogus ID
ValidationFailure(func=fi_business_id, ...)
.. versionadded:: 0.4
.. versionchanged:: 0.5
Method renamed from ``finnish_business_id`` to ``fi_business_id``
:param business_id: business_id to validate
"""
if not business_id or not re.match(business_id_pattern, business_id):
return False
factors = [7, 9, 10, 5, 8, 4, 2]
numbers = map(int, business_id[:7])
checksum = int(business_id[8])
sum_ = sum(f * n for f, n in zip(factors, numbers))
modulo = sum_ % 11
return (11 - modulo == checksum) or (modulo == 0 and checksum == 0)
@validator
def fi_ssn(ssn, allow_temporal_ssn=True):
"""
Validate a Finnish Social Security Number.
This validator is based on `django-localflavor-fi`_.
.. _django-localflavor-fi:
https://github.com/django/django-localflavor-fi/
Examples::
>>> fi_ssn('010101-0101')
True
>>> fi_ssn('101010-0102')
ValidationFailure(func=fi_ssn, args=...)
.. versionadded:: 0.5
:param ssn: Social Security Number to validate
:param allow_temporal_ssn:
Whether to accept temporal SSN numbers. Temporal SSN numbers are the
ones where the serial is in the range [900-999]. By default temporal
SSN numbers are valid.
"""
if not ssn:
return False
result = re.match(ssn_pattern, ssn)
if not result:
return False
gd = result.groupdict()
checksum = int(gd['date'] + gd['serial'])
return (
int(gd['serial']) >= 2 and
(allow_temporal_ssn or int(gd['serial']) <= 899) and
ssn_checkmarks[checksum % len(ssn_checkmarks)] ==
gd['checksum']
)
validators-0.14.2/validators/iban.py 0000664 0000000 0000000 00000002217 13612537675 0017422 0 ustar 00root root 0000000 0000000 import re
from .utils import validator
regex = (
r'^[A-Z]{2}[0-9]{2}[A-Z0-9]{11,30}$'
)
pattern = re.compile(regex)
def char_value(char):
"""A=10, B=11, ..., Z=35
"""
if char.isdigit():
return int(char)
else:
return 10 + ord(char) - ord('A')
def modcheck(value):
"""Check if the value string passes the mod97-test.
"""
# move country code and check numbers to end
rearranged = value[4:] + value[:4]
# convert letters to numbers
converted = [char_value(char) for char in rearranged]
# interpret as integer
integerized = int(''.join([str(i) for i in converted]))
return (integerized % 97 == 1)
@validator
def iban(value):
"""
Return whether or not given value is a valid IBAN code.
If the value is a valid IBAN this function returns ``True``, otherwise
:class:`~validators.utils.ValidationFailure`.
Examples::
>>> iban('DE29100500001061045672')
True
>>> iban('123456')
ValidationFailure(func=iban, ...)
.. versionadded:: 0.8
:param value: IBAN string to validate
"""
return pattern.match(value) and modcheck(value)
validators-0.14.2/validators/ip_address.py 0000664 0000000 0000000 00000006457 13612537675 0020640 0 ustar 00root root 0000000 0000000 from .utils import validator
@validator
def ipv4(value):
"""
Return whether or not given value is a valid IP version 4 address.
This validator is based on `WTForms IPAddress validator`_
.. _WTForms IPAddress validator:
https://github.com/wtforms/wtforms/blob/master/wtforms/validators.py
Examples::
>>> ipv4('123.0.0.7')
True
>>> ipv4('900.80.70.11')
ValidationFailure(func=ipv4, args={'value': '900.80.70.11'})
.. versionadded:: 0.2
:param value: IP address string to validate
"""
groups = value.split('.')
if len(groups) != 4 or any(not x.isdigit() for x in groups):
return False
return all(0 <= int(part) < 256 for part in groups)
@validator
def ipv4_cidr(value):
"""
Return whether or not given value is a valid CIDR-notated IP version 4
address range.
This validator is based on RFC4632 3.1.
Examples::
>>> ipv4_cidr('1.1.1.1/8')
True
>>> ipv4_cidr('1.1.1.1')
ValidationFailure(func=ipv4_cidr, args={'value': '1.1.1.1'})
"""
try:
prefix, suffix = value.split('/', 2)
except ValueError:
return False
if not ipv4(prefix) or not suffix.isdigit():
return False
return 0 <= int(suffix) <= 32
@validator
def ipv6(value):
"""
Return whether or not given value is a valid IP version 6 address
(including IPv4-mapped IPv6 addresses).
This validator is based on `WTForms IPAddress validator`_.
.. _WTForms IPAddress validator:
https://github.com/wtforms/wtforms/blob/master/wtforms/validators.py
Examples::
>>> ipv6('abcd:ef::42:1')
True
>>> ipv6('::ffff:192.0.2.128')
True
>>> ipv6('::192.0.2.128')
True
>>> ipv6('abc.0.0.1')
ValidationFailure(func=ipv6, args={'value': 'abc.0.0.1'})
.. versionadded:: 0.2
:param value: IP address string to validate
"""
ipv6_groups = value.split(':')
if len(ipv6_groups) == 1:
return False
ipv4_groups = ipv6_groups[-1].split('.')
if len(ipv4_groups) > 1:
if not ipv4(ipv6_groups[-1]):
return False
ipv6_groups = ipv6_groups[:-1]
else:
ipv4_groups = []
max_groups = 6 if ipv4_groups else 8
if len(ipv6_groups) > max_groups:
return False
count_blank = 0
for part in ipv6_groups:
if not part:
count_blank += 1
continue
try:
num = int(part, 16)
except ValueError:
return False
else:
if not 0 <= num <= 65536:
return False
if count_blank < 2:
return True
elif count_blank == 2 and not ipv6_groups[0] and not ipv6_groups[1]:
return True
return False
@validator
def ipv6_cidr(value):
"""
Returns whether or not given value is a valid CIDR-notated IP version 6
address range.
This validator is based on RFC4632 3.1.
Examples::
>>> ipv6_cidr('::1/128')
True
>>> ipv6_cidr('::1')
ValidationFailure(func=ipv6_cidr, args={'value': '::1'})
"""
try:
prefix, suffix = value.split('/', 2)
except ValueError:
return False
if not ipv6(prefix) or not suffix.isdigit():
return False
return 0 <= int(suffix) <= 128
validators-0.14.2/validators/length.py 0000664 0000000 0000000 00000001712 13612537675 0017771 0 ustar 00root root 0000000 0000000 from .between import between
from .utils import validator
@validator
def length(value, min=None, max=None):
"""
Return whether or not the length of given string is within a specified
range.
Examples::
>>> length('something', min=2)
True
>>> length('something', min=9, max=9)
True
>>> length('something', max=5)
ValidationFailure(func=length, ...)
:param value:
The string to validate.
:param min:
The minimum required length of the string. If not provided, minimum
length will not be checked.
:param max:
The maximum length of the string. If not provided, maximum length
will not be checked.
.. versionadded:: 0.2
"""
if (min is not None and min < 0) or (max is not None and max < 0):
raise AssertionError(
'`min` and `max` need to be greater than zero.'
)
return between(len(value), min=min, max=max)
validators-0.14.2/validators/mac_address.py 0000664 0000000 0000000 00000001504 13612537675 0020754 0 ustar 00root root 0000000 0000000 import re
from .utils import validator
pattern = re.compile(r'^(?:[0-9a-fA-F]{2}:){5}[0-9a-fA-F]{2}$')
@validator
def mac_address(value):
"""
Return whether or not given value is a valid MAC address.
If the value is valid MAC address this function returns ``True``,
otherwise :class:`~validators.utils.ValidationFailure`.
This validator is based on `WTForms MacAddress validator`_.
.. _WTForms MacAddress validator:
https://github.com/wtforms/wtforms/blob/master/wtforms/validators.py
Examples::
>>> mac_address('01:23:45:67:ab:CD')
True
>>> mac_address('00:00:00:00:00')
ValidationFailure(func=mac_address, args={'value': '00:00:00:00:00'})
.. versionadded:: 0.2
:param value: Mac address string to validate
"""
return pattern.match(value)
validators-0.14.2/validators/slug.py 0000664 0000000 0000000 00000001021 13612537675 0017453 0 ustar 00root root 0000000 0000000 import re
from .utils import validator
slug_regex = re.compile(r'^[-a-zA-Z0-9_]+$')
@validator
def slug(value):
"""
Validate whether or not given value is valid slug.
Valid slug can contain only alphanumeric characters, hyphens and
underscores.
Examples::
>>> slug('my.slug')
ValidationFailure(func=slug, args={'value': 'my.slug'})
>>> slug('my-slug-2134')
True
.. versionadded:: 0.6
:param value: value to validate
"""
return slug_regex.match(value)
validators-0.14.2/validators/truthy.py 0000664 0000000 0000000 00000001605 13612537675 0020050 0 ustar 00root root 0000000 0000000 import six
from .utils import validator
@validator
def truthy(value):
"""
Validate that given value is not a falsey value.
This validator is based on `WTForms DataRequired validator`_.
.. _WTForms DataRequired validator:
https://github.com/wtforms/wtforms/blob/master/wtforms/validators.py
Examples::
>>> truthy(1)
True
>>> truthy('someone')
True
>>> truthy(0)
ValidationFailure(func=truthy, args={'value': 0})
>>> truthy(' ')
ValidationFailure(func=truthy, args={'value': ' '})
>>> truthy(False)
ValidationFailure(func=truthy, args={'value': False})
>>> truthy(None)
ValidationFailure(func=truthy, args={'value': None})
.. versionadded:: 0.2
"""
return (
value and
(not isinstance(value, six.string_types) or value.strip())
)
validators-0.14.2/validators/url.py 0000664 0000000 0000000 00000011120 13612537675 0017304 0 ustar 00root root 0000000 0000000 import re
from .utils import validator
ip_middle_octet = r"(?:\.(?:1?\d{1,2}|2[0-4]\d|25[0-5]))"
ip_last_octet = r"(?:\.(?:[1-9]\d?|1\d\d|2[0-4]\d|25[0-4]))"
regex = re.compile( # noqa: W605
r"^"
# protocol identifier
r"(?:(?:https?|ftp)://)"
# user:pass authentication
r"(?:[-a-z\u00a1-\uffff0-9._~%!$&'()*+,;=:]+"
r"(?::[-a-z0-9._~%!$&'()*+,;=:]*)?@)?"
r"(?:"
r"(?P"
# IP address exclusion
# private & local networks
r"(?:(?:10|127)" + ip_middle_octet + r"{2}" + ip_last_octet + r")|"
r"(?:(?:169\.254|192\.168)" + ip_middle_octet + ip_last_octet + r")|"
r"(?:172\.(?:1[6-9]|2\d|3[0-1])" + ip_middle_octet + ip_last_octet + r"))"
r"|"
# private & local hosts
r"(?P"
r"(?:localhost))"
r"|"
# IP address dotted notation octets
# excludes loopback network 0.0.0.0
# excludes reserved space >= 224.0.0.0
# excludes network & broadcast addresses
# (first & last IP address of each class)
r"(?P"
r"(?:[1-9]\d?|1\d\d|2[01]\d|22[0-3])"
r"" + ip_middle_octet + r"{2}"
r"" + ip_last_octet + r")"
r"|"
# IPv6 RegEx from https://stackoverflow.com/a/17871737
r"\[("
# 1:2:3:4:5:6:7:8
r"([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|"
# 1:: 1:2:3:4:5:6:7::
r"([0-9a-fA-F]{1,4}:){1,7}:|"
# 1::8 1:2:3:4:5:6::8 1:2:3:4:5:6::8
r"([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|"
# 1::7:8 1:2:3:4:5::7:8 1:2:3:4:5::8
r"([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|"
# 1::6:7:8 1:2:3:4::6:7:8 1:2:3:4::8
r"([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|"
# 1::5:6:7:8 1:2:3::5:6:7:8 1:2:3::8
r"([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|"
# 1::4:5:6:7:8 1:2::4:5:6:7:8 1:2::8
r"([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|"
# 1::3:4:5:6:7:8 1::3:4:5:6:7:8 1::8
r"[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|"
# ::2:3:4:5:6:7:8 ::2:3:4:5:6:7:8 ::8 ::
r":((:[0-9a-fA-F]{1,4}){1,7}|:)|"
# fe80::7:8%eth0 fe80::7:8%1
# (link-local IPv6 addresses with zone index)
r"fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|"
r"::(ffff(:0{1,4}){0,1}:){0,1}"
r"((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}"
# ::255.255.255.255 ::ffff:255.255.255.255 ::ffff:0:255.255.255.255
# (IPv4-mapped IPv6 addresses and IPv4-translated addresses)
r"(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|"
r"([0-9a-fA-F]{1,4}:){1,4}:"
r"((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}"
# 2001:db8:3:4::192.0.2.33 64:ff9b::192.0.2.33
# (IPv4-Embedded IPv6 Address)
r"(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])"
r")\]|"
# host name
u"(?:(?:[a-z\u00a1-\uffff0-9]-?)*[a-z\u00a1-\uffff0-9]+)"
# domain name
u"(?:\.(?:[a-z\u00a1-\uffff0-9]-?)*[a-z\u00a1-\uffff0-9]+)*"
# TLD identifier
u"(?:\.(?:[a-z\u00a1-\uffff]{2,}))"
r")"
# port number
r"(?::\d{2,5})?"
# resource path
u"(?:/[-a-z\u00a1-\uffff0-9._~%!$&'()*+,;=:@/]*)?"
# query string
r"(?:\?\S*)?"
# fragment
r"(?:#\S*)?"
r"$",
re.UNICODE | re.IGNORECASE
)
pattern = re.compile(regex)
@validator
def url(value, public=False):
"""
Return whether or not given value is a valid URL.
If the value is valid URL this function returns ``True``, otherwise
:class:`~validators.utils.ValidationFailure`.
This validator is based on the wonderful `URL validator of dperini`_.
.. _URL validator of dperini:
https://gist.github.com/dperini/729294
Examples::
>>> url('http://foobar.dk')
True
>>> url('ftp://foobar.dk')
True
>>> url('http://10.0.0.1')
True
>>> url('http://foobar.d')
ValidationFailure(func=url, ...)
>>> url('http://10.0.0.1', public=True)
ValidationFailure(func=url, ...)
.. versionadded:: 0.2
.. versionchanged:: 0.10.2
Added support for various exotic URLs and fixed various false
positives.
.. versionchanged:: 0.10.3
Added ``public`` parameter.
.. versionchanged:: 0.11.0
Made the regular expression this function uses case insensitive.
.. versionchanged:: 0.11.3
Added support for URLs containing localhost
:param value: URL address string to validate
:param public: (default=False) Set True to only allow a public IP address
"""
result = pattern.match(value)
if not public:
return result
return result and not any(
(result.groupdict().get(key) for key in ('private_ip', 'private_host'))
)
validators-0.14.2/validators/utils.py 0000664 0000000 0000000 00000004102 13612537675 0017644 0 ustar 00root root 0000000 0000000 import inspect
import itertools
from collections import OrderedDict
import six
from decorator import decorator
class ValidationFailure(Exception):
def __init__(self, func, args):
self.func = func
self.__dict__.update(args)
def __repr__(self):
return u'ValidationFailure(func={func}, args={args})'.format(
func=self.func.__name__,
args=dict(
[(k, v) for (k, v) in self.__dict__.items() if k != 'func']
)
)
def __str__(self):
return repr(self)
def __unicode__(self):
return repr(self)
def __bool__(self):
return False
def __nonzero__(self):
return False
def func_args_as_dict(func, args, kwargs):
"""
Return given function's positional and key value arguments as an ordered
dictionary.
"""
if six.PY2:
_getargspec = inspect.getargspec
else:
_getargspec = inspect.getfullargspec
arg_names = list(
OrderedDict.fromkeys(
itertools.chain(
_getargspec(func)[0],
kwargs.keys()
)
)
)
return OrderedDict(
list(six.moves.zip(arg_names, args)) +
list(kwargs.items())
)
def validator(func, *args, **kwargs):
"""
A decorator that makes given function validator.
Whenever the given function is called and returns ``False`` value
this decorator returns :class:`ValidationFailure` object.
Example::
>>> @validator
... def even(value):
... return not (value % 2)
>>> even(4)
True
>>> even(5)
ValidationFailure(func=even, args={'value': 5})
:param func: function to decorate
:param args: positional function arguments
:param kwargs: key value function arguments
"""
def wrapper(func, *args, **kwargs):
value = func(*args, **kwargs)
if not value:
return ValidationFailure(
func, func_args_as_dict(func, args, kwargs)
)
return True
return decorator(wrapper, func)
validators-0.14.2/validators/uuid.py 0000664 0000000 0000000 00000001441 13612537675 0017455 0 ustar 00root root 0000000 0000000 import re
from .utils import validator
pattern = re.compile(r'^[0-9a-fA-F]{8}-([0-9a-fA-F]{4}-){3}[0-9a-fA-F]{12}$')
@validator
def uuid(value):
"""
Return whether or not given value is a valid UUID.
If the value is valid UUID this function returns ``True``, otherwise
:class:`~validators.utils.ValidationFailure`.
This validator is based on `WTForms UUID validator`_.
.. _WTForms UUID validator:
https://github.com/wtforms/wtforms/blob/master/wtforms/validators.py
Examples::
>>> uuid('2bc1c94f-0deb-43e9-92a1-4775189ec9f8')
True
>>> uuid('2bc1c94f 0deb-43e9-92a1-4775189ec9f8')
ValidationFailure(func=uuid, ...)
.. versionadded:: 0.2
:param value: UUID string to validate
"""
return pattern.match(value)