Examples

This page contains the raw code + output of our examples. For detailed explanations of what is going on please see the Quick Start guide.

Example 1

Code Listing: Example 1

 1#!/usr/bin/env python3
 2"""
 3Example 01 for StronglyTypedProperty
 4
 5This example demonstrates a simple example of the StronglyTypedProperty class
 6that creates a new class called ``MyClass`` that defines some properties.
 7- ``default_property`` - uses the default parameters which creates a property
 8  that will accept string and int values as its types. The default value is set
 9  to ``None`` which can be set to track use-before-define issues.
10- ``string_property`` - This property can only be assigned string values.
11- ``string_property_2`` - This property allows only strings but it also requires
12  a value to be assigned to the property before it can be used.
13- ``list_property`` - This property takes either a list or a tuple. It is stored
14  as a ``list`` internally which means any tuples that get assigned will be
15  converted to a list type. The default value is the 2-tuple ``(None, None)``.
16"""
17from stronglytypedproperty import strongly_typed_property
18
19
20
21class MyClass(object):
22    """
23    A simple class to demonstrate different uses of strongly typed properties
24    """
25    # Create a strongly typed property using the defaults. This will accept strings
26    # and int values as its types. The default value will be `None`.
27    default_property = strongly_typed_property("default_property")
28
29    # Create a property that only stores strings but is explicitly defaulted
30    # to `None`.
31    string_property = strongly_typed_property("string_property", (str), default=None)
32
33    # Same as `string_property` but will throw an exception if the value is used prior to assignment.
34    string_property_2 = strongly_typed_property("string_property_2", (str), req_assign_before_use=True)
35
36    # Create a list type property that can accept lists or tuples but will
37    # store data internally as a list
38    list_property = strongly_typed_property(
39        name="list_property", expected_type=(tuple, list), internal_type=list, default=(None, None)
40    )
41
42
43
44#
45# default_property
46#
47def default_property_example():
48    print("\n--- default_property_example() ---")
49
50    # Create an object of MyClass
51    myobj = MyClass()
52
53    print(f"myobj.default_property default: {myobj.default_property}")
54
55    myobj.default_property = 99
56    print(f"myobj.default_property = 99: {myobj.default_property}")
57
58    myobj.default_property = "ninety-nime"
59    print(f"myobj.default_property = 'ninety-nine': {myobj.default_property}")
60
61
62
63#
64# Call example methods
65#
66if __name__ == "__main__":
67    default_property_example()

Output: Example 1


--- default_property_example() ---
myobj.default_property default: None
myobj.default_property = 99: 99
myobj.default_property = 'ninety-nine': ninety-nime

Example 2

Code Listing: Example 2

 1#!/usr/bin/env python3
 2"""
 3Example 02 for StronglyTypedProperty
 4
 5This example expands on Example-01 by showing some erroneous assignments in the
 6``string_property_example()`` function.
 7"""
 8from stronglytypedproperty import strongly_typed_property
 9
10
11
12class MyClass(object):
13    """
14    A simple class to demonstrate different uses of strongly typed properties
15    """
16    # Create a strongly typed property using the defaults. This will accept strings
17    # and int values as its types. The default value will be `None`.
18    default_property = strongly_typed_property("default_property")
19
20    # Create a property that only stores strings but is explicitly defaulted
21    # to `None`.
22    string_property = strongly_typed_property("string_property", (str), default=None)
23
24    # Same as `string_property` but will throw an exception if the value is used prior to assignment.
25    string_property_2 = strongly_typed_property("string_property_2", (str), req_assign_before_use=True)
26
27    # Create a list type property that can accept lists or tuples but will
28    # store data internally as a list
29    list_property = strongly_typed_property(
30        name="list_property", expected_type=(tuple, list), internal_type=list, default=(None, None)
31    )
32
33
34
35#
36# string_property
37#
38def string_property_example():
39    print("\n--- string_property_example() ---")
40
41    # Create an object of MyClass
42    myobj = MyClass()
43
44    print(f"myobj.string_property: {myobj.string_property}")
45
46    try:
47        myobj.string_property = 99
48        print("If this is displayed then type checking failed!")
49    except TypeError as err:
50        print("TypeError was called.")
51        print(f"    Message: {err}")
52
53    myobj.string_property = "ninety-nime"
54    print(f"myobj.string_property = 'ninety-nine': {myobj.string_property}")
55
56
57
58#
59# Call example methods
60#
61if __name__ == "__main__":
62    string_property_example()

Output: Example 2


--- string_property_example() ---
myobj.string_property: None
TypeError was called.
    Message: Invalid type assigned to `string_property`, must be one of (str)
myobj.string_property = 'ninety-nine': ninety-nime

Example 3

Code Listing: Example 3

 1#!/usr/bin/env python3
 2"""
 3Example 03 for StronglyTypedProperty
 4
 5This is another expansion of Example 01 that shows an error being thrown when
 6trying to use ``string_property_2`` before assignment. In this case the error
 7``UnboundLocalError`` is triggered.
 8"""
 9from stronglytypedproperty import strongly_typed_property
10
11
12
13class MyClass(object):
14    """
15    A simple class to demonstrate different uses of strongly typed properties
16    """
17    # Create a strongly typed property using the defaults. This will accept strings
18    # and int values as its types. The default value will be `None`.
19    default_property = strongly_typed_property("default_property")
20
21    # Create a property that only stores strings but is explicitly defaulted
22    # to `None`.
23    string_property = strongly_typed_property("string_property", (str), default=None)
24
25    # Same as `string_property` but will throw an exception if the value is used prior to assignment.
26    string_property_2 = strongly_typed_property("string_property_2", (str), req_assign_before_use=True)
27
28    # Create a list type property that can accept lists or tuples but will
29    # store data internally as a list
30    list_property = strongly_typed_property(
31        name="list_property", expected_type=(tuple, list), internal_type=list, default=(None, None)
32    )
33
34
35
36#
37# string_property_2
38#
39def string_property_2_example():
40    print("\n--- string_property_2_example() ---")
41
42    # Create an object of MyClass
43    myobj = MyClass()
44
45    try:
46        print(f"myobj.string_property_2: {myobj.string_property_2}")
47    except UnboundLocalError as err:
48        print("UnboundLocalError was called.")
49        print(f"    Message: {err}")
50
51
52
53#
54# Call example methods
55#
56if __name__ == "__main__":
57    string_property_2_example()

Output: Example 3


--- string_property_2_example() ---
UnboundLocalError was called.
    Message: Property `string_property_2` was used before assignment.

Example 4

Code Listing: Example 4

 1#!/usr/bin/env python3
 2"""
 3Example for StronglyTypedProperty
 4
 5
 6"""
 7from stronglytypedproperty import strongly_typed_property
 8
 9
10
11class MyClass(object):
12    """
13    A simple class to demonstrate different uses of strongly typed properties
14    """
15    # Create a strongly typed property using the defaults. This will accept strings
16    # and int values as its types. The default value will be `None`.
17    default_property = strongly_typed_property("default_property")
18
19    # Create a property that only stores strings but is explicitly defaulted
20    # to `None`.
21    string_property = strongly_typed_property("string_property", (str), default=None)
22
23    # Same as `string_property` but will throw an exception if the value is used prior to assignment.
24    string_property_2 = strongly_typed_property("string_property_2", (str), req_assign_before_use=True)
25
26    # Create a list type property that can accept lists or tuples but will
27    # store data internally as a list
28    list_property = strongly_typed_property(
29        name="list_property", expected_type=(tuple, list), internal_type=list, default=(None, None)
30    )
31
32
33
34#
35# list_property
36#
37def list_property_example():
38    print("\n--- list_property_example() ---")
39
40    # Create an object of MyClass
41    myobj = MyClass()
42
43    print(f"myobj.list_property: {myobj.list_property}")
44
45    # Assigning a list is allowable:
46    myobj.list_property = [2, "list"]
47    print(f"myobj.list_property: {myobj.list_property}")
48
49    # Assigning a tuple is also allowed:
50    myobj.list_property = (2, "tuple")
51    print(f"myobj.list_property: {myobj.list_property}")
52
53
54
55#
56# Call example methods
57#
58if __name__ == "__main__":
59    list_property_example()

Output: Example 4


--- list_property_example() ---
myobj.list_property: (None, None)
myobj.list_property: [2, 'list']
myobj.list_property: [2, 'tuple']

Example 5

Code Listing: Example 5

  1#!/usr/bin/env python3
  2"""
  3Example 05 for StronglyTypedProperty
  4
  5This example demonstrates the use of a validator function on properties.
  6In this case, we want the property ``prop_two_tuple`` to only accept _tuples_
  7that have exactly _two_ entries in them.
  8
  9To do this, we create a function ``validator_2tuple(value)`` that takes a
 10candidate value to be assigned to the property and can check it. If the function
 11returns 1 (truthy) then the value is accepted and will be saved to the property.
 12Otherwise, if the return value is 0 (falsy) then the assignment will fail and
 13a ``TypeError`` will be thrown.
 14
 15"""
 16from typing import Iterable
 17from stronglytypedproperty import strongly_typed_property
 18
 19
 20
 21def validator_2tuple(value: Iterable) -> int:
 22    """
 23    Validator callback for strongly typed property for two-tuples.
 24
 25    Assumes ``value`` is iterable.
 26
 27    Returns:
 28        int: 0 (FAIL) if length != 2, otherwise 1 (PASS).
 29    """
 30    if len(value) != 2:
 31        return 0
 32    return 1
 33
 34
 35
 36class MyClass(object):
 37    """
 38    Demonstrate the use of StronglyTypedProperty
 39    """
 40    # Create a type that must always take a tuple type of length 2.
 41    # - Length is checked every time a new value is set.
 42    prop_two_tuple = strongly_typed_property(
 43        "prop_two_tuple", tuple, default=(None, None), validator=validator_2tuple
 44    )
 45
 46
 47
 48def test_two_tuple() -> None:
 49    # Create an instance of MyClass
 50    obj = MyClass()
 51
 52    print("Test `prop_two_tuple`")
 53    print("-----------------------")
 54
 55    # -----
 56    print(f"1. Set `prop_two_tuple = (1,1)`")
 57    print(">  Should pass because length is 2.")
 58    obj.prop_two_tuple = (1, 1)
 59    print(f">  obj.prop_two_tuple = {obj.prop_two_tuple}")
 60    print(">OK<")
 61    print("")
 62
 63    # -----
 64    print(f"2. Set `prop_two_tuple = ('one','two')`")
 65    print(">  Should pass because length is 2.")
 66    obj.prop_two_tuple = ('one', 'two')
 67    print(f">  obj.prop_two_tuple = {obj.prop_two_tuple}")
 68    print(">OK<")
 69    print("")
 70
 71    # -----
 72    print(f"3. Set `prop_two_tuple = None`")
 73    print(">  This should raise a `TypeError` exception because `NoneType` is not a tuple")
 74    try:
 75        obj.prop_two_tuple = None
 76        print(f">  obj.prop_two_tuple = {obj.prop_two_tuple}")
 77        print(f">  *** If we see this message then StronglyTypedProperty failed to catch the TypeError ***")
 78    except TypeError as err:
 79        print(f">  TypeError was correctly raised by strongly_typed_property!")
 80        print(f">  - err message:\n  {err}")
 81    print(">OK<")
 82    print("")
 83
 84    # -----
 85    print(f"4. Set `prop_two_tuple = (1,2,3)`")
 86    print(">  This should raise a `ValueError` exception because the length is incorrect")
 87    try:
 88        obj.prop_two_tuple = (1, 2, 3)
 89        print(f">  obj.prop_two_tuple = {obj.prop_two_tuple}")
 90        print(f">  *** If we see this message then StronglyTypedProperty failed to catch the ValueError ***")
 91    except ValueError as err:
 92        print(f">  ValueError was correctly raised by strongly_typed_property!")
 93        print(f">  - err message:\n  {err}")
 94    print(">OK<")
 95    print("")
 96
 97
 98
 99if __name__ == "__main__":
100    test_two_tuple()

Output: Example 5

Test `prop_two_tuple`
-----------------------
1. Set `prop_two_tuple = (1,1)`
>  Should pass because length is 2.
>  obj.prop_two_tuple = (1, 1)
>OK<

2. Set `prop_two_tuple = ('one','two')`
>  Should pass because length is 2.
>  obj.prop_two_tuple = ('one', 'two')
>OK<

3. Set `prop_two_tuple = None`
>  This should raise a `TypeError` exception because `NoneType` is not a tuple
>  TypeError was correctly raised by strongly_typed_property!
>  - err message:
  Invalid type assigned to `prop_two_tuple`, must be one of (tuple)
>OK<

4. Set `prop_two_tuple = (1,2,3)`
>  This should raise a `ValueError` exception because the length is incorrect
>  ValueError was correctly raised by strongly_typed_property!
>  - err message:
  Assignment of `(1, 2, 3)` to property `prop_two_tuple` failed validation check in `<function validator_2tuple at 0x795ad85d4d50>`.
>OK<