mirror of
https://github.com/hyperion-project/hyperion.ng.git
synced 2023-10-10 13:36:59 +02:00
add json check before compile (#354)
* add json check before compile * do more checking on effects * add effects checking * better effects checking. * integrate schema check for default config reduce size of default configs
This commit is contained in:
parent
f22848f9f4
commit
2c61b49b57
1
.gitignore
vendored
1
.gitignore
vendored
@ -17,3 +17,4 @@ CMakeCache.txt
|
|||||||
/HyperionConfig.h
|
/HyperionConfig.h
|
||||||
/lib
|
/lib
|
||||||
.directory
|
.directory
|
||||||
|
*.pyc
|
||||||
|
@ -16,6 +16,7 @@ SET ( HYPERION_VERSION_STABLE OFF )
|
|||||||
SET ( HYPERION_VERSION_MAJOR 2 )
|
SET ( HYPERION_VERSION_MAJOR 2 )
|
||||||
SET ( HYPERION_VERSION_MINOR 0 )
|
SET ( HYPERION_VERSION_MINOR 0 )
|
||||||
SET ( HYPERION_VERSION_PATCH 0 )
|
SET ( HYPERION_VERSION_PATCH 0 )
|
||||||
|
SET ( CURRENT_CONFIG_VERSION 2 )
|
||||||
|
|
||||||
SET ( DEFAULT_AMLOGIC OFF )
|
SET ( DEFAULT_AMLOGIC OFF )
|
||||||
SET ( DEFAULT_DISPMANX OFF )
|
SET ( DEFAULT_DISPMANX OFF )
|
||||||
@ -140,6 +141,40 @@ message(STATUS "ENABLE_PROFILER = ${ENABLE_PROFILER}")
|
|||||||
SET ( PROTOBUF_INSTALL_BIN_DIR ${CMAKE_BINARY_DIR}/proto )
|
SET ( PROTOBUF_INSTALL_BIN_DIR ${CMAKE_BINARY_DIR}/proto )
|
||||||
SET ( PROTOBUF_INSTALL_LIB_DIR ${CMAKE_BINARY_DIR}/proto )
|
SET ( PROTOBUF_INSTALL_LIB_DIR ${CMAKE_BINARY_DIR}/proto )
|
||||||
|
|
||||||
|
# check all json files
|
||||||
|
FILE ( GLOB_RECURSE HYPERION_SCHEMAS RELATIVE ${CMAKE_SOURCE_DIR} ${CMAKE_SOURCE_DIR}/libsrc/*schema*.json )
|
||||||
|
SET( JSON_FILES
|
||||||
|
config/hyperion.config.json.default
|
||||||
|
${HYPERION_SCHEMAS}
|
||||||
|
)
|
||||||
|
EXECUTE_PROCESS (
|
||||||
|
COMMAND python test/jsonchecks/checkjson.py ${JSON_FILES}
|
||||||
|
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
|
||||||
|
RESULT_VARIABLE CHECK_JSON_FAILED
|
||||||
|
)
|
||||||
|
IF ( ${CHECK_JSON_FAILED} )
|
||||||
|
MESSAGE (FATAL_ERROR "check of json files failed" )
|
||||||
|
ENDIF ()
|
||||||
|
|
||||||
|
EXECUTE_PROCESS (
|
||||||
|
COMMAND python test/jsonchecks/checkeffects.py effects effects/schema
|
||||||
|
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
|
||||||
|
RESULT_VARIABLE CHECK_EFFECTS_FAILED
|
||||||
|
)
|
||||||
|
IF ( ${CHECK_EFFECTS_FAILED} )
|
||||||
|
MESSAGE (FATAL_ERROR "check of json effect files failed" )
|
||||||
|
ENDIF ()
|
||||||
|
|
||||||
|
EXECUTE_PROCESS (
|
||||||
|
COMMAND python test/jsonchecks/checkschema.py config/hyperion.config.json.default libsrc/hyperion/schemas/hyperion.schema-${CURRENT_CONFIG_VERSION}.json
|
||||||
|
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
|
||||||
|
RESULT_VARIABLE CHECK_CONFIG_FAILED
|
||||||
|
)
|
||||||
|
IF ( ${CHECK_CONFIG_FAILED} )
|
||||||
|
MESSAGE (FATAL_ERROR "check of json default config failed" )
|
||||||
|
ENDIF ()
|
||||||
|
|
||||||
|
|
||||||
# Createt the configuration file
|
# Createt the configuration file
|
||||||
|
|
||||||
# Add project specific cmake modules (find, etc)
|
# Add project specific cmake modules (find, etc)
|
||||||
|
@ -30,6 +30,9 @@
|
|||||||
// Define to enable profiler for development purpose
|
// Define to enable profiler for development purpose
|
||||||
#cmakedefine ENABLE_PROFILER
|
#cmakedefine ENABLE_PROFILER
|
||||||
|
|
||||||
|
// Define version id of current config
|
||||||
|
#define CURRENT_CONFIG_VERSION ${CURRENT_CONFIG_VERSION}
|
||||||
|
|
||||||
// the hyperion build id string
|
// the hyperion build id string
|
||||||
#define HYPERION_BUILD_ID "${HYPERION_BUILD_ID}"
|
#define HYPERION_BUILD_ID "${HYPERION_BUILD_ID}"
|
||||||
|
|
||||||
@ -40,4 +43,4 @@
|
|||||||
|
|
||||||
#define HYPERION_JSON_VERSION "1.0.0"
|
#define HYPERION_JSON_VERSION "1.0.0"
|
||||||
|
|
||||||
#define CURRENT_CONFIG_VERSION 2
|
|
||||||
|
@ -70,7 +70,7 @@
|
|||||||
{
|
{
|
||||||
"imageToLedMappingType" : "multicolor_mean",
|
"imageToLedMappingType" : "multicolor_mean",
|
||||||
"channelAdjustment_enable" : true,
|
"channelAdjustment_enable" : true,
|
||||||
"channelAdjustment_v4l_only" : true,
|
"channelAdjustment_v4l_only" : false,
|
||||||
"channelAdjustment" :
|
"channelAdjustment" :
|
||||||
[
|
[
|
||||||
{
|
{
|
||||||
@ -87,7 +87,7 @@
|
|||||||
}
|
}
|
||||||
],
|
],
|
||||||
"transform_enable" : true,
|
"transform_enable" : true,
|
||||||
"transform_v4l_only" : true,
|
"transform_v4l_only" : false,
|
||||||
"transform" :
|
"transform" :
|
||||||
[
|
[
|
||||||
{
|
{
|
||||||
@ -381,234 +381,94 @@
|
|||||||
"leds" :
|
"leds" :
|
||||||
[
|
[
|
||||||
{
|
{
|
||||||
"index" : 0,
|
"index": 0,
|
||||||
"hscan" : { "minimum" : 0.5000, "maximum" : 0.5625 },
|
"hscan": { "maximum": 0.1667, "minimum": 0 },
|
||||||
"vscan" : { "minimum" : 0.9200, "maximum" : 1.0000 }
|
"vscan": { "maximum": 0.0800, "minimum": 0 }
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"index" : 1,
|
"index": 1,
|
||||||
"hscan" : { "minimum" : 0.4375, "maximum" : 0.5000 },
|
"hscan": { "maximum": 0.3332, "minimum": 0.1667 },
|
||||||
"vscan" : { "minimum" : 0.9200, "maximum" : 1.0000 }
|
"vscan": { "maximum": 0.0800, "minimum": 0 }
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"index" : 2,
|
"index": 2,
|
||||||
"hscan" : { "minimum" : 0.3750, "maximum" : 0.4375 },
|
"hscan": { "maximum": 0.5, "minimum": 0.3333 },
|
||||||
"vscan" : { "minimum" : 0.9200, "maximum" : 1.0000 }
|
"vscan": { "maximum": 0.0800, "minimum": 0 }
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"index" : 3,
|
"index": 3,
|
||||||
"hscan" : { "minimum" : 0.3125, "maximum" : 0.3750 },
|
"hscan": { "maximum": 0.6667, "minimum": 0.5 },
|
||||||
"vscan" : { "minimum" : 0.9200, "maximum" : 1.0000 }
|
"vscan": { "maximum": 0.0800, "minimum": 0 }
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"index" : 4,
|
"index": 4,
|
||||||
"hscan" : { "minimum" : 0.2500, "maximum" : 0.3125 },
|
"hscan": { "maximum": 0.8333, "minimum": 0.6667 },
|
||||||
"vscan" : { "minimum" : 0.9200, "maximum" : 1.0000 }
|
"vscan": { "maximum": 0.0800, "minimum": 0 }
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"index" : 5,
|
"index": 5,
|
||||||
"hscan" : { "minimum" : 0.1875, "maximum" : 0.2500 },
|
"hscan": { "maximum": 1, "minimum": 0.8333 },
|
||||||
"vscan" : { "minimum" : 0.9200, "maximum" : 1.0000 }
|
"vscan": { "maximum": 0.0800, "minimum": 0 }
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"index" : 6,
|
"index": 6,
|
||||||
"hscan" : { "minimum" : 0.1250, "maximum" : 0.1875 },
|
"hscan": { "maximum": 1, "minimum": 0.95 },
|
||||||
"vscan" : { "minimum" : 0.9200, "maximum" : 1.0000 }
|
"vscan": { "maximum": 0.3333, "minimum": 0 }
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"index" : 7,
|
"index": 7,
|
||||||
"hscan" : { "minimum" : 0.0625, "maximum" : 0.1250 },
|
"hscan": { "maximum": 1, "minimum": 0.95 },
|
||||||
"vscan" : { "minimum" : 0.9200, "maximum" : 1.0000 }
|
"vscan": { "maximum": 0.6667, "minimum": 0.3333 }
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"index" : 8,
|
"index": 8,
|
||||||
"hscan" : { "minimum" : 0.0000, "maximum" : 0.0625 },
|
"hscan": { "maximum": 1, "minimum": 0.95 },
|
||||||
"vscan" : { "minimum" : 0.9200, "maximum" : 1.0000 }
|
"vscan": { "maximum": 1, "minimum": 0.6667 }
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"index" : 9,
|
"index": 9,
|
||||||
"hscan" : { "minimum" : 0.0000, "maximum" : 0.0500 },
|
"hscan": { "maximum": 1, "minimum": 0.8333 },
|
||||||
"vscan" : { "minimum" : 0.8571, "maximum" : 1.0000 }
|
"vscan": { "maximum": 1, "minimum": 0.92 }
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"index" : 10,
|
"index": 10,
|
||||||
"hscan" : { "minimum" : 0.0000, "maximum" : 0.0500 },
|
"hscan": { "maximum": 0.8333, "minimum": 0.6667 },
|
||||||
"vscan" : { "minimum" : 0.7143, "maximum" : 0.8571 }
|
"vscan": { "maximum": 1, "minimum": 0.92 }
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"index" : 11,
|
"index": 11,
|
||||||
"hscan" : { "minimum" : 0.0000, "maximum" : 0.0500 },
|
"hscan": { "maximum": 0.6667, "minimum": 0.5 },
|
||||||
"vscan" : { "minimum" : 0.5714, "maximum" : 0.7143 }
|
"vscan": { "maximum": 1, "minimum": 0.92 }
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"index" : 12,
|
"index": 12,
|
||||||
"hscan" : { "minimum" : 0.0000, "maximum" : 0.0500 },
|
"hscan": { "maximum": 0.5, "minimum": 0.3333 },
|
||||||
"vscan" : { "minimum" : 0.4286, "maximum" : 0.5714 }
|
"vscan": { "maximum": 1, "minimum": 0.92 }
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"index" : 13,
|
"index": 13,
|
||||||
"hscan" : { "minimum" : 0.0000, "maximum" : 0.0500 },
|
"hscan": { "maximum": 0.3333, "minimum": 0.1667 },
|
||||||
"vscan" : { "minimum" : 0.2857, "maximum" : 0.4286 }
|
"vscan": { "maximum": 1, "minimum": 0.92 }
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"index" : 14,
|
"index": 14,
|
||||||
"hscan" : { "minimum" : 0.0000, "maximum" : 0.0500 },
|
"hscan": { "maximum": 0.1667, "minimum": 0 },
|
||||||
"vscan" : { "minimum" : 0.1429, "maximum" : 0.2857 }
|
"vscan": { "maximum": 1, "minimum": 0.92 }
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"index" : 15,
|
"index": 15,
|
||||||
"hscan" : { "minimum" : 0.0000, "maximum" : 0.0500 },
|
"hscan": { "maximum": 0.05, "minimum": 0 },
|
||||||
"vscan" : { "minimum" : 0.0000, "maximum" : 0.1429 }
|
"vscan": { "maximum": 1, "minimum": 0.6667 }
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"index" : 16,
|
"index": 16,
|
||||||
"hscan" : { "minimum" : 0.0000, "maximum" : 0.0625 },
|
"hscan": { "maximum": 0.05, "minimum": 0 },
|
||||||
"vscan" : { "minimum" : 0.0000, "maximum" : 0.0800 }
|
"vscan": { "maximum": 0.6667, "minimum": 0.3333 }
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"index" : 17,
|
"index": 17,
|
||||||
"hscan" : { "minimum" : 0.0625, "maximum" : 0.1250 },
|
"hscan": { "maximum": 0.05, "minimum": 0 },
|
||||||
"vscan" : { "minimum" : 0.0000, "maximum" : 0.0800 }
|
"vscan": { "maximum": 0.3333, "minimum": 0 }
|
||||||
},
|
|
||||||
{
|
|
||||||
"index" : 18,
|
|
||||||
"hscan" : { "minimum" : 0.1250, "maximum" : 0.1875 },
|
|
||||||
"vscan" : { "minimum" : 0.0000, "maximum" : 0.0800 }
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"index" : 19,
|
|
||||||
"hscan" : { "minimum" : 0.1875, "maximum" : 0.2500 },
|
|
||||||
"vscan" : { "minimum" : 0.0000, "maximum" : 0.0800 }
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"index" : 20,
|
|
||||||
"hscan" : { "minimum" : 0.2500, "maximum" : 0.3125 },
|
|
||||||
"vscan" : { "minimum" : 0.0000, "maximum" : 0.0800 }
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"index" : 21,
|
|
||||||
"hscan" : { "minimum" : 0.3125, "maximum" : 0.3750 },
|
|
||||||
"vscan" : { "minimum" : 0.0000, "maximum" : 0.0800 }
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"index" : 22,
|
|
||||||
"hscan" : { "minimum" : 0.3750, "maximum" : 0.4375 },
|
|
||||||
"vscan" : { "minimum" : 0.0000, "maximum" : 0.0800 }
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"index" : 23,
|
|
||||||
"hscan" : { "minimum" : 0.4375, "maximum" : 0.5000 },
|
|
||||||
"vscan" : { "minimum" : 0.0000, "maximum" : 0.0800 }
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"index" : 24,
|
|
||||||
"hscan" : { "minimum" : 0.5000, "maximum" : 0.5625 },
|
|
||||||
"vscan" : { "minimum" : 0.0000, "maximum" : 0.0800 }
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"index" : 25,
|
|
||||||
"hscan" : { "minimum" : 0.5625, "maximum" : 0.6250 },
|
|
||||||
"vscan" : { "minimum" : 0.0000, "maximum" : 0.0800 }
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"index" : 26,
|
|
||||||
"hscan" : { "minimum" : 0.6250, "maximum" : 0.6875 },
|
|
||||||
"vscan" : { "minimum" : 0.0000, "maximum" : 0.0800 }
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"index" : 27,
|
|
||||||
"hscan" : { "minimum" : 0.6875, "maximum" : 0.7500 },
|
|
||||||
"vscan" : { "minimum" : 0.0000, "maximum" : 0.0800 }
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"index" : 28,
|
|
||||||
"hscan" : { "minimum" : 0.7500, "maximum" : 0.8125 },
|
|
||||||
"vscan" : { "minimum" : 0.0000, "maximum" : 0.0800 }
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"index" : 29,
|
|
||||||
"hscan" : { "minimum" : 0.8125, "maximum" : 0.8750 },
|
|
||||||
"vscan" : { "minimum" : 0.0000, "maximum" : 0.0800 }
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"index" : 30,
|
|
||||||
"hscan" : { "minimum" : 0.8750, "maximum" : 0.9375 },
|
|
||||||
"vscan" : { "minimum" : 0.0000, "maximum" : 0.0800 }
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"index" : 31,
|
|
||||||
"hscan" : { "minimum" : 0.9375, "maximum" : 1.0000 },
|
|
||||||
"vscan" : { "minimum" : 0.0000, "maximum" : 0.0800 }
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"index" : 32,
|
|
||||||
"hscan" : { "minimum" : 0.9500, "maximum" : 1.0000 },
|
|
||||||
"vscan" : { "minimum" : 0.0000, "maximum" : 0.1429 }
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"index" : 33,
|
|
||||||
"hscan" : { "minimum" : 0.9500, "maximum" : 1.0000 },
|
|
||||||
"vscan" : { "minimum" : 0.1429, "maximum" : 0.2857 }
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"index" : 34,
|
|
||||||
"hscan" : { "minimum" : 0.9500, "maximum" : 1.0000 },
|
|
||||||
"vscan" : { "minimum" : 0.2857, "maximum" : 0.4286 }
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"index" : 35,
|
|
||||||
"hscan" : { "minimum" : 0.9500, "maximum" : 1.0000 },
|
|
||||||
"vscan" : { "minimum" : 0.4286, "maximum" : 0.5714 }
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"index" : 36,
|
|
||||||
"hscan" : { "minimum" : 0.9500, "maximum" : 1.0000 },
|
|
||||||
"vscan" : { "minimum" : 0.5714, "maximum" : 0.7143 }
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"index" : 37,
|
|
||||||
"hscan" : { "minimum" : 0.9500, "maximum" : 1.0000 },
|
|
||||||
"vscan" : { "minimum" : 0.7143, "maximum" : 0.8571 }
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"index" : 38,
|
|
||||||
"hscan" : { "minimum" : 0.9500, "maximum" : 1.0000 },
|
|
||||||
"vscan" : { "minimum" : 0.8571, "maximum" : 1.0000 }
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"index" : 39,
|
|
||||||
"hscan" : { "minimum" : 0.9375, "maximum" : 1.0000 },
|
|
||||||
"vscan" : { "minimum" : 0.9200, "maximum" : 1.0000 }
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"index" : 40,
|
|
||||||
"hscan" : { "minimum" : 0.8750, "maximum" : 0.9375 },
|
|
||||||
"vscan" : { "minimum" : 0.9200, "maximum" : 1.0000 }
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"index" : 41,
|
|
||||||
"hscan" : { "minimum" : 0.8125, "maximum" : 0.8750 },
|
|
||||||
"vscan" : { "minimum" : 0.9200, "maximum" : 1.0000 }
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"index" : 42,
|
|
||||||
"hscan" : { "minimum" : 0.7500, "maximum" : 0.8125 },
|
|
||||||
"vscan" : { "minimum" : 0.9200, "maximum" : 1.0000 }
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"index" : 43,
|
|
||||||
"hscan" : { "minimum" : 0.6875, "maximum" : 0.7500 },
|
|
||||||
"vscan" : { "minimum" : 0.9200, "maximum" : 1.0000 }
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"index" : 44,
|
|
||||||
"hscan" : { "minimum" : 0.6250, "maximum" : 0.6875 },
|
|
||||||
"vscan" : { "minimum" : 0.9200, "maximum" : 1.0000 }
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"index" : 45,
|
|
||||||
"hscan" : { "minimum" : 0.5625, "maximum" : 0.6250 },
|
|
||||||
"vscan" : { "minimum" : 0.9200, "maximum" : 1.0000 }
|
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
@ -22,7 +22,7 @@
|
|||||||
{
|
{
|
||||||
"imageToLedMappingType" : "multicolor_mean",
|
"imageToLedMappingType" : "multicolor_mean",
|
||||||
"channelAdjustment_enable" : true,
|
"channelAdjustment_enable" : true,
|
||||||
"channelAdjustment_v4l_only" : true,
|
"channelAdjustment_v4l_only" : false,
|
||||||
"channelAdjustment" :
|
"channelAdjustment" :
|
||||||
[
|
[
|
||||||
{
|
{
|
||||||
@ -39,7 +39,7 @@
|
|||||||
}
|
}
|
||||||
],
|
],
|
||||||
"transform_enable" : true,
|
"transform_enable" : true,
|
||||||
"transform_v4l_only" : true,
|
"transform_v4l_only" : false,
|
||||||
"transform" :
|
"transform" :
|
||||||
[
|
[
|
||||||
{
|
{
|
||||||
@ -114,7 +114,7 @@
|
|||||||
"type" : "auto",
|
"type" : "auto",
|
||||||
"width" : 80,
|
"width" : 80,
|
||||||
"height" : 45,
|
"height" : 45,
|
||||||
"frequency_Hz" : 10.0,
|
"frequency_Hz" : 10,
|
||||||
"priority" : 900
|
"priority" : 900
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -190,237 +190,97 @@
|
|||||||
"paths" : ["../custom-effects"]
|
"paths" : ["../custom-effects"]
|
||||||
},
|
},
|
||||||
|
|
||||||
"leds" :
|
"leds":
|
||||||
[
|
[
|
||||||
{
|
{
|
||||||
"index" : 0,
|
"index": 0,
|
||||||
"hscan" : { "minimum" : 0.5000, "maximum" : 0.5625 },
|
"hscan": { "maximum": 0.1667, "minimum": 0 },
|
||||||
"vscan" : { "minimum" : 0.9200, "maximum" : 1.0000 }
|
"vscan": { "maximum": 0.0800, "minimum": 0 }
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"index" : 1,
|
"index": 1,
|
||||||
"hscan" : { "minimum" : 0.4375, "maximum" : 0.5000 },
|
"hscan": { "maximum": 0.3332, "minimum": 0.1667 },
|
||||||
"vscan" : { "minimum" : 0.9200, "maximum" : 1.0000 }
|
"vscan": { "maximum": 0.0800, "minimum": 0 }
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"index" : 2,
|
"index": 2,
|
||||||
"hscan" : { "minimum" : 0.3750, "maximum" : 0.4375 },
|
"hscan": { "maximum": 0.5, "minimum": 0.3333 },
|
||||||
"vscan" : { "minimum" : 0.9200, "maximum" : 1.0000 }
|
"vscan": { "maximum": 0.0800, "minimum": 0 }
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"index" : 3,
|
"index": 3,
|
||||||
"hscan" : { "minimum" : 0.3125, "maximum" : 0.3750 },
|
"hscan": { "maximum": 0.6667, "minimum": 0.5 },
|
||||||
"vscan" : { "minimum" : 0.9200, "maximum" : 1.0000 }
|
"vscan": { "maximum": 0.0800, "minimum": 0 }
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"index" : 4,
|
"index": 4,
|
||||||
"hscan" : { "minimum" : 0.2500, "maximum" : 0.3125 },
|
"hscan": { "maximum": 0.8333, "minimum": 0.6667 },
|
||||||
"vscan" : { "minimum" : 0.9200, "maximum" : 1.0000 }
|
"vscan": { "maximum": 0.0800, "minimum": 0 }
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"index" : 5,
|
"index": 5,
|
||||||
"hscan" : { "minimum" : 0.1875, "maximum" : 0.2500 },
|
"hscan": { "maximum": 1, "minimum": 0.8333 },
|
||||||
"vscan" : { "minimum" : 0.9200, "maximum" : 1.0000 }
|
"vscan": { "maximum": 0.0800, "minimum": 0 }
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"index" : 6,
|
"index": 6,
|
||||||
"hscan" : { "minimum" : 0.1250, "maximum" : 0.1875 },
|
"hscan": { "maximum": 1, "minimum": 0.95 },
|
||||||
"vscan" : { "minimum" : 0.9200, "maximum" : 1.0000 }
|
"vscan": { "maximum": 0.3333, "minimum": 0 }
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"index" : 7,
|
"index": 7,
|
||||||
"hscan" : { "minimum" : 0.0625, "maximum" : 0.1250 },
|
"hscan": { "maximum": 1, "minimum": 0.95 },
|
||||||
"vscan" : { "minimum" : 0.9200, "maximum" : 1.0000 }
|
"vscan": { "maximum": 0.6667, "minimum": 0.3333 }
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"index" : 8,
|
"index": 8,
|
||||||
"hscan" : { "minimum" : 0.0000, "maximum" : 0.0625 },
|
"hscan": { "maximum": 1, "minimum": 0.95 },
|
||||||
"vscan" : { "minimum" : 0.9200, "maximum" : 1.0000 }
|
"vscan": { "maximum": 1, "minimum": 0.6667 }
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"index" : 9,
|
"index": 9,
|
||||||
"hscan" : { "minimum" : 0.0000, "maximum" : 0.0500 },
|
"hscan": { "maximum": 1, "minimum": 0.8333 },
|
||||||
"vscan" : { "minimum" : 0.8571, "maximum" : 1.0000 }
|
"vscan": { "maximum": 1, "minimum": 0.92 }
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"index" : 10,
|
"index": 10,
|
||||||
"hscan" : { "minimum" : 0.0000, "maximum" : 0.0500 },
|
"hscan": { "maximum": 0.8333, "minimum": 0.6667 },
|
||||||
"vscan" : { "minimum" : 0.7143, "maximum" : 0.8571 }
|
"vscan": { "maximum": 1, "minimum": 0.92 }
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"index" : 11,
|
"index": 11,
|
||||||
"hscan" : { "minimum" : 0.0000, "maximum" : 0.0500 },
|
"hscan": { "maximum": 0.6667, "minimum": 0.5 },
|
||||||
"vscan" : { "minimum" : 0.5714, "maximum" : 0.7143 }
|
"vscan": { "maximum": 1, "minimum": 0.92 }
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"index" : 12,
|
"index": 12,
|
||||||
"hscan" : { "minimum" : 0.0000, "maximum" : 0.0500 },
|
"hscan": { "maximum": 0.5, "minimum": 0.3333 },
|
||||||
"vscan" : { "minimum" : 0.4286, "maximum" : 0.5714 }
|
"vscan": { "maximum": 1, "minimum": 0.92 }
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"index" : 13,
|
"index": 13,
|
||||||
"hscan" : { "minimum" : 0.0000, "maximum" : 0.0500 },
|
"hscan": { "maximum": 0.3333, "minimum": 0.1667 },
|
||||||
"vscan" : { "minimum" : 0.2857, "maximum" : 0.4286 }
|
"vscan": { "maximum": 1, "minimum": 0.92 }
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"index" : 14,
|
"index": 14,
|
||||||
"hscan" : { "minimum" : 0.0000, "maximum" : 0.0500 },
|
"hscan": { "maximum": 0.1667, "minimum": 0 },
|
||||||
"vscan" : { "minimum" : 0.1429, "maximum" : 0.2857 }
|
"vscan": { "maximum": 1, "minimum": 0.92 }
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"index" : 15,
|
"index": 15,
|
||||||
"hscan" : { "minimum" : 0.0000, "maximum" : 0.0500 },
|
"hscan": { "maximum": 0.05, "minimum": 0 },
|
||||||
"vscan" : { "minimum" : 0.0000, "maximum" : 0.1429 }
|
"vscan": { "maximum": 1, "minimum": 0.6667 }
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"index" : 16,
|
"index": 16,
|
||||||
"hscan" : { "minimum" : 0.0000, "maximum" : 0.0625 },
|
"hscan": { "maximum": 0.05, "minimum": 0 },
|
||||||
"vscan" : { "minimum" : 0.0000, "maximum" : 0.0800 }
|
"vscan": { "maximum": 0.6667, "minimum": 0.3333 }
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"index" : 17,
|
"index": 17,
|
||||||
"hscan" : { "minimum" : 0.0625, "maximum" : 0.1250 },
|
"hscan": { "maximum": 0.05, "minimum": 0 },
|
||||||
"vscan" : { "minimum" : 0.0000, "maximum" : 0.0800 }
|
"vscan": { "maximum": 0.3333, "minimum": 0 }
|
||||||
},
|
|
||||||
{
|
|
||||||
"index" : 18,
|
|
||||||
"hscan" : { "minimum" : 0.1250, "maximum" : 0.1875 },
|
|
||||||
"vscan" : { "minimum" : 0.0000, "maximum" : 0.0800 }
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"index" : 19,
|
|
||||||
"hscan" : { "minimum" : 0.1875, "maximum" : 0.2500 },
|
|
||||||
"vscan" : { "minimum" : 0.0000, "maximum" : 0.0800 }
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"index" : 20,
|
|
||||||
"hscan" : { "minimum" : 0.2500, "maximum" : 0.3125 },
|
|
||||||
"vscan" : { "minimum" : 0.0000, "maximum" : 0.0800 }
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"index" : 21,
|
|
||||||
"hscan" : { "minimum" : 0.3125, "maximum" : 0.3750 },
|
|
||||||
"vscan" : { "minimum" : 0.0000, "maximum" : 0.0800 }
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"index" : 22,
|
|
||||||
"hscan" : { "minimum" : 0.3750, "maximum" : 0.4375 },
|
|
||||||
"vscan" : { "minimum" : 0.0000, "maximum" : 0.0800 }
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"index" : 23,
|
|
||||||
"hscan" : { "minimum" : 0.4375, "maximum" : 0.5000 },
|
|
||||||
"vscan" : { "minimum" : 0.0000, "maximum" : 0.0800 }
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"index" : 24,
|
|
||||||
"hscan" : { "minimum" : 0.5000, "maximum" : 0.5625 },
|
|
||||||
"vscan" : { "minimum" : 0.0000, "maximum" : 0.0800 }
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"index" : 25,
|
|
||||||
"hscan" : { "minimum" : 0.5625, "maximum" : 0.6250 },
|
|
||||||
"vscan" : { "minimum" : 0.0000, "maximum" : 0.0800 }
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"index" : 26,
|
|
||||||
"hscan" : { "minimum" : 0.6250, "maximum" : 0.6875 },
|
|
||||||
"vscan" : { "minimum" : 0.0000, "maximum" : 0.0800 }
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"index" : 27,
|
|
||||||
"hscan" : { "minimum" : 0.6875, "maximum" : 0.7500 },
|
|
||||||
"vscan" : { "minimum" : 0.0000, "maximum" : 0.0800 }
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"index" : 28,
|
|
||||||
"hscan" : { "minimum" : 0.7500, "maximum" : 0.8125 },
|
|
||||||
"vscan" : { "minimum" : 0.0000, "maximum" : 0.0800 }
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"index" : 29,
|
|
||||||
"hscan" : { "minimum" : 0.8125, "maximum" : 0.8750 },
|
|
||||||
"vscan" : { "minimum" : 0.0000, "maximum" : 0.0800 }
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"index" : 30,
|
|
||||||
"hscan" : { "minimum" : 0.8750, "maximum" : 0.9375 },
|
|
||||||
"vscan" : { "minimum" : 0.0000, "maximum" : 0.0800 }
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"index" : 31,
|
|
||||||
"hscan" : { "minimum" : 0.9375, "maximum" : 1.0000 },
|
|
||||||
"vscan" : { "minimum" : 0.0000, "maximum" : 0.0800 }
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"index" : 32,
|
|
||||||
"hscan" : { "minimum" : 0.9500, "maximum" : 1.0000 },
|
|
||||||
"vscan" : { "minimum" : 0.0000, "maximum" : 0.1429 }
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"index" : 33,
|
|
||||||
"hscan" : { "minimum" : 0.9500, "maximum" : 1.0000 },
|
|
||||||
"vscan" : { "minimum" : 0.1429, "maximum" : 0.2857 }
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"index" : 34,
|
|
||||||
"hscan" : { "minimum" : 0.9500, "maximum" : 1.0000 },
|
|
||||||
"vscan" : { "minimum" : 0.2857, "maximum" : 0.4286 }
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"index" : 35,
|
|
||||||
"hscan" : { "minimum" : 0.9500, "maximum" : 1.0000 },
|
|
||||||
"vscan" : { "minimum" : 0.4286, "maximum" : 0.5714 }
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"index" : 36,
|
|
||||||
"hscan" : { "minimum" : 0.9500, "maximum" : 1.0000 },
|
|
||||||
"vscan" : { "minimum" : 0.5714, "maximum" : 0.7143 }
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"index" : 37,
|
|
||||||
"hscan" : { "minimum" : 0.9500, "maximum" : 1.0000 },
|
|
||||||
"vscan" : { "minimum" : 0.7143, "maximum" : 0.8571 }
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"index" : 38,
|
|
||||||
"hscan" : { "minimum" : 0.9500, "maximum" : 1.0000 },
|
|
||||||
"vscan" : { "minimum" : 0.8571, "maximum" : 1.0000 }
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"index" : 39,
|
|
||||||
"hscan" : { "minimum" : 0.9375, "maximum" : 1.0000 },
|
|
||||||
"vscan" : { "minimum" : 0.9200, "maximum" : 1.0000 }
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"index" : 40,
|
|
||||||
"hscan" : { "minimum" : 0.8750, "maximum" : 0.9375 },
|
|
||||||
"vscan" : { "minimum" : 0.9200, "maximum" : 1.0000 }
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"index" : 41,
|
|
||||||
"hscan" : { "minimum" : 0.8125, "maximum" : 0.8750 },
|
|
||||||
"vscan" : { "minimum" : 0.9200, "maximum" : 1.0000 }
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"index" : 42,
|
|
||||||
"hscan" : { "minimum" : 0.7500, "maximum" : 0.8125 },
|
|
||||||
"vscan" : { "minimum" : 0.9200, "maximum" : 1.0000 }
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"index" : 43,
|
|
||||||
"hscan" : { "minimum" : 0.6875, "maximum" : 0.7500 },
|
|
||||||
"vscan" : { "minimum" : 0.9200, "maximum" : 1.0000 }
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"index" : 44,
|
|
||||||
"hscan" : { "minimum" : 0.6250, "maximum" : 0.6875 },
|
|
||||||
"vscan" : { "minimum" : 0.9200, "maximum" : 1.0000 }
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"index" : 45,
|
|
||||||
"hscan" : { "minimum" : 0.5625, "maximum" : 0.6250 },
|
|
||||||
"vscan" : { "minimum" : 0.9200, "maximum" : 1.0000 }
|
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
19
test/jsonchecks/COPYING
Normal file
19
test/jsonchecks/COPYING
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
Copyright (c) 2011 Julian Berman
|
||||||
|
|
||||||
|
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.
|
50
test/jsonchecks/checkeffects.py
Normal file
50
test/jsonchecks/checkeffects.py
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
import json, sys, glob
|
||||||
|
from os import path
|
||||||
|
from jsonschema import Draft3Validator
|
||||||
|
|
||||||
|
print("-- validate json effect files")
|
||||||
|
|
||||||
|
jsonFiles = sys.argv[1]
|
||||||
|
schemaFiles = sys.argv[2]
|
||||||
|
|
||||||
|
retval = 0
|
||||||
|
total = 0
|
||||||
|
errors = 0
|
||||||
|
with open("libsrc/effectengine/EffectDefinition.schema.json") as baseSchemaFile:
|
||||||
|
baseSchema = json.load(baseSchemaFile)
|
||||||
|
baseValidator = Draft3Validator(baseSchema)
|
||||||
|
for filename in glob.glob(jsonFiles+'/*.json'):
|
||||||
|
with open(filename) as f:
|
||||||
|
total += 1
|
||||||
|
msg = " check effect %s ... " % filename
|
||||||
|
try:
|
||||||
|
effect = json.load(f)
|
||||||
|
script = path.basename(effect['script'])
|
||||||
|
if not path.exists(jsonFiles+'/'+script):
|
||||||
|
raise ValueError('script file: '+script+' not found.')
|
||||||
|
|
||||||
|
schema = path.splitext(script)[0]+'.schema.json'
|
||||||
|
if not path.exists(jsonFiles+'/schema/'+schema):
|
||||||
|
raise ValueError('schema file: '+schema+' not found.')
|
||||||
|
schema = jsonFiles+'/schema/'+schema
|
||||||
|
|
||||||
|
# validate against schema
|
||||||
|
with open(schema) as s:
|
||||||
|
effectSchema = json.load(s)
|
||||||
|
Draft3Validator.check_schema(effectSchema)
|
||||||
|
validator = Draft3Validator(effectSchema)
|
||||||
|
baseValidator.validate(effect)
|
||||||
|
validator.validate(effect['args'])
|
||||||
|
|
||||||
|
#print(msg + "ok")
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
print(msg + 'error ('+str(e)+')')
|
||||||
|
errors += 1
|
||||||
|
retval = 1
|
||||||
|
|
||||||
|
|
||||||
|
print(" checked effect files: %s success: %s errors: %s" % (total,(total-errors),errors))
|
||||||
|
|
||||||
|
sys.exit(retval)
|
23
test/jsonchecks/checkjson.py
Normal file
23
test/jsonchecks/checkjson.py
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
import json, sys
|
||||||
|
|
||||||
|
print("-- validate json files")
|
||||||
|
|
||||||
|
retval = 0
|
||||||
|
total = 0
|
||||||
|
errors = 0
|
||||||
|
for filename in sys.argv[1:]:
|
||||||
|
with open(filename) as f:
|
||||||
|
total += 1
|
||||||
|
msg = " check json %s ... " % filename
|
||||||
|
try:
|
||||||
|
json.load(f)
|
||||||
|
#print(msg + "ok")
|
||||||
|
except ValueError as e:
|
||||||
|
print(msg + 'invalid')
|
||||||
|
retval = 1
|
||||||
|
errors += 1
|
||||||
|
|
||||||
|
print(" checked files: %s success: %s errors: %s" % (total,(total-errors),errors))
|
||||||
|
|
||||||
|
sys.exit(retval)
|
21
test/jsonchecks/checkschema.py
Normal file
21
test/jsonchecks/checkschema.py
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
import json, sys, glob
|
||||||
|
from os import path
|
||||||
|
from jsonschema import Draft3Validator
|
||||||
|
|
||||||
|
print('-- validate json file')
|
||||||
|
|
||||||
|
jsonFileName = sys.argv[1]
|
||||||
|
schemaFileName = sys.argv[2]
|
||||||
|
|
||||||
|
try:
|
||||||
|
with open(schemaFileName) as schemaFile:
|
||||||
|
with open(jsonFileName) as jsonFile:
|
||||||
|
j = json.load(jsonFile)
|
||||||
|
validator = Draft3Validator(json.load(schemaFile))
|
||||||
|
validator.validate(j)
|
||||||
|
except Exception as e:
|
||||||
|
print('validation error: '+jsonFileName + ' '+schemaFileName+' ('+str(e)+')')
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
sys.exit(0)
|
734
test/jsonchecks/jsonschema.py
Normal file
734
test/jsonchecks/jsonschema.py
Normal file
@ -0,0 +1,734 @@
|
|||||||
|
"""
|
||||||
|
An implementation of JSON Schema for Python
|
||||||
|
|
||||||
|
The main functionality is provided by the validator classes for each of the
|
||||||
|
supported JSON Schema versions.
|
||||||
|
|
||||||
|
Most commonly, the :function:`validate` function is the quickest way to simply
|
||||||
|
validate a given instance under a schema, and will create a validator for you.
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
from __future__ import division, unicode_literals
|
||||||
|
|
||||||
|
import collections
|
||||||
|
import itertools
|
||||||
|
import operator
|
||||||
|
import re
|
||||||
|
import sys
|
||||||
|
import warnings
|
||||||
|
|
||||||
|
|
||||||
|
__version__ = "0.7"
|
||||||
|
|
||||||
|
FLOAT_TOLERANCE = 10 ** -15
|
||||||
|
PY3 = sys.version_info[0] >= 3
|
||||||
|
|
||||||
|
if PY3:
|
||||||
|
basestring = unicode = str
|
||||||
|
iteritems = operator.methodcaller("items")
|
||||||
|
from urllib.parse import unquote
|
||||||
|
else:
|
||||||
|
from itertools import izip as zip
|
||||||
|
iteritems = operator.methodcaller("iteritems")
|
||||||
|
from urllib import unquote
|
||||||
|
|
||||||
|
|
||||||
|
class UnknownType(Exception):
|
||||||
|
"""
|
||||||
|
An unknown type was given.
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
class InvalidRef(Exception):
|
||||||
|
"""
|
||||||
|
An invalid reference was given.
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
class SchemaError(Exception):
|
||||||
|
"""
|
||||||
|
The provided schema is malformed.
|
||||||
|
|
||||||
|
The same attributes exist for ``SchemaError``s as for ``ValidationError``s.
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
validator = None
|
||||||
|
|
||||||
|
def __init__(self, message):
|
||||||
|
super(SchemaError, self).__init__(message)
|
||||||
|
self.message = message
|
||||||
|
self.path = []
|
||||||
|
|
||||||
|
|
||||||
|
class ValidationError(Exception):
|
||||||
|
"""
|
||||||
|
The instance didn't properly validate with the provided schema.
|
||||||
|
|
||||||
|
Relevant attributes are:
|
||||||
|
* ``message`` : a human readable message explaining the error
|
||||||
|
* ``path`` : a list containing the path to the offending element (or []
|
||||||
|
if the error happened globally) in *reverse* order (i.e.
|
||||||
|
deepest index first).
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
# the failing validator will be set externally at whatever recursion level
|
||||||
|
# is immediately above the validation failure
|
||||||
|
validator = None
|
||||||
|
|
||||||
|
def __init__(self, message):
|
||||||
|
super(ValidationError, self).__init__(message)
|
||||||
|
self.message = message
|
||||||
|
|
||||||
|
# Any validator that recurses must append to the ValidationError's
|
||||||
|
# path (e.g., properties and items)
|
||||||
|
self.path = []
|
||||||
|
|
||||||
|
|
||||||
|
class Draft3Validator(object):
|
||||||
|
"""
|
||||||
|
A validator for JSON Schema draft 3.
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
DEFAULT_TYPES = {
|
||||||
|
"array" : list, "boolean" : bool, "integer" : int, "null" : type(None),
|
||||||
|
"number" : (int, float), "object" : dict, "string" : basestring,
|
||||||
|
}
|
||||||
|
|
||||||
|
def __init__(self, schema, types=()):
|
||||||
|
"""
|
||||||
|
Initialize a validator.
|
||||||
|
|
||||||
|
``schema`` should be a *valid* JSON Schema object already converted to
|
||||||
|
a native Python object (typically a dict via ``json.load``).
|
||||||
|
|
||||||
|
``types`` is a mapping (or iterable of 2-tuples) containing additional
|
||||||
|
types or alternate types to verify via the 'type' property. For
|
||||||
|
instance, the default types for the 'number' JSON Schema type are
|
||||||
|
``int`` and ``float``. To override this behavior (e.g. for also
|
||||||
|
allowing ``decimal.Decimal``), pass ``types={"number" : (int, float,
|
||||||
|
decimal.Decimal)} *including* the default types if so desired, which
|
||||||
|
are fairly obvious but can be accessed via the ``DEFAULT_TYPES``
|
||||||
|
attribute on this class if necessary.
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
self._types = dict(self.DEFAULT_TYPES)
|
||||||
|
self._types.update(types)
|
||||||
|
self._types["any"] = tuple(self._types.values())
|
||||||
|
|
||||||
|
self.schema = schema
|
||||||
|
|
||||||
|
def is_type(self, instance, type):
|
||||||
|
"""
|
||||||
|
Check if an ``instance`` is of the provided (JSON Schema) ``type``.
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
if type not in self._types:
|
||||||
|
raise UnknownType(type)
|
||||||
|
type = self._types[type]
|
||||||
|
|
||||||
|
# bool inherits from int, so ensure bools aren't reported as integers
|
||||||
|
if isinstance(instance, bool):
|
||||||
|
type = _flatten(type)
|
||||||
|
if int in type and bool not in type:
|
||||||
|
return False
|
||||||
|
return isinstance(instance, type)
|
||||||
|
|
||||||
|
def is_valid(self, instance, _schema=None):
|
||||||
|
"""
|
||||||
|
Check if the ``instance`` is valid under the current schema.
|
||||||
|
|
||||||
|
Returns a bool indicating whether validation succeeded.
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
error = next(self.iter_errors(instance, _schema), None)
|
||||||
|
return error is None
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def check_schema(cls, schema):
|
||||||
|
"""
|
||||||
|
Validate a ``schema`` against the meta-schema to see if it is valid.
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
for error in cls(cls.META_SCHEMA).iter_errors(schema):
|
||||||
|
s = SchemaError(error.message)
|
||||||
|
s.path = error.path
|
||||||
|
s.validator = error.validator
|
||||||
|
# I think we're safer raising these always, not yielding them
|
||||||
|
raise s
|
||||||
|
|
||||||
|
def iter_errors(self, instance, _schema=None):
|
||||||
|
"""
|
||||||
|
Lazily yield each of the errors in the given ``instance``.
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
if _schema is None:
|
||||||
|
_schema = self.schema
|
||||||
|
|
||||||
|
for k, v in iteritems(_schema):
|
||||||
|
validator = getattr(self, "validate_%s" % (k.lstrip("$"),), None)
|
||||||
|
|
||||||
|
if validator is None:
|
||||||
|
continue
|
||||||
|
|
||||||
|
errors = validator(v, instance, _schema) or ()
|
||||||
|
for error in errors:
|
||||||
|
# if the validator hasn't already been set (due to recursion)
|
||||||
|
# make sure to set it
|
||||||
|
error.validator = error.validator or k
|
||||||
|
yield error
|
||||||
|
|
||||||
|
def validate(self, *args, **kwargs):
|
||||||
|
"""
|
||||||
|
Validate an ``instance`` under the given ``schema``.
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
for error in self.iter_errors(*args, **kwargs):
|
||||||
|
raise error
|
||||||
|
|
||||||
|
def validate_type(self, types, instance, schema):
|
||||||
|
types = _list(types)
|
||||||
|
|
||||||
|
for type in types:
|
||||||
|
# Ouch. Brain hurts. Two paths here, either we have a schema, then
|
||||||
|
# check if the instance is valid under it
|
||||||
|
if ((
|
||||||
|
self.is_type(type, "object") and
|
||||||
|
self.is_valid(instance, type)
|
||||||
|
|
||||||
|
# Or we have a type as a string, just check if the instance is that
|
||||||
|
# type. Also, HACK: we can reach the `or` here if skip_types is
|
||||||
|
# something other than error. If so, bail out.
|
||||||
|
|
||||||
|
) or (
|
||||||
|
self.is_type(type, "string") and
|
||||||
|
(self.is_type(instance, type) or type not in self._types)
|
||||||
|
)):
|
||||||
|
return
|
||||||
|
else:
|
||||||
|
yield ValidationError(_types_msg(instance, types))
|
||||||
|
|
||||||
|
def validate_properties(self, properties, instance, schema):
|
||||||
|
if not self.is_type(instance, "object"):
|
||||||
|
return
|
||||||
|
|
||||||
|
for property, subschema in iteritems(properties):
|
||||||
|
if property in instance:
|
||||||
|
for error in self.iter_errors(instance[property], subschema):
|
||||||
|
error.path.append(property)
|
||||||
|
yield error
|
||||||
|
elif subschema.get("required", False):
|
||||||
|
error = ValidationError(
|
||||||
|
"%r is a required property" % (property,)
|
||||||
|
)
|
||||||
|
error.path.append(property)
|
||||||
|
error.validator = "required"
|
||||||
|
yield error
|
||||||
|
|
||||||
|
def validate_patternProperties(self, patternProperties, instance, schema):
|
||||||
|
for pattern, subschema in iteritems(patternProperties):
|
||||||
|
for k, v in iteritems(instance):
|
||||||
|
if re.match(pattern, k):
|
||||||
|
for error in self.iter_errors(v, subschema):
|
||||||
|
yield error
|
||||||
|
|
||||||
|
def validate_additionalProperties(self, aP, instance, schema):
|
||||||
|
if not self.is_type(instance, "object"):
|
||||||
|
return
|
||||||
|
|
||||||
|
extras = set(_find_additional_properties(instance, schema))
|
||||||
|
|
||||||
|
if self.is_type(aP, "object"):
|
||||||
|
for extra in extras:
|
||||||
|
for error in self.iter_errors(instance[extra], aP):
|
||||||
|
yield error
|
||||||
|
elif not aP and extras:
|
||||||
|
error = "Additional properties are not allowed (%s %s unexpected)"
|
||||||
|
yield ValidationError(error % _extras_msg(extras))
|
||||||
|
|
||||||
|
def validate_dependencies(self, dependencies, instance, schema):
|
||||||
|
if not self.is_type(instance, "object"):
|
||||||
|
return
|
||||||
|
|
||||||
|
for property, dependency in iteritems(dependencies):
|
||||||
|
if property not in instance:
|
||||||
|
continue
|
||||||
|
|
||||||
|
if self.is_type(dependency, "object"):
|
||||||
|
for error in self.iter_errors(instance, dependency):
|
||||||
|
yield error
|
||||||
|
else:
|
||||||
|
dependencies = _list(dependency)
|
||||||
|
for dependency in dependencies:
|
||||||
|
if dependency not in instance:
|
||||||
|
yield ValidationError(
|
||||||
|
"%r is a dependency of %r" % (dependency, property)
|
||||||
|
)
|
||||||
|
|
||||||
|
def validate_items(self, items, instance, schema):
|
||||||
|
if not self.is_type(instance, "array"):
|
||||||
|
return
|
||||||
|
|
||||||
|
if self.is_type(items, "object"):
|
||||||
|
for index, item in enumerate(instance):
|
||||||
|
for error in self.iter_errors(item, items):
|
||||||
|
error.path.append(index)
|
||||||
|
yield error
|
||||||
|
else:
|
||||||
|
for (index, item), subschema in zip(enumerate(instance), items):
|
||||||
|
for error in self.iter_errors(item, subschema):
|
||||||
|
error.path.append(index)
|
||||||
|
yield error
|
||||||
|
|
||||||
|
def validate_additionalItems(self, aI, instance, schema):
|
||||||
|
if not self.is_type(instance, "array"):
|
||||||
|
return
|
||||||
|
if not self.is_type(schema.get("items"), "array"):
|
||||||
|
return
|
||||||
|
|
||||||
|
if self.is_type(aI, "object"):
|
||||||
|
for item in instance[len(schema):]:
|
||||||
|
for error in self.iter_errors(item, aI):
|
||||||
|
yield error
|
||||||
|
elif not aI and len(instance) > len(schema.get("items", [])):
|
||||||
|
error = "Additional items are not allowed (%s %s unexpected)"
|
||||||
|
yield ValidationError(
|
||||||
|
error % _extras_msg(instance[len(schema.get("items", [])):])
|
||||||
|
)
|
||||||
|
|
||||||
|
def validate_minimum(self, minimum, instance, schema):
|
||||||
|
if not self.is_type(instance, "number"):
|
||||||
|
return
|
||||||
|
|
||||||
|
instance = float(instance)
|
||||||
|
if schema.get("exclusiveMinimum", False):
|
||||||
|
failed = instance <= minimum
|
||||||
|
cmp = "less than or equal to"
|
||||||
|
else:
|
||||||
|
failed = instance < minimum
|
||||||
|
cmp = "less than"
|
||||||
|
|
||||||
|
if failed:
|
||||||
|
yield ValidationError(
|
||||||
|
"%r is %s the minimum of %r" % (instance, cmp, minimum)
|
||||||
|
)
|
||||||
|
|
||||||
|
def validate_maximum(self, maximum, instance, schema):
|
||||||
|
if not self.is_type(instance, "number"):
|
||||||
|
return
|
||||||
|
|
||||||
|
instance = float(instance)
|
||||||
|
if schema.get("exclusiveMaximum", False):
|
||||||
|
failed = instance >= maximum
|
||||||
|
cmp = "greater than or equal to"
|
||||||
|
else:
|
||||||
|
failed = instance > maximum
|
||||||
|
cmp = "greater than"
|
||||||
|
|
||||||
|
if failed:
|
||||||
|
yield ValidationError(
|
||||||
|
"%r is %s the maximum of %r" % (instance, cmp, maximum)
|
||||||
|
)
|
||||||
|
|
||||||
|
def validate_minItems(self, mI, instance, schema):
|
||||||
|
if self.is_type(instance, "array") and len(instance) < mI:
|
||||||
|
yield ValidationError("%r is too short" % (instance,))
|
||||||
|
|
||||||
|
def validate_maxItems(self, mI, instance, schema):
|
||||||
|
if self.is_type(instance, "array") and len(instance) > mI:
|
||||||
|
yield ValidationError("%r is too long" % (instance,))
|
||||||
|
|
||||||
|
def validate_uniqueItems(self, uI, instance, schema):
|
||||||
|
if uI and self.is_type(instance, "array") and not _uniq(instance):
|
||||||
|
yield ValidationError("%r has non-unique elements" % instance)
|
||||||
|
|
||||||
|
def validate_pattern(self, patrn, instance, schema):
|
||||||
|
if self.is_type(instance, "string") and not re.match(patrn, instance):
|
||||||
|
yield ValidationError("%r does not match %r" % (instance, patrn))
|
||||||
|
|
||||||
|
def validate_minLength(self, mL, instance, schema):
|
||||||
|
if self.is_type(instance, "string") and len(instance) < mL:
|
||||||
|
yield ValidationError("%r is too short" % (instance,))
|
||||||
|
|
||||||
|
def validate_maxLength(self, mL, instance, schema):
|
||||||
|
if self.is_type(instance, "string") and len(instance) > mL:
|
||||||
|
yield ValidationError("%r is too long" % (instance,))
|
||||||
|
|
||||||
|
def validate_enum(self, enums, instance, schema):
|
||||||
|
if instance not in enums:
|
||||||
|
yield ValidationError("%r is not one of %r" % (instance, enums))
|
||||||
|
|
||||||
|
def validate_divisibleBy(self, dB, instance, schema):
|
||||||
|
if not self.is_type(instance, "number"):
|
||||||
|
return
|
||||||
|
|
||||||
|
if isinstance(dB, float):
|
||||||
|
mod = instance % dB
|
||||||
|
failed = (mod > FLOAT_TOLERANCE) and (dB - mod) > FLOAT_TOLERANCE
|
||||||
|
else:
|
||||||
|
failed = instance % dB
|
||||||
|
|
||||||
|
if failed:
|
||||||
|
yield ValidationError("%r is not divisible by %r" % (instance, dB))
|
||||||
|
|
||||||
|
def validate_disallow(self, disallow, instance, schema):
|
||||||
|
for disallowed in _list(disallow):
|
||||||
|
if self.is_valid(instance, {"type" : [disallowed]}):
|
||||||
|
yield ValidationError(
|
||||||
|
"%r is disallowed for %r" % (disallowed, instance)
|
||||||
|
)
|
||||||
|
|
||||||
|
def validate_extends(self, extends, instance, schema):
|
||||||
|
if self.is_type(extends, "object"):
|
||||||
|
extends = [extends]
|
||||||
|
for subschema in extends:
|
||||||
|
for error in self.iter_errors(instance, subschema):
|
||||||
|
yield error
|
||||||
|
|
||||||
|
def validate_ref(self, ref, instance, schema):
|
||||||
|
if ref != "#" and not ref.startswith("#/"):
|
||||||
|
warnings.warn("jsonschema only supports json-pointer $refs")
|
||||||
|
return
|
||||||
|
|
||||||
|
resolved = resolve_json_pointer(self.schema, ref)
|
||||||
|
for error in self.iter_errors(instance, resolved):
|
||||||
|
yield error
|
||||||
|
|
||||||
|
|
||||||
|
Draft3Validator.META_SCHEMA = {
|
||||||
|
"$schema" : "http://json-schema.org/draft-03/schema#",
|
||||||
|
"id" : "http://json-schema.org/draft-03/schema#",
|
||||||
|
"type" : "object",
|
||||||
|
|
||||||
|
"properties" : {
|
||||||
|
"type" : {
|
||||||
|
"type" : ["string", "array"],
|
||||||
|
"items" : {"type" : ["string", {"$ref" : "#"}]},
|
||||||
|
"uniqueItems" : True,
|
||||||
|
"default" : "any"
|
||||||
|
},
|
||||||
|
"properties" : {
|
||||||
|
"type" : "object",
|
||||||
|
"additionalProperties" : {"$ref" : "#", "type": "object"},
|
||||||
|
"default" : {}
|
||||||
|
},
|
||||||
|
"patternProperties" : {
|
||||||
|
"type" : "object",
|
||||||
|
"additionalProperties" : {"$ref" : "#"},
|
||||||
|
"default" : {}
|
||||||
|
},
|
||||||
|
"additionalProperties" : {
|
||||||
|
"type" : [{"$ref" : "#"}, "boolean"], "default" : {}
|
||||||
|
},
|
||||||
|
"items" : {
|
||||||
|
"type" : [{"$ref" : "#"}, "array"],
|
||||||
|
"items" : {"$ref" : "#"},
|
||||||
|
"default" : {}
|
||||||
|
},
|
||||||
|
"additionalItems" : {
|
||||||
|
"type" : [{"$ref" : "#"}, "boolean"], "default" : {}
|
||||||
|
},
|
||||||
|
"required" : {"type" : "boolean", "default" : False},
|
||||||
|
"dependencies" : {
|
||||||
|
"type" : ["string", "array", "object"],
|
||||||
|
"additionalProperties" : {
|
||||||
|
"type" : ["string", "array", {"$ref" : "#"}],
|
||||||
|
"items" : {"type" : "string"}
|
||||||
|
},
|
||||||
|
"default" : {}
|
||||||
|
},
|
||||||
|
"minimum" : {"type" : "number"},
|
||||||
|
"maximum" : {"type" : "number"},
|
||||||
|
"exclusiveMinimum" : {"type" : "boolean", "default" : False},
|
||||||
|
"exclusiveMaximum" : {"type" : "boolean", "default" : False},
|
||||||
|
"minItems" : {"type" : "integer", "minimum" : 0, "default" : 0},
|
||||||
|
"maxItems" : {"type" : "integer", "minimum" : 0},
|
||||||
|
"uniqueItems" : {"type" : "boolean", "default" : False},
|
||||||
|
"pattern" : {"type" : "string", "format" : "regex"},
|
||||||
|
"minLength" : {"type" : "integer", "minimum" : 0, "default" : 0},
|
||||||
|
"maxLength" : {"type" : "integer"},
|
||||||
|
"enum" : {"type" : "array", "minItems" : 1, "uniqueItems" : True},
|
||||||
|
"default" : {"type" : "any"},
|
||||||
|
"title" : {"type" : "string"},
|
||||||
|
"description" : {"type" : "string"},
|
||||||
|
"format" : {"type" : "string"},
|
||||||
|
"maxDecimal" : {"type" : "number", "minimum" : 0},
|
||||||
|
"divisibleBy" : {
|
||||||
|
"type" : "number",
|
||||||
|
"minimum" : 0,
|
||||||
|
"exclusiveMinimum" : True,
|
||||||
|
"default" : 1
|
||||||
|
},
|
||||||
|
"disallow" : {
|
||||||
|
"type" : ["string", "array"],
|
||||||
|
"items" : {"type" : ["string", {"$ref" : "#"}]},
|
||||||
|
"uniqueItems" : True
|
||||||
|
},
|
||||||
|
"extends" : {
|
||||||
|
"type" : [{"$ref" : "#"}, "array"],
|
||||||
|
"items" : {"$ref" : "#"},
|
||||||
|
"default" : {}
|
||||||
|
},
|
||||||
|
"id" : {"type" : "string", "format" : "uri"},
|
||||||
|
"$ref" : {"type" : "string", "format" : "uri"},
|
||||||
|
"$schema" : {"type" : "string", "format" : "uri"},
|
||||||
|
},
|
||||||
|
"dependencies" : {
|
||||||
|
"exclusiveMinimum" : "minimum", "exclusiveMaximum" : "maximum"
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
class Validator(Draft3Validator):
|
||||||
|
"""
|
||||||
|
Deprecated: Use :class:`Draft3Validator` instead.
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
def __init__(
|
||||||
|
self, version=None, unknown_type="skip", unknown_property="skip",
|
||||||
|
*args, **kwargs
|
||||||
|
):
|
||||||
|
super(Validator, self).__init__({}, *args, **kwargs)
|
||||||
|
warnings.warn(
|
||||||
|
"Validator is deprecated and will be removed. "
|
||||||
|
"Use Draft3Validator instead.",
|
||||||
|
DeprecationWarning, stacklevel=2,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class ErrorTree(object):
|
||||||
|
"""
|
||||||
|
ErrorTrees make it easier to check which validations failed.
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
def __init__(self, errors=()):
|
||||||
|
self.errors = {}
|
||||||
|
self._contents = collections.defaultdict(self.__class__)
|
||||||
|
|
||||||
|
for error in errors:
|
||||||
|
container = self
|
||||||
|
for element in reversed(error.path):
|
||||||
|
container = container[element]
|
||||||
|
container.errors[error.validator] = error
|
||||||
|
|
||||||
|
def __contains__(self, k):
|
||||||
|
return k in self._contents
|
||||||
|
|
||||||
|
def __getitem__(self, k):
|
||||||
|
return self._contents[k]
|
||||||
|
|
||||||
|
def __setitem__(self, k, v):
|
||||||
|
self._contents[k] = v
|
||||||
|
|
||||||
|
def __iter__(self):
|
||||||
|
return iter(self._contents)
|
||||||
|
|
||||||
|
def __len__(self):
|
||||||
|
child_errors = sum(len(tree) for _, tree in iteritems(self._contents))
|
||||||
|
return len(self.errors) + child_errors
|
||||||
|
|
||||||
|
def __repr__(self):
|
||||||
|
return "<%s (%s errors)>" % (self.__class__.__name__, len(self))
|
||||||
|
|
||||||
|
|
||||||
|
def resolve_json_pointer(schema, ref):
|
||||||
|
"""
|
||||||
|
Resolve a local reference ``ref`` within the given root ``schema``.
|
||||||
|
|
||||||
|
``ref`` should be a local ref whose ``#`` is still present.
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
if ref == "#":
|
||||||
|
return schema
|
||||||
|
|
||||||
|
parts = ref.lstrip("#/").split("/")
|
||||||
|
|
||||||
|
parts = map(unquote, parts)
|
||||||
|
parts = [part.replace('~1', '/').replace('~0', '~') for part in parts]
|
||||||
|
|
||||||
|
try:
|
||||||
|
for part in parts:
|
||||||
|
schema = schema[part]
|
||||||
|
except KeyError:
|
||||||
|
raise InvalidRef("Unresolvable json-pointer %r" % ref)
|
||||||
|
else:
|
||||||
|
return schema
|
||||||
|
|
||||||
|
|
||||||
|
def _find_additional_properties(instance, schema):
|
||||||
|
"""
|
||||||
|
Return the set of additional properties for the given ``instance``.
|
||||||
|
|
||||||
|
Weeds out properties that should have been validated by ``properties`` and
|
||||||
|
/ or ``patternProperties``.
|
||||||
|
|
||||||
|
Assumes ``instance`` is dict-like already.
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
properties = schema.get("properties", {})
|
||||||
|
patterns = "|".join(schema.get("patternProperties", {}))
|
||||||
|
for property in instance:
|
||||||
|
if property not in properties:
|
||||||
|
if patterns and re.search(patterns, property):
|
||||||
|
continue
|
||||||
|
yield property
|
||||||
|
|
||||||
|
|
||||||
|
def _extras_msg(extras):
|
||||||
|
"""
|
||||||
|
Create an error message for extra items or properties.
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
if len(extras) == 1:
|
||||||
|
verb = "was"
|
||||||
|
else:
|
||||||
|
verb = "were"
|
||||||
|
return ", ".join(repr(extra) for extra in extras), verb
|
||||||
|
|
||||||
|
|
||||||
|
def _types_msg(instance, types):
|
||||||
|
"""
|
||||||
|
Create an error message for a failure to match the given types.
|
||||||
|
|
||||||
|
If the ``instance`` is an object and contains a ``name`` property, it will
|
||||||
|
be considered to be a description of that object and used as its type.
|
||||||
|
|
||||||
|
Otherwise the message is simply the reprs of the given ``types``.
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
reprs = []
|
||||||
|
for type in types:
|
||||||
|
try:
|
||||||
|
reprs.append(repr(type["name"]))
|
||||||
|
except Exception:
|
||||||
|
reprs.append(repr(type))
|
||||||
|
return "%r is not of type %s" % (instance, ", ".join(reprs))
|
||||||
|
|
||||||
|
|
||||||
|
def _flatten(suitable_for_isinstance):
|
||||||
|
"""
|
||||||
|
isinstance() can accept a bunch of really annoying different types:
|
||||||
|
* a single type
|
||||||
|
* a tuple of types
|
||||||
|
* an arbitrary nested tree of tuples
|
||||||
|
|
||||||
|
Return a flattened tuple of the given argument.
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
types = set()
|
||||||
|
|
||||||
|
if not isinstance(suitable_for_isinstance, tuple):
|
||||||
|
suitable_for_isinstance = (suitable_for_isinstance,)
|
||||||
|
for thing in suitable_for_isinstance:
|
||||||
|
if isinstance(thing, tuple):
|
||||||
|
types.update(_flatten(thing))
|
||||||
|
else:
|
||||||
|
types.add(thing)
|
||||||
|
return tuple(types)
|
||||||
|
|
||||||
|
|
||||||
|
def _list(thing):
|
||||||
|
"""
|
||||||
|
Wrap ``thing`` in a list if it's a single str.
|
||||||
|
|
||||||
|
Otherwise, return it unchanged.
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
if isinstance(thing, basestring):
|
||||||
|
return [thing]
|
||||||
|
return thing
|
||||||
|
|
||||||
|
|
||||||
|
def _delist(thing):
|
||||||
|
"""
|
||||||
|
Unwrap ``thing`` to a single element if its a single str in a list.
|
||||||
|
|
||||||
|
Otherwise, return it unchanged.
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
if (
|
||||||
|
isinstance(thing, list) and
|
||||||
|
len(thing) == 1
|
||||||
|
and isinstance(thing[0], basestring)
|
||||||
|
):
|
||||||
|
return thing[0]
|
||||||
|
return thing
|
||||||
|
|
||||||
|
|
||||||
|
def _uniq(container):
|
||||||
|
"""
|
||||||
|
Check if all of a container's elements are unique.
|
||||||
|
|
||||||
|
Successively tries first to rely that the elements are hashable, then
|
||||||
|
falls back on them being sortable, and finally falls back on brute
|
||||||
|
force.
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
try:
|
||||||
|
return len(set(container)) == len(container)
|
||||||
|
except TypeError:
|
||||||
|
try:
|
||||||
|
sort = sorted(container)
|
||||||
|
sliced = itertools.islice(container, 1, None)
|
||||||
|
for i, j in zip(container, sliced):
|
||||||
|
if i == j:
|
||||||
|
return False
|
||||||
|
except (NotImplementedError, TypeError):
|
||||||
|
seen = []
|
||||||
|
for e in container:
|
||||||
|
if e in seen:
|
||||||
|
return False
|
||||||
|
seen.append(e)
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
|
def validate(instance, schema, cls=Draft3Validator, *args, **kwargs):
|
||||||
|
"""
|
||||||
|
Validate an ``instance`` under the given ``schema``.
|
||||||
|
|
||||||
|
First verifies that the provided schema is itself valid, since not doing so
|
||||||
|
can lead to less obvious failures when validating. If you know it is or
|
||||||
|
don't care, use ``YourValidator(schema).validate(instance)`` directly
|
||||||
|
instead (e.g. ``Draft3Validator``).
|
||||||
|
|
||||||
|
``cls`` is a validator class that will be used to validate the instance.
|
||||||
|
By default this is a draft 3 validator. Any other provided positional and
|
||||||
|
keyword arguments will be provided to this class when constructing a
|
||||||
|
validator.
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
meta_validate = kwargs.pop("meta_validate", None)
|
||||||
|
|
||||||
|
if meta_validate is not None:
|
||||||
|
warnings.warn(
|
||||||
|
"meta_validate is deprecated and will be removed. If you do not "
|
||||||
|
"want to validate a schema, use Draft3Validator.validate instead.",
|
||||||
|
DeprecationWarning, stacklevel=2,
|
||||||
|
)
|
||||||
|
|
||||||
|
if meta_validate is not False: # yes this is needed since True was default
|
||||||
|
cls.check_schema(schema)
|
||||||
|
cls(schema, *args, **kwargs).validate(instance)
|
Loading…
Reference in New Issue
Block a user