Skip to content

Commit fecffd0

Browse files
committed
Fix pylint for bink 0.7.1
1 parent fc6ce10 commit fecffd0

8 files changed

Lines changed: 549 additions & 142 deletions

File tree

AGENTS.md

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
# Contribution checks
2+
3+
For every change to Python code, do not consider the task complete until both
4+
commands pass from the repository root:
5+
6+
```sh
7+
pylint $(git ls-files 'bink/*.py')
8+
python -m unittest discover -v
9+
```
10+
11+
Fix pylint findings in the code; do not silence them with broad disables or
12+
configuration changes unless the warning is demonstrably inapplicable.
13+
14+
Do not create, update, or publish a release while either check fails. Run the
15+
same checks again immediately before committing or handing off a release.

bink/__init__.py

Lines changed: 19 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,23 @@
11
"""Python bindings for the Blade Ink C API."""
22

3-
from ._ffi import (BINK_ERROR_ERROR, BINK_ERROR_WARNING, BINK_FAIL,
4-
BINK_FAIL_INVALID_ARGUMENT, BINK_FAIL_INVALID_UTF8,
5-
BINK_FAIL_NUL_BYTE, BINK_FAIL_NULL_POINTER,
6-
BINK_FAIL_PANIC, BINK_OK, BINK_VALUE_BOOL,
7-
BINK_VALUE_DIVERT_TARGET, BINK_VALUE_FLOAT, BINK_VALUE_INT,
8-
BINK_VALUE_LIST, BINK_VALUE_STRING,
9-
BINK_VALUE_VARIABLE_POINTER, LIB)
3+
from ._ffi import (
4+
BINK_ERROR_ERROR,
5+
BINK_ERROR_WARNING,
6+
BINK_FAIL,
7+
BINK_FAIL_INVALID_ARGUMENT,
8+
BINK_FAIL_INVALID_UTF8,
9+
BINK_FAIL_NUL_BYTE,
10+
BINK_FAIL_NULL_POINTER,
11+
BINK_FAIL_PANIC,
12+
BINK_OK,
13+
BINK_VALUE_BOOL,
14+
BINK_VALUE_DIVERT_TARGET,
15+
BINK_VALUE_FLOAT,
16+
BINK_VALUE_INT,
17+
BINK_VALUE_LIST,
18+
BINK_VALUE_STRING,
19+
BINK_VALUE_VARIABLE_POINTER,
20+
LIB,
21+
)
1022

1123
__all__ = [name for name in globals() if name.startswith("BINK_")] + ["LIB"]

bink/_ffi.py

Lines changed: 88 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,29 @@
11
"""Low-level ctypes declarations shared by the public wrappers."""
2+
23
import ctypes
34
import ctypes.util
45
import os
56
import platform
67

7-
BINK_OK, BINK_FAIL, BINK_FAIL_NULL_POINTER, BINK_FAIL_INVALID_UTF8, BINK_FAIL_NUL_BYTE, BINK_FAIL_PANIC, BINK_FAIL_INVALID_ARGUMENT = range(7)
8+
(
9+
BINK_OK,
10+
BINK_FAIL,
11+
BINK_FAIL_NULL_POINTER,
12+
BINK_FAIL_INVALID_UTF8,
13+
BINK_FAIL_NUL_BYTE,
14+
BINK_FAIL_PANIC,
15+
BINK_FAIL_INVALID_ARGUMENT,
16+
) = range(7)
817
BINK_ERROR_WARNING, BINK_ERROR_ERROR = range(2)
9-
BINK_VALUE_BOOL, BINK_VALUE_INT, BINK_VALUE_FLOAT, BINK_VALUE_STRING, BINK_VALUE_LIST, BINK_VALUE_DIVERT_TARGET, BINK_VALUE_VARIABLE_POINTER = range(7)
18+
(
19+
BINK_VALUE_BOOL,
20+
BINK_VALUE_INT,
21+
BINK_VALUE_FLOAT,
22+
BINK_VALUE_STRING,
23+
BINK_VALUE_LIST,
24+
BINK_VALUE_DIVERT_TARGET,
25+
BINK_VALUE_VARIABLE_POINTER,
26+
) = range(7)
1027

1128

1229
def _load_library():
@@ -29,54 +46,99 @@ def _load_library():
2946

3047

3148
def _declare(name, args, restype=ctypes.c_int):
49+
"""Set ctypes argument and result types for an exported C function."""
3250
fn = getattr(LIB, name)
3351
fn.argtypes, fn.restype = args, restype
3452

3553

3654
for _name, _args in {
3755
"bink_story_new": [ctypes.POINTER(P), ctypes.c_char_p, CP],
3856
"bink_story_can_continue": [P, ctypes.POINTER(ctypes.c_bool), CP],
39-
"bink_story_cont": [P, CP, CP], "bink_story_continue_maximally": [P, CP, CP],
57+
"bink_story_cont": [P, CP, CP],
58+
"bink_story_continue_maximally": [P, CP, CP],
4059
"bink_story_continue_async": [P, ctypes.c_float, ctypes.POINTER(ctypes.c_bool), CP],
4160
"bink_story_get_current_text": [P, CP, CP],
4261
"bink_story_get_current_choices": [P, ctypes.POINTER(P), ctypes.POINTER(SZ), CP],
4362
"bink_story_choose_choice_index": [P, SZ, CP],
4463
"bink_story_get_current_tags": [P, ctypes.POINTER(P), ctypes.POINTER(SZ), CP],
4564
"bink_story_get_global_tags": [P, ctypes.POINTER(P), ctypes.POINTER(SZ), CP],
46-
"bink_story_get_tags_for_content_at_path": [P, ctypes.c_char_p, ctypes.POINTER(P), ctypes.POINTER(SZ), CP],
65+
"bink_story_get_tags_for_content_at_path": [
66+
P,
67+
ctypes.c_char_p,
68+
ctypes.POINTER(P),
69+
ctypes.POINTER(SZ),
70+
CP,
71+
],
4772
"bink_story_choose_path_string": [P, ctypes.c_char_p, CP],
48-
"bink_story_choose_path_string_with_args": [P, ctypes.c_char_p, ctypes.c_bool, P, CP],
73+
"bink_story_choose_path_string_with_args": [
74+
P,
75+
ctypes.c_char_p,
76+
ctypes.c_bool,
77+
P,
78+
CP,
79+
],
4980
"bink_story_evaluate_function": [P, ctypes.c_char_p, P, ctypes.POINTER(P), CP, CP],
50-
"bink_story_load_state": [P, ctypes.c_char_p, CP], "bink_story_save_state": [P, CP, CP],
81+
"bink_story_load_state": [P, ctypes.c_char_p, CP],
82+
"bink_story_save_state": [P, CP, CP],
5183
"bink_story_reset_state": [P, CP],
52-
"bink_story_get_visit_count_at_path_string": [P, ctypes.c_char_p, ctypes.POINTER(ctypes.c_int32), CP],
53-
"bink_story_get_current_path": [P, CP, CP], "bink_story_build_string_of_hierarchy": [P, CP, CP],
54-
"bink_choices_get_text": [P, SZ, CP, CP], "bink_choices_get_tags": [P, SZ, ctypes.POINTER(P), ctypes.POINTER(SZ), CP],
84+
"bink_story_get_visit_count_at_path_string": [
85+
P,
86+
ctypes.c_char_p,
87+
ctypes.POINTER(ctypes.c_int32),
88+
CP,
89+
],
90+
"bink_story_get_current_path": [P, CP, CP],
91+
"bink_story_build_string_of_hierarchy": [P, CP, CP],
92+
"bink_choices_get_text": [P, SZ, CP, CP],
93+
"bink_choices_get_tags": [P, SZ, ctypes.POINTER(P), ctypes.POINTER(SZ), CP],
5594
"bink_tags_get": [P, SZ, CP, CP],
56-
"bink_value_new_bool": [ctypes.c_bool, ctypes.POINTER(P), CP], "bink_value_new_int": [ctypes.c_int32, ctypes.POINTER(P), CP],
57-
"bink_value_new_float": [ctypes.c_float, ctypes.POINTER(P), CP], "bink_value_new_string": [ctypes.c_char_p, ctypes.POINTER(P), CP],
58-
"bink_value_get_bool": [P, ctypes.POINTER(ctypes.c_bool), CP], "bink_value_get_int": [P, ctypes.POINTER(ctypes.c_int32), CP],
59-
"bink_value_get_float": [P, ctypes.POINTER(ctypes.c_float), CP], "bink_value_get_string": [P, CP, CP],
95+
"bink_value_new_bool": [ctypes.c_bool, ctypes.POINTER(P), CP],
96+
"bink_value_new_int": [ctypes.c_int32, ctypes.POINTER(P), CP],
97+
"bink_value_new_float": [ctypes.c_float, ctypes.POINTER(P), CP],
98+
"bink_value_new_string": [ctypes.c_char_p, ctypes.POINTER(P), CP],
99+
"bink_value_get_bool": [P, ctypes.POINTER(ctypes.c_bool), CP],
100+
"bink_value_get_int": [P, ctypes.POINTER(ctypes.c_int32), CP],
101+
"bink_value_get_float": [P, ctypes.POINTER(ctypes.c_float), CP],
102+
"bink_value_get_string": [P, CP, CP],
60103
"bink_value_get_kind": [P, ctypes.POINTER(ctypes.c_int), CP],
61-
"bink_value_array_new": [ctypes.POINTER(P), CP], "bink_value_array_push": [P, P, CP],
62-
"bink_list_new": [ctypes.POINTER(P), CP], "bink_story_list_new_from_origin": [P, ctypes.c_char_p, ctypes.POINTER(P), CP],
63-
"bink_story_list_new_from_item": [P, ctypes.c_char_p, ctypes.POINTER(P), CP], "bink_list_add_item": [P, ctypes.c_char_p, ctypes.c_int32, CP],
64-
"bink_list_get_count": [P, ctypes.POINTER(SZ), CP], "bink_list_get_item": [P, SZ, CP, ctypes.POINTER(ctypes.c_int32), CP],
65-
"bink_list_get_origin_count": [P, ctypes.POINTER(SZ), CP], "bink_list_get_origin": [P, SZ, CP, CP],
66-
"bink_value_new_list": [P, ctypes.POINTER(P), CP], "bink_value_get_list": [P, ctypes.POINTER(P), CP],
67-
"bink_var_get": [P, ctypes.c_char_p, ctypes.POINTER(P), CP], "bink_var_set": [P, ctypes.c_char_p, P, CP],
68-
"bink_story_switch_flow": [P, ctypes.c_char_p, CP], "bink_story_remove_flow": [P, ctypes.c_char_p, CP],
69-
"bink_story_switch_to_default_flow": [P, CP], "bink_story_set_allow_external_function_fallbacks": [P, ctypes.c_bool, CP],
104+
"bink_value_array_new": [ctypes.POINTER(P), CP],
105+
"bink_value_array_push": [P, P, CP],
106+
"bink_list_new": [ctypes.POINTER(P), CP],
107+
"bink_story_list_new_from_origin": [P, ctypes.c_char_p, ctypes.POINTER(P), CP],
108+
"bink_story_list_new_from_item": [P, ctypes.c_char_p, ctypes.POINTER(P), CP],
109+
"bink_list_add_item": [P, ctypes.c_char_p, ctypes.c_int32, CP],
110+
"bink_list_get_count": [P, ctypes.POINTER(SZ), CP],
111+
"bink_list_get_item": [P, SZ, CP, ctypes.POINTER(ctypes.c_int32), CP],
112+
"bink_list_get_origin_count": [P, ctypes.POINTER(SZ), CP],
113+
"bink_list_get_origin": [P, SZ, CP, CP],
114+
"bink_value_new_list": [P, ctypes.POINTER(P), CP],
115+
"bink_value_get_list": [P, ctypes.POINTER(P), CP],
116+
"bink_var_get": [P, ctypes.c_char_p, ctypes.POINTER(P), CP],
117+
"bink_var_set": [P, ctypes.c_char_p, P, CP],
118+
"bink_story_switch_flow": [P, ctypes.c_char_p, CP],
119+
"bink_story_remove_flow": [P, ctypes.c_char_p, CP],
120+
"bink_story_switch_to_default_flow": [P, CP],
121+
"bink_story_set_allow_external_function_fallbacks": [P, ctypes.c_bool, CP],
70122
"bink_unbind_external_function": [P, ctypes.c_char_p, CP],
71-
"bink_fun_args_count": [P, ctypes.POINTER(SZ), CP], "bink_fun_args_get": [P, SZ, ctypes.POINTER(P), CP],
123+
"bink_fun_args_count": [P, ctypes.POINTER(SZ), CP],
124+
"bink_fun_args_get": [P, SZ, ctypes.POINTER(P), CP],
72125
}.items():
73126
_declare(_name, _args)
74127

75-
for _name, _args in {"bink_story_free": [P], "bink_choices_free": [P], "bink_tags_free": [P], "bink_value_free": [P], "bink_value_array_free": [P], "bink_list_free": [P], "bink_cstring_free": [ctypes.c_char_p]}.items():
128+
for _name, _args in {
129+
"bink_story_free": [P],
130+
"bink_choices_free": [P],
131+
"bink_tags_free": [P],
132+
"bink_value_free": [P],
133+
"bink_value_array_free": [P],
134+
"bink_list_free": [P],
135+
"bink_cstring_free": [ctypes.c_char_p],
136+
}.items():
76137
_declare(_name, _args, None)
77138

78139

79140
def check(result, error):
141+
"""Raise the FFI error returned by a non-success status."""
80142
if result == BINK_OK:
81143
return
82144
message = error.value.decode("utf-8") if error.value else "Blade Ink FFI error"
@@ -86,11 +148,13 @@ def check(result, error):
86148

87149

88150
def call(name, *args):
151+
"""Invoke an FFI function that receives a trailing error-message output."""
89152
error = ctypes.c_char_p()
90153
check(getattr(LIB, name)(*args, ctypes.byref(error)), error)
91154

92155

93156
def take_string(value):
157+
"""Decode and free an FFI-owned C string."""
94158
try:
95159
return value.value.decode("utf-8") if value.value else ""
96160
finally:

bink/choices.py

Lines changed: 31 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
"""Choice collections returned by a story."""
2+
23
import ctypes
34

45
from ._ffi import LIB, call, take_string
@@ -7,27 +8,48 @@
78

89
class Choices:
910
"""An owned sequence of choice text, with access to each choice's tags."""
11+
1012
def __init__(self, pointer, length):
1113
self._choices, self._len = pointer, length
1214

13-
def __len__(self): return self._len
14-
def __bool__(self): return bool(self._len)
15-
def __iter__(self): return (self[index] for index in range(self._len))
15+
def __len__(self):
16+
return self._len
17+
18+
def __bool__(self):
19+
return bool(self._len)
20+
21+
def __iter__(self):
22+
return (self[index] for index in range(self._len))
1623

1724
def _index(self, index):
18-
if not isinstance(index, int): raise TypeError("choice index must be an integer")
19-
if index < 0: index += self._len
20-
if not 0 <= index < self._len: raise IndexError("choice index out of range")
25+
if not isinstance(index, int):
26+
raise TypeError("choice index must be an integer")
27+
if index < 0:
28+
index += self._len
29+
if not 0 <= index < self._len:
30+
raise IndexError("choice index out of range")
2131
return index
2232

2333
def __getitem__(self, index):
2434
value = ctypes.c_char_p()
25-
call("bink_choices_get_text", self._choices, self._index(index), ctypes.byref(value))
35+
call(
36+
"bink_choices_get_text",
37+
self._choices,
38+
self._index(index),
39+
ctypes.byref(value),
40+
)
2641
return take_string(value)
2742

2843
def get_tags(self, index):
29-
pointer, length = ctypes.c_void_p(), ctypes.c_size_t()
30-
call("bink_choices_get_tags", self._choices, self._index(index), ctypes.byref(pointer), ctypes.byref(length))
44+
"""Return the tags associated with the choice at ``index``."""
45+
pointer, length = ctypes.c_void_p(None), ctypes.c_size_t(0)
46+
call(
47+
"bink_choices_get_tags",
48+
self._choices,
49+
self._index(index),
50+
ctypes.byref(pointer),
51+
ctypes.byref(length),
52+
)
3153
return Tags(pointer, length.value)
3254

3355
def __del__(self):

0 commit comments

Comments
 (0)