Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/fcracker79/pycomb
Tcomb port for Python 3
https://github.com/fcracker79/pycomb
combinators tcomb type type-safe validation
Last synced: about 2 months ago
JSON representation
Tcomb port for Python 3
- Host: GitHub
- URL: https://github.com/fcracker79/pycomb
- Owner: fcracker79
- License: mit
- Created: 2015-09-07T23:44:45.000Z (about 9 years ago)
- Default Branch: master
- Last Pushed: 2020-12-14T14:06:06.000Z (almost 4 years ago)
- Last Synced: 2024-07-04T02:59:54.641Z (3 months ago)
- Topics: combinators, tcomb, type, type-safe, validation
- Language: Python
- Size: 71.3 KB
- Stars: 11
- Watchers: 5
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
[![build status](https://img.shields.io/travis/fcracker79/pycomb/master.svg?style=flat-square)](https://travis-ci.org/fcracker79/pycomb)
PyComb
======[Tcomb](http://www.github.com/gcanti/tcomb) port for Python 3.
It provides a means to apply runtime type checking.Installation
------------```sh
pip install pycomb
```Basic examples
--------------```python
from pycomb import combinators
# A simple string
MyStringType = combinators.String
s1 = combinators.String('hello') # This IS a 'str' object
s2 = combinators.String(10) # This will fail# A list that contains only strings
ListOfStrings = combinators.list(combinators.String)
l1 = ListOfStrings(['1', '2', '3']) # This IS a native tuple
l1 = ListOfStrings(['1', '2', 3]) # This will fail# Structured data
User = combinators.struct(
{
'name': combinators.String,
'age': combinators.Int,
'city': combinators.maybe(combinators.String)
}
)
my_user = User({'name': 'John Burns', 'age': 30}) # This IS a dict
my_user2 = User({'name': 'John Burns', 'age': '30'}) # This will fail
my_user3 = User({'name': 'John Burns', 'age': 30, 'city': 'New York'}) # This IS a dict# Subtypes
SmallString = combinators.subtype(
combinators.String,
lambda d: len(d) <= 10) # Strings shorter than 11 characters
SmallString('12345678901') # This will fail
SmallString('12345') # This IS a 'str' object# Constants
john_data = {'name': 'John'}
John = combinators.constant(john_data, name='JohnConstant')
John({'name': 'John'})
John({'name': 'Jack'}) # Error on JohnConstant: expected JohnConstant but was dict# Regexp with groups
import re
def name_condition(d):
return d in ('John', 'Jack')
def age_condition(d):
return int(d) > 0Name = combinators.subtype(combinators.String, name_condition, name='Name')
Age = combinators.subtype(combinators.String, age_condition, name='Age')
NameAndAge = combinators.regexp_group('(\w+) +(-?[0-9]+)', Name, Age, name='NameAndAge')
NameAndAge('John 32') # Ok
NameAndAge('John 3x') # Error on NameAndAge: expected NameAndAge but was str
NameAndAge('John -32') # Error on NameAndAge[1]: expected Age but was str
NameAndAge('WRONG 32') # Error on NameAndAge[0]: expected Name but was str```
Validation context
------------------
The validation procedure runs within a context that controls:1. The behavior in case of error
2. The production mode: if active, no such error is raised during validation**Context Examples**
```python
from pycomb import combinators, context
# Example of production mode
ListOfNumbers = combinators.list(combinators.Number, 'ListOfNumbers')
production_ctx = context.create(production_mode=True)
numbers = ListOfNumbers([1, 2, 'hello'], ctx=production_ctx) # This will NOT fail# Example of custom behavior in case of error
class MyObserver(context.ValidationErrorObserver):
def on_error(self, ctx, expected_type, found_type):
print('Expected {}, got {}'.format(expected_type, found_type))ListOfNumbers = combinators.list(combinators.Number, 'ListOfNumbers')
notification_ctx = context.create(validation_error_observer=MyObserver())
numbers = ListOfNumbers([1, 2, 'hello'], ctx=production_ctx) # This will NOT fail
# Expected output:
# > Expected Int or Float, got```
Decorators
----------
It is possible to wrap functions in order to protect the input parameters,
or ensure the type of its return value**Decorators example**
```python
from pycomb import combinators
# Example of input parameters check
@combinators.function(
combinators.String, combinators.Int,
c=combinators.Float, d=combinators.list(combinators.Int))
def f(a, b, c=None, d=None):
pass
f('John', 1, c=1.0, d=[3, 4]) # OK
f(1, 1, c=1.0, d=[3, 4]) # This will fail# Example of output check
@returning(cmb.subtype(cmb.String, lambda d: len(d) < 10))
def f(n):
return ' ' * nf(3) # OK
f(10) # This will fail```
More types are supported, such as:
* Unions
* Intersections
* Functions
* Enums
* ...All the base types have a default example field.
Please read the test code to find more examples.