Skip to main content

CI Build Status Latest Version License Downloads

parse_type extends the parse module (opposite of string.format()) with the following features:

  • build type converters for common use cases (enum/mapping, choice)

  • build a type converter with a cardinality constraint (0..1, 0..*, 1..*)

    from the type converter with cardinality=1.

  • compose a type converter from other type converters

  • an extended parser that supports the CardinalityField naming schema

    and creates missing type variants (0..1, 0..*, 1..*) from the primary type converter

Definitions

type converter

A type converter function that converts a textual representation of a value type into instance of this value type. In addition, a type converter function is often annotated with attributes that allows the parse module to use it in a generic way. A type converter is also called a parse_type (a definition used here).

cardinality field

A naming convention for related types that differ in cardinality. A cardinality field is a type name suffix in the format of a field. It allows parse format expression, ala:

"{person:Person}"     #< Cardinality: 1    (one; the normal case)
"{person:Person?}"    #< Cardinality: 0..1 (zero or one  = optional)
"{persons:Person*}"   #< Cardinality: 0..* (zero or more = many0)
"{persons:Person+}"   #< Cardinality: 1..* (one  or more = many)

This naming convention mimics the relationship descriptions in UML diagrams.

Basic Example

Define an own type converter for numbers (integers):

# -- USE CASE:
def parse_number(text):
    return int(text)
parse_number.pattern = r"\d+"  # -- REGULAR EXPRESSION pattern for type.

This is equivalent to:

import parse

@parse.with_pattern(r"\d+")
def parse_number(text):
     return int(text)
assert hasattr(parse_number, "pattern")
assert parse_number.pattern == r"\d+"
# -- USE CASE: Use the type converter with the parse module.
schema = "Hello {number:Number}"
parser = parse.Parser(schema, dict(Number=parse_number))
result = parser.parse("Hello 42")
assert result is not None, "REQUIRE: text matches the schema."
assert result["number"] == 42

result = parser.parse("Hello XXX")
assert result is None, "MISMATCH: text does not match the schema."

Cardinality

Create an type converter for “ManyNumbers” (List, separated with commas) with cardinality “1..* = 1+” (many) from the type converter for a “Number”.

# -- USE CASE: Create new type converter with a cardinality constraint.
# CARDINALITY: many := one or more (1..*)
from parse import Parser
from parse_type import TypeBuilder
parse_numbers = TypeBuilder.with_many(parse_number, listsep=",")

schema = "List: {numbers:ManyNumbers}"
parser = Parser(schema, dict(ManyNumbers=parse_numbers))
result = parser.parse("List: 1, 2, 3")
assert result["numbers"] == [1, 2, 3]

Create an type converter for an “OptionalNumbers” with cardinality “0..1 = ?” (optional) from the type converter for a “Number”.

# -- USE CASE: Create new type converter with cardinality constraint.
# CARDINALITY: optional := zero or one (0..1)
from parse import Parser
from parse_type import TypeBuilder

parse_optional_number = TypeBuilder.with_optional(parse_number)
schema = "Optional: {number:OptionalNumber}"
parser = Parser(schema, dict(OptionalNumber=parse_optional_number))
result = parser.parse("Optional: 42")
assert result["number"] == 42
result = parser.parse("Optional: ")
assert result["number"] == None

Enumeration (Name-to-Value Mapping)

Create an type converter for an “Enumeration” from the description of the mapping as dictionary.

# -- USE CASE: Create a type converter for an enumeration.
from parse import Parser
from parse_type import TypeBuilder

parse_enum_yesno = TypeBuilder.make_enum({"yes": True, "no": False})
parser = Parser("Answer: {answer:YesNo}", dict(YesNo=parse_enum_yesno))
result = parser.parse("Answer: yes")
assert result["answer"] == True

Create an type converter for an “Enumeration” from the description of the mapping as an enumeration class (Python 3.4 enum or the enum34 backport; see also: PEP-0435).

# -- USE CASE: Create a type converter for enum34 enumeration class.
# NOTE: Use Python 3.4 or enum34 backport.
from parse import Parser
from parse_type import TypeBuilder
from enum import Enum

class Color(Enum):
    red   = 1
    green = 2
    blue  = 3

parse_enum_color = TypeBuilder.make_enum(Color)
parser = Parser("Select: {color:Color}", dict(Color=parse_enum_color))
result = parser.parse("Select: red")
assert result["color"] is Color.red

Choice (Name Enumeration)

A Choice data type allows to select one of several strings.

Create an type converter for an “Choice” list, a list of unique names (as string).

from parse import Parser
from parse_type import TypeBuilder

parse_choice_yesno = TypeBuilder.make_choice(["yes", "no"])
schema = "Answer: {answer:ChoiceYesNo}"
parser = Parser(schema, dict(ChoiceYesNo=parse_choice_yesno))
result = parser.parse("Answer: yes")
assert result["answer"] == "yes"

Variant (Type Alternatives)

Sometimes you need a type converter that can accept text for multiple type converter alternatives. This is normally called a “variant” (or: union).

Create an type converter for an “Variant” type that accepts:

  • Numbers (positive numbers, as integer)

  • Color enum values (by name)

from parse import Parser, with_pattern
from parse_type import TypeBuilder
from enum import Enum

class Color(Enum):
    red   = 1
    green = 2
    blue  = 3

@with_pattern(r"\d+")
def parse_number(text):
    return int(text)

# -- MAKE VARIANT: Alternatives of different type converters.
parse_color = TypeBuilder.make_enum(Color)
parse_variant = TypeBuilder.make_variant([parse_number, parse_color])
schema = "Variant: {variant:Number_or_Color}"
parser = Parser(schema, dict(Number_or_Color=parse_variant))

# -- TEST VARIANT: With number, color and mismatch.
result = parser.parse("Variant: 42")
assert result["variant"] == 42
result = parser.parse("Variant: blue")
assert result["variant"] is Color.blue
result = parser.parse("Variant: __MISMATCH__")
assert not result

Extended Parser with CardinalityField support

The parser extends the parse.Parser and adds the following functionality:

  • supports the CardinalityField naming scheme

  • automatically creates missing type variants for types with a CardinalityField by using the primary type converter for cardinality=1

  • extends the provide type converter dictionary with new type variants.

Example:

# -- USE CASE: Parser with CardinalityField support.
# NOTE: Automatically adds missing type variants with CardinalityField part.
# USE:  parse_number() type converter from above.
from parse_type.cfparse import Parser

# -- PREPARE: parser, adds missing type variant for cardinality 1..* (many)
type_dict = dict(Number=parse_number)
schema = "List: {numbers:Number+}"
parser = Parser(schema, type_dict)
assert "Number+" in type_dict, "Created missing type variant based on: Number"

# -- USE: parser.
result = parser.parse("List: 1, 2, 3")
assert result["numbers"] == [1, 2, 3]

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

parse_type-0.6.6.tar.gz (98.0 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

parse_type-0.6.6-py2.py3-none-any.whl (27.1 kB view details)

Uploaded Python 2Python 3

File details

Details for the file parse_type-0.6.6.tar.gz.

File metadata

  • Download URL: parse_type-0.6.6.tar.gz
  • Upload date:
  • Size: 98.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.12.9

File hashes

Hashes for parse_type-0.6.6.tar.gz
Algorithm Hash digest
SHA256 513a3784104839770d690e04339a8b4d33439fcd5dd99f2e4580f9fc1097bfb2
MD5 e81bc44d8c483f3219ddfab427337e01
BLAKE2b-256 19ea42ba6ce0abba04ab6e0b997dcb9b528a4661b62af1fe1b0d498120d5ea78

See more details on using hashes here.

Provenance

The following attestation bundles were made for parse_type-0.6.6.tar.gz:

Publisher: release-to-pypi.yml on jenisys/parse_type

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file parse_type-0.6.6-py2.py3-none-any.whl.

File metadata

  • Download URL: parse_type-0.6.6-py2.py3-none-any.whl
  • Upload date:
  • Size: 27.1 kB
  • Tags: Python 2, Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.12.9

File hashes

Hashes for parse_type-0.6.6-py2.py3-none-any.whl
Algorithm Hash digest
SHA256 3ca79bbe71e170dfccc8ec6c341edfd1c2a0fc1e5cfd18330f93af938de2348c
MD5 c459889174498fc77de43a1666951c0c
BLAKE2b-256 858deef3d8cdccc32abdd91b1286884c99b8c3a6d3b135affcc2a7a0f383bb32

See more details on using hashes here.

Provenance

The following attestation bundles were made for parse_type-0.6.6-py2.py3-none-any.whl:

Publisher: release-to-pypi.yml on jenisys/parse_type

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Release history Release notifications | RSS feed

This release

0.6.6 This release

2 files

0.6.6b0

2 files

0.6.4

2 files

0.6.3

2 files

0.6.2

2 files

0.6.1

2 files

0.6.0

2 files

0.5.2

2 files

0.4.2

2 files

0.4.1

2 files

0.4.0

2 files

0.3.4

1 file

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page