Skip to content

Commit 01090f2

Browse files
committed
linting
1 parent a1253dd commit 01090f2

8 files changed

Lines changed: 145 additions & 98 deletions

File tree

.github/workflows/pylint.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ jobs:
2020
pip install pylint
2121
- name: Analysing the code with pylint
2222
run: |
23-
pylint $(git ls-files '*.py')
23+
pylint $(git ls-files 'bink/*.py')
2424
- name: Run tests
2525
run: |
2626
python -m unittest -v tests/story_tests.py

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,8 @@ To learn more about the Ink language, you can check [the official documentation]
1111
Here is a quick example that uses basic features to play an Ink story using the `bladeink` crate.
1212

1313
```python
14-
# Story is the entry point of the `bladeink` lib.
15-
story = Story.from_file("inkfiles/TheIntercept.ink.json")
14+
# Story is the entry point of the Blade Ink lib.
15+
story = story_from_file("inkfiles/TheIntercept.ink.json")
1616
self.assertTrue(story.can_continue())
1717

1818
end = False

bink/Choices.py

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,31 @@
1-
from bink.loadlib import lib, BINK_OK
1+
# pylint: disable=E1101
2+
"""Handle Ink Choices."""
23
import ctypes
4+
from bink.loadlib import LIB, BINK_OK
35

4-
class Choices:
5-
def __init__(self, choices, c_len: int):
6+
class Choices:
7+
"""List of story choices."""
8+
def __init__(self, choices, c_len: int):
69
self._choices = choices
710
self._len = c_len
811

912
def len(self) -> int:
13+
"""Returns the number of choices."""
1014
return self._len
11-
15+
1216
def get_text(self, idx) -> str:
17+
"""Returns the choice text."""
1318
text = ctypes.c_char_p()
14-
ret = lib.bink_choices_get_text(self._choices, idx, ctypes.byref(text))
19+
ret = LIB.bink_choices_get_text(self._choices, idx, ctypes.byref(text))
1520

1621
if ret != BINK_OK:
17-
raise RuntimeError("Error getting choice text, index out of bounds?")
22+
raise RuntimeError(
23+
"Error getting choice text, index out of bounds?")
1824

1925
result = text.value.decode('utf-8')
20-
lib.bink_cstring_free(text)
26+
LIB.bink_cstring_free(text)
2127

2228
return result
23-
29+
2430
def __del__(self):
25-
lib.bink_choices_free(self._choices)
31+
LIB.bink_choices_free(self._choices)

bink/Story.py

Lines changed: 58 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1,106 +1,129 @@
1-
from bink.Choices import Choices
2-
from bink.Tags import Tags
3-
from bink.loadlib import lib, BINK_OK
1+
# pylint: disable=E1101, C0116
2+
3+
"""Handle Ink Story."""
44
import ctypes
5+
from bink.choices import Choices
6+
from bink.tags import Tags
7+
from bink.loadlib import LIB, BINK_OK
58

6-
class Story:
9+
class Story:
10+
"""Story is the entry point of the Blade Ink lib."""
711
def __init__(self, story_string: str):
812
err_msg = ctypes.c_char_p()
913
story = ctypes.c_void_p()
10-
ret = lib.bink_story_new(ctypes.byref(story), story_string.encode('utf-8'), ctypes.byref(err_msg))
14+
ret = LIB.bink_story_new(
15+
ctypes.byref(story),
16+
story_string.encode('utf-8'),
17+
ctypes.byref(err_msg))
1118
if ret != BINK_OK:
1219
err = err_msg.value.decode('utf-8')
13-
lib.bink_cstring_free(err_msg)
20+
LIB.bink_cstring_free(err_msg)
1421
raise RuntimeError(err)
15-
22+
1623
self._story = story
1724

1825
def can_continue(self):
1926
can_continue = ctypes.c_bool()
20-
ret = lib.bink_story_can_continue(self._story, ctypes.byref(can_continue))
27+
ret = LIB.bink_story_can_continue(
28+
self._story, ctypes.byref(can_continue))
2129

2230
if ret != BINK_OK:
2331
raise RuntimeError("Error in can_continue")
2432

2533
return can_continue.value
26-
34+
2735
def cont(self) -> str:
2836
err_msg = ctypes.c_char_p()
2937
line = ctypes.c_char_p()
30-
ret = lib.bink_story_cont(self._story, ctypes.byref(line), ctypes.byref(err_msg))
38+
ret = LIB.bink_story_cont(
39+
self._story,
40+
ctypes.byref(line),
41+
ctypes.byref(err_msg))
3142

3243
if ret != BINK_OK:
3344
err = err_msg.value.decode('utf-8')
34-
lib.bink_cstring_free(err_msg)
45+
LIB.bink_cstring_free(err_msg)
3546
raise RuntimeError(err)
3647

3748
result = line.value.decode('utf-8')
38-
lib.bink_cstring_free(line)
49+
LIB.bink_cstring_free(line)
3950

4051
return result
41-
52+
4253
def continue_maximally(self) -> str:
4354
err_msg = ctypes.c_char_p()
4455
line = ctypes.c_char_p()
45-
ret = lib.bink_story_continue_maximally(self._story, ctypes.byref(line), ctypes.byref(err_msg))
56+
ret = LIB.bink_story_continue_maximally(
57+
self._story, ctypes.byref(line), ctypes.byref(err_msg))
4658

4759
if ret != BINK_OK:
4860
err = err_msg.value.decode('utf-8')
49-
lib.bink_cstring_free(err_msg)
61+
LIB.bink_cstring_free(err_msg)
5062
raise RuntimeError(err)
5163

5264
result = line.value.decode('utf-8')
53-
lib.bink_cstring_free(line)
65+
LIB.bink_cstring_free(line)
5466

5567
return result
56-
68+
5769
def get_current_choices(self) -> Choices:
5870
choices = ctypes.c_void_p()
59-
len = ctypes.c_int()
60-
ret = lib.bink_story_get_current_choices(self._story, ctypes.byref(choices), ctypes.byref(len))
71+
choice_count = ctypes.c_int()
72+
ret = LIB.bink_story_get_current_choices(
73+
self._story, ctypes.byref(choices), ctypes.byref(choice_count))
6174

6275
if ret != BINK_OK:
6376
raise RuntimeError("Error getting current choices")
6477

65-
choices = Choices(choices, len.value)
78+
choices = Choices(choices, choice_count.value)
6679

6780
return choices
68-
81+
6982
def choose_choice_index(self, choice_index: int):
83+
"""Chooses the `Choice` from the
84+
`currentChoices` list with the given index. Internally, this
85+
sets the current content path to what the
86+
`Choice` points to, ready to continue story evaluation."""
7087
err_msg = ctypes.c_char_p()
7188
cidx = ctypes.c_int(choice_index)
72-
ret = lib.bink_story_choose_choice_index(self._story, cidx, ctypes.byref(err_msg))
89+
ret = LIB.bink_story_choose_choice_index(
90+
self._story, cidx, ctypes.byref(err_msg))
7391

7492
if ret != BINK_OK:
7593
err = err_msg.value.decode('utf-8')
76-
lib.bink_cstring_free(err_msg)
94+
LIB.bink_cstring_free(err_msg)
7795
raise RuntimeError(err)
78-
96+
7997
def get_current_tags(self) -> Tags:
8098
tags = ctypes.c_void_p()
81-
len = ctypes.c_int()
82-
ret = lib.bink_story_get_current_tags(self._story, ctypes.byref(tags), ctypes.byref(len))
99+
tag_count = ctypes.c_int()
100+
ret = LIB.bink_story_get_current_tags(
101+
self._story, ctypes.byref(tags), ctypes.byref(tag_count))
83102

84103
if ret != BINK_OK:
85104
raise RuntimeError("Error getting current tags")
86105

87-
tags = Tags(tags, len.value)
106+
tags = Tags(tags, tag_count.value)
88107

89108
return tags
90-
91-
def choose_path_string(self, path : str):
109+
110+
def choose_path_string(self, path: str):
92111
err_msg = ctypes.c_char_p()
93112
story = ctypes.c_void_p()
94-
ret = lib.bink_story_new(ctypes.byref(story), path.encode('utf-8'), ctypes.byref(err_msg))
113+
ret = LIB.bink_story_new(
114+
ctypes.byref(story),
115+
path.encode('utf-8'),
116+
ctypes.byref(err_msg))
95117
if ret != BINK_OK:
96118
err = err_msg.value.decode('utf-8')
97-
lib.bink_cstring_free(err_msg)
119+
LIB.bink_cstring_free(err_msg)
98120
raise RuntimeError(err)
99-
121+
100122
def __del__(self):
101-
lib.bink_story_free(self._story)
123+
LIB.bink_story_free(self._story)
124+
102125

103-
def from_file(story_file: str):
104-
with open(story_file, 'r') as file:
126+
def story_from_file(story_file: str):
127+
with open(story_file, 'r', encoding='utf-8') as file:
105128
content = file.read()
106129
return Story(content)

bink/Tags.py

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,31 @@
1-
from bink.loadlib import lib, BINK_OK
1+
# pylint: disable=E1101
2+
3+
"""Handle Ink tags."""
24
import ctypes
5+
from bink.loadlib import LIB, BINK_OK
36

4-
class Tags:
5-
def __init__(self, tags, c_len):
7+
class Tags:
8+
"""Contains a list of tags."""
9+
def __init__(self, tags, c_len):
610
self._tags = tags
711
self._len = c_len
812

913
def len(self) -> int:
14+
"""Returns the number of choices."""
1015
return self._len
11-
16+
1217
def get(self, idx) -> str:
18+
"""Returns the tag text."""
1319
tag = ctypes.c_char_p()
14-
ret = lib.bink_choices_get_text(self._tags, idx, ctypes.byref(tag))
20+
ret = LIB.bink_choices_get_text(self._tags, idx, ctypes.byref(tag))
1521

1622
if ret != BINK_OK:
1723
raise RuntimeError("Error getting tag, index out of bounds?")
1824

1925
result = tag.value.decode('utf-8')
20-
lib.bink_cstring_free(tag)
26+
LIB.bink_cstring_free(tag)
2127

2228
return result
23-
29+
2430
def __del__(self):
25-
lib.bink_choices_free(self._tags)
31+
LIB.bink_choices_free(self._tags)

bink/loadlib.py

Lines changed: 48 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -1,46 +1,55 @@
1+
"""Load the Bink C library."""
12
import os
23
import platform
34
import ctypes.util
45

5-
# First, look for a bundled FreeType shared object on the top-level of the
6-
# installed freetype-py module.
7-
system = platform.system()
8-
if system == 'Windows':
9-
library_name = 'bink.dll'
10-
elif system == 'Darwin':
11-
library_name = 'libbink.dylib'
12-
else:
13-
library_name = 'libbink.so'
14-
15-
_filename = os.path.join(os.path.dirname(__file__), 'lib/' + library_name)
16-
17-
# If no bundled shared object is found, look for a system-wide installed one.
18-
if not os.path.exists(_filename):
19-
# on windows all ctypes does when checking for the library
20-
# is to append .dll to the end and look for an exact match
21-
# within any entry in PATH.
22-
_filename = ctypes.util.find_library('bink')
23-
24-
if _filename is None:
25-
if platform.system() == 'Windows':
26-
# Check current working directory for dll as ctypes fails to do so
27-
_filename = os.path.join(os.path.realpath('.'), "bink.dll")
28-
else:
29-
_filename = library_name
30-
31-
try:
32-
print("lib filename: ", _filename)
33-
lib = ctypes.CDLL(_filename)
34-
except (OSError, TypeError):
35-
lib = None
36-
raise RuntimeError('bink library not found')
37-
38-
lib.bink_story_new.argtypes = [ctypes.POINTER(ctypes.c_void_p), ctypes.c_char_p, ctypes.POINTER(ctypes.c_char_p)]
39-
lib.bink_story_new.restype = ctypes.c_int
40-
41-
lib.bink_story_can_continue.argtypes = [ctypes.c_void_p, ctypes.POINTER(ctypes.c_bool)]
42-
lib.bink_story_can_continue.restype = ctypes.c_int
6+
def _load_library():
7+
# First, look for a bundled bink shared object on the lib folder.
8+
system = platform.system()
9+
library_name = None
10+
if system == 'Windows':
11+
library_name = 'bink.dll'
12+
elif system == 'Darwin':
13+
library_name = 'libbink.dylib'
14+
else:
15+
library_name = 'libbink.so'
16+
17+
_filename = os.path.join(os.path.dirname(__file__), 'lib/' + library_name)
18+
19+
# If no bundled shared object is found, look for a system-wide installed one.
20+
if not os.path.exists(_filename):
21+
# on windows all ctypes does when checking for the library
22+
# is to append .dll to the end and look for an exact match
23+
# within any entry in PATH.
24+
_filename = ctypes.util.find_library('bink')
25+
26+
if _filename is None:
27+
if platform.system() == 'Windows':
28+
# Check current working directory for dll as ctypes fails to do so
29+
_filename = os.path.join(os.path.realpath('.'), "bink.dll")
30+
else:
31+
_filename = library_name
32+
33+
try:
34+
print("lib filename: ", _filename)
35+
lib = ctypes.CDLL(_filename)
36+
except (OSError, TypeError) as exc:
37+
lib = None
38+
raise RuntimeError('bink library not found') from exc
39+
return lib
40+
41+
LIB = _load_library()
42+
43+
LIB.bink_story_new.argtypes = [
44+
ctypes.POINTER(
45+
ctypes.c_void_p), ctypes.c_char_p, ctypes.POINTER(
46+
ctypes.c_char_p)]
47+
LIB.bink_story_new.restype = ctypes.c_int
48+
49+
LIB.bink_story_can_continue.argtypes = [
50+
ctypes.c_void_p, ctypes.POINTER(ctypes.c_bool)]
51+
LIB.bink_story_can_continue.restype = ctypes.c_int
4352

4453
BINK_OK = 0
4554
BINK_FAIL = 1
46-
BINK_FAIL_NULL_POINTER = 2
55+
BINK_FAIL_NULL_POINTER = 2

setup.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
"""Package definition."""
12
from setuptools import find_packages, setup
23

34
setup(
@@ -7,4 +8,4 @@
78
description='Runtime for Ink, a scripting language for writing interactive narrative',
89
author='Rafael Garcia',
910
license='Apache 2.0',
10-
)
11+
)

tests/story_tests.py

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,15 @@
1-
from bink import Story
1+
from bink.story import Story, story_from_file
22
import unittest
33

4+
45
class StoryTestCase(unittest.TestCase):
56
def test_oneline(self):
6-
story = Story.from_file("inkfiles/oneline.ink.json")
7+
story = story_from_file("inkfiles/oneline.ink.json")
78
self.assertTrue(story.can_continue())
89
self.assertEqual(story.cont(), "Line.\n")
910

1011
def test_the_intercept(self):
11-
story = Story.from_file("inkfiles/TheIntercept.ink.json")
12+
story = story_from_file("inkfiles/TheIntercept.ink.json")
1213
self.assertTrue(story.can_continue())
1314

1415
end = False
@@ -35,5 +36,6 @@ def test_the_intercept(self):
3536

3637
print("Story ended ok.")
3738

39+
3840
if __name__ == '__main__':
3941
unittest.main()

0 commit comments

Comments
 (0)