Skip to content

Commit a8c2d3a

Browse files
Merge branch 'master' of github.com:openfisca/openfisca-core into refactor-web_api-test-fixtures
2 parents fd6c776 + 81abfac commit a8c2d3a

9 files changed

Lines changed: 82 additions & 54 deletions

File tree

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
.venv
12
.project
23
.spyderproject
34
.pydevproject

CHANGELOG.md

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,23 @@
11
# Changelog
22

3-
### 35.1.0 [#973](https://github.com/openfisca/openfisca-core/pull/973)
3+
## 35.2.0 [#982](https://github.com/openfisca/openfisca-core/pull/982)
4+
5+
#### Technical changes
6+
7+
- Allow parameters to be arrays.
8+
9+
### 35.1.1 [#981](https://github.com/openfisca/openfisca-core/pull/981)
10+
11+
#### Technical changes
12+
13+
- Fix false negative web API test following an update in the country template used for testing.
14+
15+
## 35.1.0 [#973](https://github.com/openfisca/openfisca-core/pull/973)
416

517
#### Technical changes
618

719
- Extend assert_near so it is able to compare dates.
20+
821
### 35.0.5 [#974](https://github.com/openfisca/openfisca-core/pull/974)
922

1023
#### Technical changes

README.md

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,9 @@ This package contains the core features of OpenFisca, which are meant to be used
1717

1818
OpenFisca runs on Python 3.7. More recent versions should work, but are not tested.
1919

20-
2120
## Installation
2221

23-
If you're developping your own country package, you don't need to explicitly install OpenFisca-Core. It just needs to appear [in your package dependencies](https://github.com/openfisca/openfisca-france/blob/18.2.1/setup.py#L53).
22+
If you're developing your own country package, you don't need to explicitly install OpenFisca-Core. It just needs to appear [in your package dependencies](https://github.com/openfisca/openfisca-france/blob/18.2.1/setup.py#L53).
2423

2524
If you want to contribute to OpenFisca-Core itself, welcome! To install it locally in development mode run the following commands:
2625

openfisca_core/parameters.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@
3636
# 'unit' and 'reference' are only listed here for backward compatibility.
3737
# It is now recommended to include them in metadata, until a common consensus emerges.
3838
COMMON_KEYS = {'description', 'metadata', 'unit', 'reference', 'documentation'}
39-
ALLOWED_PARAM_TYPES = (float, int, bool, type(None))
39+
ALLOWED_PARAM_TYPES = (float, int, bool, type(None), List)
4040

4141

4242
def date_constructor(loader, node):
@@ -319,7 +319,7 @@ def validate(self, data):
319319
)
320320
if not isinstance(value, ALLOWED_PARAM_TYPES):
321321
raise ParameterParsingError(
322-
"Invalid value in {} : {}".format(self.name, value),
322+
"Value in {} has type {}, which is not one of the allowed types ({}): {}".format(self.name, type(value), ALLOWED_PARAM_TYPES, value),
323323
self.file_path
324324
)
325325

@@ -851,7 +851,7 @@ def load_parameter_file(file_path, name = ''):
851851
:returns: An instance of :any:`ParameterNode` or :any:`Scale` or :any:`Parameter`.
852852
"""
853853
if not os.path.exists(file_path):
854-
raise ValueError("{} doest not exist".format(file_path))
854+
raise ValueError("{} does not exist".format(file_path))
855855
if os.path.isdir(file_path):
856856
return ParameterNode(name, directory_path = file_path)
857857
data = _load_yaml_file(file_path)

openfisca_web_api/openAPI.yml

Lines changed: 41 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -34,49 +34,49 @@ paths:
3434
post:
3535
summary: "Run a simulation"
3636
tags:
37-
- Calculations
37+
- Calculations
3838
operationId: "calculate"
3939
consumes:
40-
- "application/json"
40+
- "application/json"
4141
produces:
42-
- "application/json"
42+
- "application/json"
4343
parameters:
4444
- in: "body"
4545
name: "Situation"
46-
description: 'Describe the situation (persons and entities). Add the variable you wish to calculate in the proper entity, with null as the value. Learn more in our official documentation: https://openfisca.org/doc/openfisca-web-api/input-output-data.html'
46+
description: "Describe the situation (persons and entities). Add the variable you wish to calculate in the proper entity, with null as the value. Learn more in our official documentation: https://openfisca.org/doc/openfisca-web-api/input-output-data.html"
4747
required: true
4848
schema:
49-
$ref: '#/definitions/SituationInput'
49+
$ref: "#/definitions/SituationInput"
5050
responses:
5151
200:
5252
description: "The calculation result is sent back in the response body"
5353
headers:
54-
$ref: '#/commons/Headers'
54+
$ref: "#/commons/Headers"
5555
schema:
56-
$ref: '#/definitions/SituationOutput'
56+
$ref: "#/definitions/SituationOutput"
5757
404:
5858
description: "A variable mentioned in the input situation does not exist in the loaded tax and benefit system. Details are sent back in the response body"
5959
headers:
60-
$ref: '#/commons/Headers'
60+
$ref: "#/commons/Headers"
6161
400:
6262
description: "The request is invalid. Details about the error are sent back in the response body"
6363
headers:
64-
$ref: '#/commons/Headers'
64+
$ref: "#/commons/Headers"
6565
/parameters:
6666
get:
6767
tags:
68-
- "Parameters"
68+
- "Parameters"
6969
summary: "List all available parameters"
7070
operationId: "getParameters"
7171
produces:
72-
- "application/json"
72+
- "application/json"
7373
responses:
7474
200:
7575
description: "The list of parameters is sent back in the response body"
7676
headers:
77-
$ref: '#/commons/Headers'
77+
$ref: "#/commons/Headers"
7878
schema:
79-
$ref: '#/definitions/Parameters'
79+
$ref: "#/definitions/Parameters"
8080
/parameter/{parameterID}:
8181
get:
8282
tags:
@@ -95,13 +95,13 @@ paths:
9595
200:
9696
description: "The requested parameter's information is sent back in the response body"
9797
headers:
98-
$ref: '#/commons/Headers'
98+
$ref: "#/commons/Headers"
9999
schema:
100100
$ref: "#/definitions/Parameter"
101101
404:
102102
description: "The requested parameter does not exist"
103103
headers:
104-
$ref: '#/commons/Headers'
104+
$ref: "#/commons/Headers"
105105
/variables:
106106
get:
107107
tags:
@@ -114,7 +114,7 @@ paths:
114114
200:
115115
description: "The list of variables is sent back in the response body"
116116
headers:
117-
$ref: '#/commons/Headers'
117+
$ref: "#/commons/Headers"
118118
schema:
119119
$ref: "#/definitions/Variables"
120120
/variable/{variableID}:
@@ -135,13 +135,13 @@ paths:
135135
200:
136136
description: "The requested variable's information is sent back in the response body"
137137
headers:
138-
$ref: '#/commons/Headers'
138+
$ref: "#/commons/Headers"
139139
schema:
140140
$ref: "#/definitions/Variable"
141141
404:
142142
description: "The requested variable does not exist"
143143
headers:
144-
$ref: '#/commons/Headers'
144+
$ref: "#/commons/Headers"
145145
/entities:
146146
get:
147147
tags:
@@ -154,61 +154,61 @@ paths:
154154
200:
155155
description: "The list of the entities as well as their information is sent back in the response body"
156156
headers:
157-
$ref: '#/commons/Headers'
157+
$ref: "#/commons/Headers"
158158
schema:
159159
$ref: "#/definitions/Entities"
160160
/trace:
161161
post:
162162
summary: "Explore a simulation's steps in details."
163163
tags:
164-
- Calculations
164+
- Calculations
165165
operationId: "trace"
166166
consumes:
167-
- "application/json"
167+
- "application/json"
168168
produces:
169-
- "application/json"
169+
- "application/json"
170170
parameters:
171171
- in: "body"
172172
name: "Situation"
173-
description: 'Describe the situation (persons and entities). Add the variable you wish to calculate in the proper entity, with null as the value.'
173+
description: "Describe the situation (persons and entities). Add the variable you wish to calculate in the proper entity, with null as the value."
174174
required: true
175175
schema:
176-
$ref: '#/definitions/SituationInput'
176+
$ref: "#/definitions/SituationInput"
177177
responses:
178178
200:
179179
description: "The calculation details are sent back in the response body"
180180
headers:
181-
$ref: '#/commons/Headers'
181+
$ref: "#/commons/Headers"
182182
schema:
183-
$ref: '#/definitions/Trace'
183+
$ref: "#/definitions/Trace"
184184
404:
185185
description: "A variable mentioned in the input situation does not exist in the loaded tax and benefit system. Details are sent back in the response body"
186186
headers:
187-
$ref: '#/commons/Headers'
187+
$ref: "#/commons/Headers"
188188
400:
189189
description: "The request is invalid. Details about the error are sent back in the response body"
190190
headers:
191-
$ref: '#/commons/Headers'
191+
$ref: "#/commons/Headers"
192192
/spec:
193193
get:
194194
summary: Provide the API documentation in an OpenAPI format
195195
tags:
196-
- Documentation
196+
- Documentation
197197
operationId: spec
198198
produces:
199-
- application/json
199+
- application/json
200200
responses:
201201
200:
202202
description: The API documentation is sent back in the response body
203203
headers:
204-
$ref: '#/commons/Headers'
204+
$ref: "#/commons/Headers"
205205

206206
definitions:
207207
Parameter:
208208
type: "object"
209209
properties:
210210
values:
211-
$ref: '#/definitions/Values'
211+
$ref: "#/definitions/Values"
212212
brackets:
213213
type: "object"
214214
additionalProperties:
@@ -219,7 +219,7 @@ definitions:
219219
type: "object"
220220
properties:
221221
definition:
222-
type: 'string'
222+
type: "string"
223223
metadata:
224224
type: "object"
225225
description:
@@ -237,9 +237,9 @@ definitions:
237237
type: "object"
238238
properties:
239239
description:
240-
type: 'string'
240+
type: "string"
241241
href:
242-
type: 'string'
242+
type: "string"
243243

244244
Variable:
245245
type: "object"
@@ -284,9 +284,9 @@ definitions:
284284
type: "object"
285285
properties:
286286
description:
287-
type: 'string'
287+
type: "string"
288288
href:
289-
type: 'string'
289+
type: "string"
290290

291291
Formula:
292292
type: "object"
@@ -303,10 +303,11 @@ definitions:
303303
format: "float"
304304

305305
Values:
306+
description: All keys are ISO dates. Values can be numbers, booleans, or arrays of a single type (number, boolean or string).
306307
type: "object"
307-
additionalProperties:
308-
type: "number"
309-
format: "float"
308+
additionalProperties: true
309+
# propertyNames: # this keyword is part of JSON Schema but is not supported in OpenAPI Specification at the time of writing, see https://swagger.io/docs/specification/data-models/keywords/#unsupported
310+
# pattern: "^[12][0-9]{3}-[01][0-9]-[0-3][0-9]$" # all keys are ISO dates
310311

311312
Entities:
312313
type: "object"

setup.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@
2626

2727
dev_requirements = [
2828
'autopep8 >= 1.4.0, < 1.6.0',
29-
'flake8 >= 3.7.0, < 3.9.0',
29+
'flake8 >= 3.9.0, < 4.0.0',
3030
'flake8-bugbear >= 19.3.0, < 20.0.0',
3131
'flake8-print >= 3.1.0, < 4.0.0',
3232
'pytest-cov >= 2.6.1, < 3.0.0',
@@ -37,7 +37,7 @@
3737

3838
setup(
3939
name = 'OpenFisca-Core',
40-
version = '35.1.0',
40+
version = '35.2.0',
4141
author = 'OpenFisca Team',
4242
author_email = 'contact@openfisca.org',
4343
classifiers = [
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
description: Array types should be allowed.
2+
values:
3+
2013-01-01:
4+
value: [ FR ]
5+
2018-06-01:
6+
value: [ ES, FR, IT, NZ ]

tests/core/parameter_validation/test_parameter_validation.py

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
year = 2016
99

1010

11-
def check(file_name, keywords):
11+
def check_fails_with_message(file_name, keywords):
1212
path = os.path.join(BASE_DIR, file_name) + '.yaml'
1313
try:
1414
load_parameter_file(path, file_name)
@@ -22,7 +22,7 @@ def check(file_name, keywords):
2222
@pytest.mark.parametrize("test", [
2323
('indentation', {'Invalid YAML', 'indentation.yaml', 'line 2', 'mapping values are not allowed'}),
2424
('wrong_scale', {'Unexpected property', 'scale[1]', 'treshold'}),
25-
('wrong_value', {'Invalid value', 'wrong_value[2015-12-01]', '1A'}),
25+
('wrong_value', {'not one of the allowed types', 'wrong_value[2015-12-01]', '1A'}),
2626
('unexpected_key_in_parameter', {'Unexpected property', 'unexpected_key'}),
2727
('wrong_type_in_parameter', {'must be of type object'}),
2828
('wrong_type_in_value_history', {'must be of type object'}),
@@ -37,7 +37,12 @@ def check(file_name, keywords):
3737
])
3838
def test_parsing_errors(test):
3939
with pytest.raises(ParameterParsingError):
40-
check(*test)
40+
check_fails_with_message(*test)
41+
42+
43+
def test_array_type():
44+
path = os.path.join(BASE_DIR, 'array_type.yaml')
45+
load_parameter_file(path, 'array_type')
4146

4247

4348
def test_filesystem_hierarchy():

tests/web_api/test_variables.py

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -267,8 +267,9 @@ def test_variable_formula_github_link(test_client):
267267
def test_variable_formula_content(test_client):
268268
variable_response = test_client.get('/variable/income_tax')
269269
variable = json.loads(variable_response.data.decode('utf-8'))
270-
formula_code = "def formula(person, period, parameters):\n return person('salary', period) * parameters(period).taxes.income_tax_rate\n"
271-
assert variable['formulas']['0001-01-01']['content'] == formula_code
270+
content = variable['formulas']['0001-01-01']['content']
271+
assert "def formula(person, period, parameters):" in content
272+
assert "return person(\"salary\", period) * parameters(period).taxes.income_tax_rate" in content
272273

273274

274275
def test_null_values_are_dropped(test_client):
@@ -334,4 +335,6 @@ def test_variable_documentation(test_client):
334335
variable = json.loads(response.data.decode('utf-8'))
335336
assert variable['documentation'] == "This allowance was introduced on the 1st of Jan 1980.\nIt disappeared in Dec 2016."
336337

337-
assert variable['formulas']['1980-01-01']['documentation'] == "\nTo compute this allowance, the 'rent' value must be provided for the same month, but 'housing_occupancy_status' is not necessary.\n"
338+
formula_documentation = variable['formulas']['1980-01-01']['documentation']
339+
assert "Housing allowance." in formula_documentation
340+
assert "Calculating it before this date will always return the variable default value, 0." in formula_documentation

0 commit comments

Comments
 (0)