Skip to content

Commit

Permalink
Python Cluster Object - Field Defaults (#12381)
Browse files Browse the repository at this point in the history
* Python Cluster Object - Field Defaults

This initializes the various fields in a cluster object to type-specific
default values. This correclty handles nullable and optional types as
well.

* Missed a couple of places...

* Re-run codegen

* Re-gen Python cluster objects

* Restyle after regen

* Remove Objects.py from restyle

* Completely disable auto restyle for generated pyhon files

Co-authored-by: Andrei Litvin <[email protected]>
  • Loading branch information
2 people authored and pull[bot] committed Nov 14, 2023
1 parent 6243ed3 commit 1030398
Show file tree
Hide file tree
Showing 6 changed files with 8,511 additions and 8,958 deletions.
2 changes: 2 additions & 0 deletions .restyled.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,8 @@ exclude:
- "third_party/nanopb/repo/**/*"
- "src/android/CHIPTool/gradlew" # gradle wrapper generated file
- "third_party/android_deps/gradlew" # gradle wrapper generated file
- "src/controller/python/chip/clusters/Objects.py" # generated file, no point to restyle
- "src/controller/python/chip/clusters/CHIPClusters.py" # generated file, no point to restyle


changed_paths:
Expand Down
18 changes: 0 additions & 18 deletions scripts/tools/zap/generate.py
Original file line number Diff line number Diff line change
Expand Up @@ -146,23 +146,6 @@ def runJavaPrettifier(templates_file, output_dir):
print('google-java-format error:', err)


def runPythonPrettifier(templates_file, output_dir):
try:
jsonData = json.loads(Path(templates_file).read_text())
outputs = [(os.path.join(output_dir, template['output']))
for template in jsonData['templates']]
pyOutputs = list(
filter(lambda filepath: os.path.splitext(filepath)[1] == ".py", outputs))

if not pyOutputs:
return
args = ['autopep8', '--in-place']
args.extend(pyOutputs)
subprocess.check_call(args)
except Exception as err:
print('autopep8 error:', err)


def main():
checkPythonVersion()

Expand All @@ -172,7 +155,6 @@ def main():
prettifiers = [
runClangPrettifier,
runJavaPrettifier,
runPythonPrettifier,
]

for prettifier in prettifiers:
Expand Down
81 changes: 81 additions & 0 deletions src/app/zap-templates/templates/app/helper.js
Original file line number Diff line number Diff line change
Expand Up @@ -516,6 +516,86 @@ function zapTypeToPythonClusterObjectType(type, options)
return _zapTypeToPythonClusterObjectType.call(this, type, options)
}

async function _getPythonFieldDefault(type, options)
{
async function fn(pkgId)
{
const ns = options.hash.ns;
const typeChecker = async (method) => zclHelper[method](this.global.db, type, pkgId).then(zclType => zclType != 'unknown');

if (await typeChecker('isEnum')) {
return '0';
}

if (await typeChecker('isBitmap')) {
return '0';
}

if (await typeChecker('isStruct')) {
return 'field(default_factory=lambda: ' + ns + '.Structs.' + type + '())';
}

if (StringHelper.isCharString(type)) {
return '""';
}

if (StringHelper.isOctetString(type)) {
return 'b""';
}

if ([ 'single', 'double' ].includes(type.toLowerCase())) {
return '0.0';
}

if (type.toLowerCase() == 'boolean') {
return 'False'
}

// #10748: asUnderlyingZclType will emit wrong types for int{48|56|64}(u), so we process all int values here.
if (type.toLowerCase().match(/^int\d+$/)) {
return '0'
}

if (type.toLowerCase().match(/^int\d+u$/)) {
return '0'
}

resolvedType = await zclHelper.asUnderlyingZclType.call({ global : this.global }, type, options);
{
basicType = ChipTypesHelper.asBasicType(resolvedType);
if (basicType.match(/^int\d+_t$/)) {
return '0'
}
if (basicType.match(/^uint\d+_t$/)) {
return '0'
}
}
}

let promise = templateUtil.ensureZclPackageId(this).then(fn.bind(this));
if ((this.isList || this.isArray || this.entryType) && !options.hash.forceNotList) {
promise = promise.then(typeStr => `field(default_factory=lambda: [])`);
}

const isNull = (this.isNullable && !options.hash.forceNotNullable);
const isOptional = (this.isOptional && !options.hash.forceNotOptional);

if (isNull && isOptional) {
promise = promise.then(typeStr => `None`);
} else if (isNull) {
promise = promise.then(typeStr => `NullValue`);
} else if (isOptional) {
promise = promise.then(typeStr => `None`);
}

return templateUtil.templatePromise(this.global, promise)
}

function getPythonFieldDefault(type, options)
{
return _getPythonFieldDefault.call(this, type, options)
}

async function getResponseCommandName(responseRef, options)
{
let pkgId = await templateUtil.ensureZclPackageId(this);
Expand Down Expand Up @@ -620,3 +700,4 @@ exports.zapTypeToDecodableClusterObjectType = zapTypeToDecodableClusterObjectTyp
exports.zapTypeToPythonClusterObjectType = zapTypeToPythonClusterObjectType;
exports.getResponseCommandName = getResponseCommandName;
exports.isWeaklyTypedEnum = isWeaklyTypedEnum;
exports.getPythonFieldDefault = getPythonFieldDefault;
Loading

0 comments on commit 1030398

Please sign in to comment.