pax_global_header 0000666 0000000 0000000 00000000064 14247161714 0014521 g ustar 00root root 0000000 0000000 52 comment=9c35f185c0d44c3cb1c7433c66e3dfbb921e5e54
validators-0.20.0/ 0000775 0000000 0000000 00000000000 14247161714 0013750 5 ustar 00root root 0000000 0000000 validators-0.20.0/.github/ 0000775 0000000 0000000 00000000000 14247161714 0015310 5 ustar 00root root 0000000 0000000 validators-0.20.0/.github/workflows/ 0000775 0000000 0000000 00000000000 14247161714 0017345 5 ustar 00root root 0000000 0000000 validators-0.20.0/.github/workflows/main.yml 0000664 0000000 0000000 00000001737 14247161714 0021024 0 ustar 00root root 0000000 0000000 name: GH
on:
pull_request:
branches: '*'
push:
branches: 'master'
tags: '*'
jobs:
CI:
runs-on: ubuntu-latest
strategy:
max-parallel: 8
matrix:
python-version: [3.5, 3.6, 3.7, 3.8, 3.9, 3.10]
steps:
- uses: actions/checkout@v2
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v2
with:
python-version: ${{ matrix.python-version }}
- name: Pip cache
uses: actions/cache@v2
with:
path: ~/.cache/pip
key: ${{ runner.os }}-pip-${{ hashFiles('**/requirements/*.txt') }}
restore-keys: |
${{ runner.os }}-pip-
- name: Install dependencies
run: pip install -e ".[test]"
- name: Lint
run: |
isort --recursive --diff validators tests && isort --recursive --check-only validators tests
flake8 validators tests
- name: Test
run: py.test --doctest-glob="*.rst" --doctest-modules --ignore=setup.py
validators-0.20.0/.gitignore 0000664 0000000 0000000 00000000507 14247161714 0015742 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.20.0/.isort.cfg 0000664 0000000 0000000 00000000200 14247161714 0015637 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.20.0/.travis.yml 0000664 0000000 0000000 00000000604 14247161714 0016061 0 ustar 00root root 0000000 0000000 language: python
matrix:
include:
- python: 3.5
- python: 3.6
- python: 3.7
dist: xenial
sudo: true
- 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.20.0/CHANGES.rst 0000664 0000000 0000000 00000013416 14247161714 0015557 0 ustar 00root root 0000000 0000000 Changelog
---------
0.20.0 (2022-06-05)
^^^^^^^^^^^^^^^^^^^
- Added ipv4 digit lenghts validation (#191, pull request courtesy of Norbiox)
- Fixes error with international URLs that have more than 2 hyphens (#184, pull request courtesy of automationator)
0.19.0 (2022-05-04)
^^^^^^^^^^^^^^^^^^^
- Dropped py34 support
- Improve IPv6 validation (#201, pull request courtesy of SimonIT)
0.18.2 (2020-12-18)
^^^^^^^^^^^^^^^^^^^
- Implement actual validation for old style BTC addresses including checksumming (#182, pull request courtesy of tpatja)
- Use a regex to guesstimate validity of new segwit BTC addresses (#182, pull request courtesy of tpatja)
0.18.1 (2020-09-03)
^^^^^^^^^^^^^^^^^^^
- Made uuid validator accept UUID objects (#174, pull request courtesy of Letsch22)
0.18.0 (2020-08-19)
^^^^^^^^^^^^^^^^^^^
- Added bitcoin address validator (#166, pull request courtesy of daveusa31)
0.17.1 (2020-08-03)
^^^^^^^^^^^^^^^^^^^
- Fixed python_requires using twine
0.17.0 (2020-08-02)
^^^^^^^^^^^^^^^^^^^
- Added python_requires='>=3.4' to setup.py (#163, pull request courtesy of vphilippon)
- Fixed URL validator ip_last_octet regex (#145, pull request courtesy of ghost)
0.16.0 (2020-07-16)
^^^^^^^^^^^^^^^^^^^
- Added support for emojis and more IDNA URLs (#161, pull request courtesy of automationator)
0.15.0 (2020-05-07)
^^^^^^^^^^^^^^^^^^^
- Added bank card validators (#157, pull request courtesy of TimonPeng)
0.14.3 (2020-02-04)
^^^^^^^^^^^^^^^^^^^
- Handle None values gracefully in domain validator (#144, pull request courtesy reahaas)
- Local part of the email address should be less or equal than 64 bytes (#147, pull request courtesy mondeja)
- Removed py27 support
- Removed pypy2 support
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.20.0/LICENSE 0000664 0000000 0000000 00000002101 14247161714 0014747 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.20.0/MANIFEST.in 0000664 0000000 0000000 00000000301 14247161714 0015500 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.20.0/README.rst 0000664 0000000 0000000 00000002015 14247161714 0015435 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.20.0/docs/ 0000775 0000000 0000000 00000000000 14247161714 0014700 5 ustar 00root root 0000000 0000000 validators-0.20.0/docs/Makefile 0000664 0000000 0000000 00000015172 14247161714 0016346 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.20.0/docs/conf.py 0000664 0000000 0000000 00000020645 14247161714 0016206 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.20.0/docs/index.rst 0000664 0000000 0000000 00000006624 14247161714 0016551 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
btc_address
------
.. module:: validators.btc_address
.. autofunction:: btc_address
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.20.0/docs/make.bat 0000664 0000000 0000000 00000015065 14247161714 0016314 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.20.0/setup.py 0000664 0000000 0000000 00000003624 14247161714 0015467 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 = [
'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 :: 3',
'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'
],
python_requires='>=3.4'
)
validators-0.20.0/tests/ 0000775 0000000 0000000 00000000000 14247161714 0015112 5 ustar 00root root 0000000 0000000 validators-0.20.0/tests/__init__.py 0000664 0000000 0000000 00000000000 14247161714 0017211 0 ustar 00root root 0000000 0000000 validators-0.20.0/tests/i18n/ 0000775 0000000 0000000 00000000000 14247161714 0015671 5 ustar 00root root 0000000 0000000 validators-0.20.0/tests/i18n/__init__.py 0000664 0000000 0000000 00000000000 14247161714 0017770 0 ustar 00root root 0000000 0000000 validators-0.20.0/tests/i18n/test_es.py 0000664 0000000 0000000 00000004117 14247161714 0017714 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.20.0/tests/i18n/test_fi.py 0000664 0000000 0000000 00000002730 14247161714 0017702 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_business_id(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.20.0/tests/test_between.py 0000664 0000000 0000000 00000001537 14247161714 0020162 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.20.0/tests/test_btc_address.py 0000664 0000000 0000000 00000001740 14247161714 0021002 0 ustar 00root root 0000000 0000000 # -*- coding: utf-8 -*-
import pytest
from validators import btc_address, ValidationFailure
@pytest.mark.parametrize(
'value',
[
# P2PKH (Pay-to-PubkeyHash) type
'1BvBMSEYstWetqTFn5Au4m4GFg7xJaNVN2',
# P2SH (Pay to script hash) type
'3J98t1WpEZ73CNmQviecrnyiWrnqRhWNLy',
# Bech32/segwit type
'bc1qar0srrr7xfkvy5l643lydnw9re59gtzzwf5mdq',
'bc1qc7slrfxkknqcq2jevvvkdgvrt8080852dfjewde450xdlk4ugp7szw5tk9',
],
)
def test_returns_true_on_valid_btc_address(value):
assert btc_address(value)
@pytest.mark.parametrize(
'value',
[
'ff3Cwgr2g7vsi1bXDUkpEnVoRLA9w4FZfC69',
'b3Cgwgr2g7vsi1bXyjyDUkphEnVoRLA9w4FZfC69',
# incorrect header
'1BvBMsEYstWetqTFn5Au4m4GFg7xJaNVN2',
# incorrect checksum
'3J98t1WpEZ73CNmQviecrnyiWrnqRhWNLz',
],
)
def test_returns_failed_validation_on_invalid_btc_address(value):
assert isinstance(btc_address(value), ValidationFailure)
validators-0.20.0/tests/test_card.py 0000664 0000000 0000000 00000007263 14247161714 0017444 0 ustar 00root root 0000000 0000000 # -*- coding: utf-8 -*-
import pytest
from validators import (
amex,
card_number,
diners,
discover,
jcb,
mastercard,
unionpay,
ValidationFailure,
visa
)
visa_cards = [
'4242424242424242',
'4000002760003184'
]
mastercard_cards = [
'5555555555554444',
'2223003122003222'
]
amex_cards = [
'378282246310005',
'371449635398431'
]
unionpay_cards = [
'6200000000000005'
]
diners_cards = [
'3056930009020004',
'36227206271667'
]
jcb_cards = [
'3566002020360505'
]
discover_cards = [
'6011111111111117',
'6011000990139424'
]
@pytest.mark.parametrize(
"value",
visa_cards
+ mastercard_cards
+ amex_cards
+ unionpay_cards
+ diners_cards
+ jcb_cards
+ discover_cards,
)
def test_returns_true_on_valid_card_number(value):
assert card_number(value)
@pytest.mark.parametrize('value', [
'4242424242424240',
'4000002760003180',
'400000276000318X'
])
def test_returns_failed_on_valid_card_number(value):
assert isinstance(card_number(value), ValidationFailure)
@pytest.mark.parametrize('value', visa_cards)
def test_returns_true_on_valid_visa(value):
assert visa(value)
@pytest.mark.parametrize(
"value",
mastercard_cards
+ amex_cards
+ unionpay_cards
+ diners_cards
+ jcb_cards
+ discover_cards,
)
def test_returns_failed_on_valid_visa(value):
assert isinstance(visa(value), ValidationFailure)
@pytest.mark.parametrize('value', mastercard_cards)
def test_returns_true_on_valid_mastercard(value):
assert mastercard(value)
@pytest.mark.parametrize(
"value",
visa_cards
+ amex_cards
+ unionpay_cards
+ diners_cards
+ jcb_cards
+ discover_cards,
)
def test_returns_failed_on_valid_mastercard(value):
assert isinstance(mastercard(value), ValidationFailure)
@pytest.mark.parametrize('value', amex_cards)
def test_returns_true_on_valid_amex(value):
assert amex(value)
@pytest.mark.parametrize(
"value",
visa_cards
+ mastercard_cards
+ unionpay_cards
+ diners_cards
+ jcb_cards
+ discover_cards,
)
def test_returns_failed_on_valid_amex(value):
assert isinstance(amex(value), ValidationFailure)
@pytest.mark.parametrize('value', unionpay_cards)
def test_returns_true_on_valid_unionpay(value):
assert unionpay(value)
@pytest.mark.parametrize(
"value",
visa_cards
+ mastercard_cards
+ amex_cards
+ diners_cards
+ jcb_cards
+ discover_cards,
)
def test_returns_failed_on_valid_unionpay(value):
assert isinstance(unionpay(value), ValidationFailure)
@pytest.mark.parametrize('value', diners_cards)
def test_returns_true_on_valid_diners(value):
assert diners(value)
@pytest.mark.parametrize(
"value",
visa_cards
+ mastercard_cards
+ amex_cards
+ unionpay_cards
+ jcb_cards
+ discover_cards,
)
def test_returns_failed_on_valid_diners(value):
assert isinstance(diners(value), ValidationFailure)
@pytest.mark.parametrize('value', jcb_cards)
def test_returns_true_on_valid_jcb(value):
assert jcb(value)
@pytest.mark.parametrize(
"value",
visa_cards
+ mastercard_cards
+ amex_cards
+ unionpay_cards
+ diners_cards
+ discover_cards,
)
def test_returns_failed_on_valid_jcb(value):
assert isinstance(jcb(value), ValidationFailure)
@pytest.mark.parametrize('value', discover_cards)
def test_returns_true_on_valid_discover(value):
assert discover(value)
@pytest.mark.parametrize(
"value",
visa_cards
+ mastercard_cards
+ amex_cards
+ unionpay_cards
+ diners_cards
+ jcb_cards,
)
def test_returns_failed_on_valid_discover(value):
assert isinstance(discover(value), ValidationFailure)
validators-0.20.0/tests/test_domain.py 0000664 0000000 0000000 00000001623 14247161714 0017774 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.20.0/tests/test_email.py 0000664 0000000 0000000 00000002443 14247161714 0017615 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',),
(
'john56789.john56789.john56789.john56789.john56789.john56789.john5'
'@example.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.20.0/tests/test_extremes.py 0000664 0000000 0000000 00000001456 14247161714 0020365 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.20.0/tests/test_iban.py 0000664 0000000 0000000 00000000734 14247161714 0017440 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.20.0/tests/test_ipv4.py 0000664 0000000 0000000 00000001116 14247161714 0017404 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',),
('0127.0.0.1',),
])
def test_returns_failed_validation_on_invalid_ipv4_address(address):
assert isinstance(ipv4(address), ValidationFailure)
validators-0.20.0/tests/test_ipv4_cidr.py 0000664 0000000 0000000 00000001114 14247161714 0020403 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.20.0/tests/test_ipv6.py 0000664 0000000 0000000 00000001743 14247161714 0017414 0 ustar 00root root 0000000 0000000 # -*- coding: utf-8 -*-
import pytest
from validators import ipv4, ipv6, ValidationFailure
@pytest.mark.parametrize(('address',), [
('::',),
('::1',),
('1::',),
('dead:beef:0:0:0:0000:42:1',),
('abcd:ef::42:1',),
('0:0:0:0:0:ffff:1.2.3.4',),
('::192.168.30.2',),
('0000:0000:0000:0000:0000::',),
('0:a:b:c:d:e:f::',),
])
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',),
('1:2:3:4:5:6:7:8::',),
('1:2:3:4:5:6:7::8:9',),
('abcd::1ffff',),
('1111:',),
(':8888',),
(':1.2.3.4',),
('18:05',),
(':',),
(':1:2:',),
(':1:2::',),
('::1:2::',),
('8::1:2::9',),
('02001:0000:1234:0000:0000:C1C0:ABCD:0876',),
])
def test_returns_failed_validation_on_invalid_ipv6_address(address):
assert isinstance(ipv6(address), ValidationFailure)
validators-0.20.0/tests/test_ipv6_cidr.py 0000664 0000000 0000000 00000001345 14247161714 0020413 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.20.0/tests/test_length.py 0000664 0000000 0000000 00000001734 14247161714 0020011 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.20.0/tests/test_mac_address.py 0000664 0000000 0000000 00000001031 14247161714 0020763 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.20.0/tests/test_md5.py 0000664 0000000 0000000 00000001067 14247161714 0017214 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.20.0/tests/test_sha1.py 0000664 0000000 0000000 00000001142 14247161714 0017355 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.20.0/tests/test_sha224.py 0000664 0000000 0000000 00000001272 14247161714 0017530 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.20.0/tests/test_sha256.py 0000664 0000000 0000000 00000001344 14247161714 0017535 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.20.0/tests/test_sha512.py 0000664 0000000 0000000 00000002252 14247161714 0017527 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.20.0/tests/test_slug.py 0000664 0000000 0000000 00000000736 14247161714 0017503 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.20.0/tests/test_url.py 0000664 0000000 0000000 00000011234 14247161714 0017326 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://www.😉.com',
u'http://😉.com/😁',
u'http://উদাহরণ.বাংলা',
u'http://xn--d5b6ci4b4b3a.xn--54b7fta0cc',
u'http://дом-м.рф/1/asdf',
u'http://xn----gtbybh.xn--p1ai/1/asdf',
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.0',
u'http://10.1.1.1',
u'http://10.1.1.254',
u'http://10.1.1.255',
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://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.20.0/tests/test_uuid.py 0000664 0000000 0000000 00000001751 14247161714 0017475 0 ustar 00root root 0000000 0000000 # -*- coding: utf-8 -*-
from uuid import UUID
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',), [
(UUID('2bc1c94f-0deb-43e9-92a1-4775189ec9f8'),),
])
def test_returns_true_on_valid_uuid_object(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)
@pytest.mark.parametrize(('value',), [
(1,),
(1.0,),
(True,),
(None,),
])
def test_returns_failed_validation_on_invalid_types(value):
assert isinstance(uuid(value), ValidationFailure)
validators-0.20.0/tests/test_validation_failure.py 0000664 0000000 0000000 00000001107 14247161714 0022363 0 ustar 00root root 0000000 0000000 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 str(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.20.0/validators/ 0000775 0000000 0000000 00000000000 14247161714 0016120 5 ustar 00root root 0000000 0000000 validators-0.20.0/validators/__init__.py 0000664 0000000 0000000 00000002120 14247161714 0020224 0 ustar 00root root 0000000 0000000 from .between import between
from .btc_address import btc_address
from .card import (
amex,
card_number,
diners,
discover,
jcb,
mastercard,
unionpay,
visa
)
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',
'card_number', 'visa', 'mastercard', 'amex', 'unionpay', 'diners',
'jcb', 'discover', 'btc_address')
__version__ = '0.20.0'
validators-0.20.0/validators/between.py 0000664 0000000 0000000 00000003050 14247161714 0020121 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.20.0/validators/btc_address.py 0000664 0000000 0000000 00000002772 14247161714 0020757 0 ustar 00root root 0000000 0000000 import re
from hashlib import sha256
from .utils import validator
segwit_pattern = re.compile(
r'^(bc|tc)[0-3][02-9ac-hj-np-z]{14,74}$')
def validate_segwit_address(addr):
return segwit_pattern.match(addr)
def decode_base58(addr):
alphabet = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz"
return sum([
(58 ** e) * alphabet.index(i)
for e, i in enumerate(addr[::-1])
])
def validate_old_btc_address(addr):
"Validate P2PKH and P2SH type address"
if not len(addr) in range(25, 35):
return False
decoded_bytes = decode_base58(addr).to_bytes(25, "big")
header = decoded_bytes[:-4]
checksum = decoded_bytes[-4:]
return checksum == sha256(sha256(header).digest()).digest()[:4]
@validator
def btc_address(value):
"""
Return whether or not given value is a valid bitcoin address.
If the value is valid bitcoin address this function returns ``True``,
otherwise :class:`~validators.utils.ValidationFailure`.
Full validation is implemented for P2PKH and P2SH addresses.
For segwit addresses a regexp is used to provide a reasonable estimate
on whether the address is valid.
Examples::
>>> btc_address('3Cwgr2g7vsi1bXDUkpEnVoRLA9w4FZfC69')
True
:param value: Bitcoin address string to validate
"""
if not value or not isinstance(value, str):
return False
if value[:2] in ("bc", "tb"):
return validate_segwit_address(value)
return validate_old_btc_address(value)
validators-0.20.0/validators/card.py 0000664 0000000 0000000 00000010437 14247161714 0017410 0 ustar 00root root 0000000 0000000 import re
from .utils import validator
@validator
def card_number(value):
"""
Return whether or not given value is a valid card number.
This validator is based on Luhn algorithm.
.. luhn:
https://github.com/mmcloughlin/luhn
Examples::
>>> card_number('4242424242424242')
True
>>> card_number('4242424242424241')
ValidationFailure(func=card_number, args={'value': '4242424242424241'})
.. versionadded:: 0.15.0
:param value: card number string to validate
"""
try:
digits = list(map(int, value))
odd_sum = sum(digits[-1::-2])
even_sum = sum([sum(divmod(2 * d, 10)) for d in digits[-2::-2]])
return (odd_sum + even_sum) % 10 == 0
except ValueError:
return False
@validator
def visa(value):
"""
Return whether or not given value is a valid Visa card number.
Examples::
>>> visa('4242424242424242')
True
>>> visa('2223003122003222')
ValidationFailure(func=visa, args={'value': '2223003122003222'})
.. versionadded:: 0.15.0
:param value: Visa card number string to validate
"""
pattern = re.compile(r'^4')
return card_number(value) and len(value) == 16 and pattern.match(value)
@validator
def mastercard(value):
"""
Return whether or not given value is a valid Mastercard card number.
Examples::
>>> mastercard('5555555555554444')
True
>>> mastercard('4242424242424242')
ValidationFailure(func=mastercard, args={'value': '4242424242424242'})
.. versionadded:: 0.15.0
:param value: Mastercard card number string to validate
"""
pattern = re.compile(r'^(51|52|53|54|55|22|23|24|25|26|27)')
return card_number(value) and len(value) == 16 and pattern.match(value)
@validator
def amex(value):
"""
Return whether or not given value is a valid American Express card number.
Examples::
>>> amex('378282246310005')
True
>>> amex('4242424242424242')
ValidationFailure(func=amex, args={'value': '4242424242424242'})
.. versionadded:: 0.15.0
:param value: American Express card number string to validate
"""
pattern = re.compile(r'^(34|37)')
return card_number(value) and len(value) == 15 and pattern.match(value)
@validator
def unionpay(value):
"""
Return whether or not given value is a valid UnionPay card number.
Examples::
>>> unionpay('6200000000000005')
True
>>> unionpay('4242424242424242')
ValidationFailure(func=unionpay, args={'value': '4242424242424242'})
.. versionadded:: 0.15.0
:param value: UnionPay card number string to validate
"""
pattern = re.compile(r'^62')
return card_number(value) and len(value) == 16 and pattern.match(value)
@validator
def diners(value):
"""
Return whether or not given value is a valid Diners Club card number.
Examples::
>>> diners('3056930009020004')
True
>>> diners('4242424242424242')
ValidationFailure(func=diners, args={'value': '4242424242424242'})
.. versionadded:: 0.15.0
:param value: Diners Club card number string to validate
"""
pattern = re.compile(r'^(30|36|38|39)')
return (
card_number(value) and len(value) in [14, 16] and pattern.match(value)
)
@validator
def jcb(value):
"""
Return whether or not given value is a valid JCB card number.
Examples::
>>> jcb('3566002020360505')
True
>>> jcb('4242424242424242')
ValidationFailure(func=jcb, args={'value': '4242424242424242'})
.. versionadded:: 0.15.0
:param value: JCB card number string to validate
"""
pattern = re.compile(r'^35')
return card_number(value) and len(value) == 16 and pattern.match(value)
@validator
def discover(value):
"""
Return whether or not given value is a valid Discover card number.
Examples::
>>> discover('6011111111111117')
True
>>> discover('4242424242424242')
ValidationFailure(func=discover, args={'value': '4242424242424242'})
.. versionadded:: 0.15.0
:param value: Discover card number string to validate
"""
pattern = re.compile(r'^(60|64|65)')
return card_number(value) and len(value) == 16 and pattern.match(value)
validators-0.20.0/validators/domain.py 0000664 0000000 0000000 00000002445 14247161714 0017746 0 ustar 00root root 0000000 0000000 import re
from .utils import validator
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 str(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, AttributeError):
return False
validators-0.20.0/validators/email.py 0000664 0000000 0000000 00000003673 14247161714 0017572 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 len(user_part.encode("utf-8")) > 64:
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.20.0/validators/extremes.py 0000664 0000000 0000000 00000001737 14247161714 0020336 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.20.0/validators/hashes.py 0000664 0000000 0000000 00000004703 14247161714 0017751 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.20.0/validators/i18n/ 0000775 0000000 0000000 00000000000 14247161714 0016677 5 ustar 00root root 0000000 0000000 validators-0.20.0/validators/i18n/__init__.py 0000664 0000000 0000000 00000000225 14247161714 0021007 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.20.0/validators/i18n/es.py 0000664 0000000 0000000 00000011630 14247161714 0017661 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.20.0/validators/i18n/fi.py 0000664 0000000 0000000 00000004727 14247161714 0017661 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.20.0/validators/iban.py 0000664 0000000 0000000 00000002217 14247161714 0017405 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.20.0/validators/ip_address.py 0000664 0000000 0000000 00000007766 14247161714 0020627 0 ustar 00root root 0000000 0000000 from .utils import validator
@validator
def ipv4(value):
"""
Return whether a 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)
or any(len(x) > 3 for x in groups)
):
return False
return all(0 <= int(part) < 256 for part in groups)
@validator
def ipv4_cidr(value):
"""
Return whether a 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 a 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 = []
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 or len(part) > 4:
return False
max_groups = 6 if ipv4_groups else 8
part_count = len(ipv6_groups) - count_blank
if count_blank == 0 and part_count == max_groups:
# no :: -> must have size of max_groups
return True
elif count_blank == 1 and ipv6_groups[-1] and ipv6_groups[0] and part_count < max_groups:
# one :: inside the address or prefix or suffix : -> filter least two cases
return True
elif count_blank == 2 and part_count < max_groups and (
((ipv6_groups[0] and not ipv6_groups[-1]) or (not ipv6_groups[0] and ipv6_groups[-1])) or ipv4_groups):
# leading or trailing :: or : at end and begin -> filter last case
# Check if it has ipv4 groups because they get removed from the ipv6_groups
return True
elif count_blank == 3 and part_count == 0:
# :: is the address -> filter everything else
return True
return False
@validator
def ipv6_cidr(value):
"""
Returns whether a 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.20.0/validators/length.py 0000664 0000000 0000000 00000001712 14247161714 0017754 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.20.0/validators/mac_address.py 0000664 0000000 0000000 00000001504 14247161714 0020737 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.20.0/validators/slug.py 0000664 0000000 0000000 00000001021 14247161714 0017436 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.20.0/validators/truthy.py 0000664 0000000 0000000 00000001554 14247161714 0020036 0 ustar 00root root 0000000 0000000 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, str) or value.strip())
)
validators-0.20.0/validators/url.py 0000664 0000000 0000000 00000011511 14247161714 0017273 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"(?:\.(?:0|[1-9]\d?|1\d\d|2[0-4]\d|25[0-5]))"
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
r"(?:(?:(?:xn--[-]{0,2})|[a-z\u00a1-\uffff\U00010000-\U0010ffff0-9]-?)*"
r"[a-z\u00a1-\uffff\U00010000-\U0010ffff0-9]+)"
# domain name
r"(?:\.(?:(?:xn--[-]{0,2})|[a-z\u00a1-\uffff\U00010000-\U0010ffff0-9]-?)*"
r"[a-z\u00a1-\uffff\U00010000-\U0010ffff0-9]+)*"
# TLD identifier
r"(?:\.(?:(?:xn--[-]{0,2}[a-z\u00a1-\uffff\U00010000-\U0010ffff0-9]{2,})|"
r"[a-z\u00a1-\uffff\U00010000-\U0010ffff]{2,}))"
r")"
# port number
r"(?::\d{2,5})?"
# resource path
r"(?:/[-a-z\u00a1-\uffff\U00010000-\U0010ffff0-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.20.0/validators/utils.py 0000664 0000000 0000000 00000003746 14247161714 0017644 0 ustar 00root root 0000000 0000000 import inspect
import itertools
from collections import OrderedDict
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.
"""
_getargspec = inspect.getfullargspec
arg_names = list(
OrderedDict.fromkeys(
itertools.chain(
_getargspec(func)[0],
kwargs.keys()
)
)
)
return OrderedDict(
list(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.20.0/validators/uuid.py 0000664 0000000 0000000 00000001712 14247161714 0017441 0 ustar 00root root 0000000 0000000 from __future__ import absolute_import
import re
from uuid import UUID
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 value to validate
"""
if isinstance(value, UUID):
return True
try:
return pattern.match(value)
except TypeError:
return False