Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CHANGES.rst
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ Release 1.0.1
=========================================

* **BUGFIX**: Fixed a bug encountered when parsing CSV data (issue #32).
* **ENHANCEMENT**: Added a catch for when trying to set ``Chart.options`` to a ``SharedOptions`` instance (issue #34).
* Fixed a broken link in the documentation.

---------------

Expand Down
6 changes: 3 additions & 3 deletions docs/api.rst
Original file line number Diff line number Diff line change
Expand Up @@ -337,9 +337,9 @@ Core Components
:class:`SolidGaugeOptions <highcharts_core.options.plot_options.gauge.SolidGaugeOptions>`
* - :mod:`.options.plot_options.generic <highcharts_core.options.plot_options.generic>`
- :class:`GenericTypeOptions <highcharts_core.options.plot_options.generic.GenericTypeOptions>`
* - :mod:`.options.plot_options.Heatmap <highcharts_core.options.plot_options.Heatmap>`
- :class:`HeatmapOptions <highcharts_core.options.plot_options.Heatmap.HeatmapOptions>`
:class:`TilemapOptions <highcharts_core.options.plot_options.Tilemap.TilemapOptions>`
* - :mod:`.options.plot_options.heatmap <highcharts_core.options.plot_options.heatmap>`
- :class:`HeatmapOptions <highcharts_core.options.plot_options.heatmap.HeatmapOptions>`
:class:`TilemapOptions <highcharts_core.options.plot_options.heatmap.TilemapOptions>`
* - :mod:`.options.plot_options.histogram <highcharts_core.options.plot_options.histogram>`
- :class:`HistogramOptions <highcharts_core.options.plot_options.histogram.HistogramOptions>`
* - :mod:`.options.plot_options.item <highcharts_core.options.plot_options.item>`
Expand Down
6 changes: 3 additions & 3 deletions docs/api/options/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -265,9 +265,9 @@ Sub-components
:class:`SolidGaugeOptions <highcharts_core.options.plot_options.gauge.SolidGaugeOptions>`
* - :mod:`.options.plot_options.generic <highcharts_core.options.plot_options.generic>`
- :class:`GenericTypeOptions <highcharts_core.options.plot_options.generic.GenericTypeOptions>`
* - :mod:`.options.plot_options.Heatmap <highcharts_core.options.plot_options.Heatmap>`
- :class:`HeatmapOptions <highcharts_core.options.plot_options.Heatmap.HeatmapOptions>`
:class:`TilemapOptions <highcharts_core.options.plot_options.Tilemap.TilemapOptions>`
* - :mod:`.options.plot_options.heatmap <highcharts_core.options.plot_options.heatmap>`
- :class:`HeatmapOptions <highcharts_core.options.plot_options.heatmap.HeatmapOptions>`
:class:`TilemapOptions <highcharts_core.options.plot_options.heatmap.TilemapOptions>`
* - :mod:`.options.plot_options.histogram <highcharts_core.options.plot_options.histogram>`
- :class:`HistogramOptions <highcharts_core.options.plot_options.histogram.HistogramOptions>`
* - :mod:`.options.plot_options.item <highcharts_core.options.plot_options.item>`
Expand Down
6 changes: 3 additions & 3 deletions docs/api/options/plot_options/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -139,9 +139,9 @@ Sub-components
:class:`SolidGaugeOptions <highcharts_core.options.plot_options.gauge.SolidGaugeOptions>`
* - :mod:`.options.plot_options.generic <highcharts_core.options.plot_options.generic>`
- :class:`GenericTypeOptions <highcharts_core.options.plot_options.generic.GenericTypeOptions>`
* - :mod:`.options.plot_options.Heatmap <highcharts_core.options.plot_options.Heatmap>`
- :class:`HeatmapOptions <highcharts_core.options.plot_options.Heatmap.HeatmapOptions>`
:class:`TilemapOptions <highcharts_core.options.plot_options.Tilemap.TilemapOptions>`
* - :mod:`.options.plot_options.heatmap <highcharts_core.options.plot_options.heatmap>`
- :class:`HeatmapOptions <highcharts_core.options.plot_options.heatmap.HeatmapOptions>`
:class:`TilemapOptions <highcharts_core.options.plot_options.heatmap.TilemapOptions>`
* - :mod:`.options.plot_options.histogram <highcharts_core.options.plot_options.histogram>`
- :class:`HistogramOptions <highcharts_core.options.plot_options.histogram.HistogramOptions>`
* - :mod:`.options.plot_options.item <highcharts_core.options.plot_options.item>`
Expand Down
12 changes: 11 additions & 1 deletion highcharts_core/chart.py
Original file line number Diff line number Diff line change
Expand Up @@ -185,8 +185,18 @@ def options(self) -> Optional[HighchartsOptions]:
return self._options

@options.setter
@class_sensitive(HighchartsOptions)
def options(self, value):
if not value:
self._options = None
elif isinstance(value, SharedOptions):
raise errors.HighchartsValueError('Chart.options expects a HighchartsOptions instance '
'or a valid descendent. However, the value you supplied '
'is a SharedOptions instance, which wil a descendent is not '
'valid for this parameter.')
else:
value = validate_types(value,
types = HighchartsOptions)

self._options = value

@property
Expand Down
68 changes: 42 additions & 26 deletions highcharts_core/options/series/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -440,12 +440,6 @@ def load_from_csv(self,
except AttributeError:
pass

if checkers.is_on_filesystem(as_string_or_file):
with open(as_string_or_file, 'r') as file_:
as_str = file_.read()
else:
as_str = as_string_or_file

property_column_map = validators.dict(property_column_map, allow_empty = False)
cleaned_column_map = {}
for key in property_column_map:
Expand All @@ -464,17 +458,32 @@ def load_from_csv(self,
f'instead.')
cleaned_column_map[key] = map_value

columns, csv_records = utility_functions.parse_csv(
as_str,
has_header_row = has_header_row,
delimiter = delimiter,
null_text = null_text,
wrapper_character = wrapper_character,
line_terminator = line_terminator,
wrap_all_strings = False,
double_wrapper_character_when_nested = False,
escape_character = "\\"
)
if not checkers.is_on_filesystem(as_string_or_file):
as_str = as_string_or_file
columns, csv_records = utility_functions.parse_csv(
as_str,
has_header_row = has_header_row,
delimiter = delimiter,
null_text = null_text,
wrapper_character = wrapper_character,
line_terminator = line_terminator,
wrap_all_strings = False,
double_wrapper_character_when_nested = False,
escape_character = "\\"
)
else:
with open(as_string_or_file, 'r', newline = '') as file_:
columns, csv_records = utility_functions.parse_csv(
file_,
has_header_row = has_header_row,
delimiter = delimiter,
null_text = null_text,
wrapper_character = wrapper_character,
line_terminator = line_terminator,
wrap_all_strings = False,
double_wrapper_character_when_nested = False,
escape_character = "\\"
)

for key in cleaned_column_map:
map_value = cleaned_column_map[key]
Expand All @@ -495,7 +504,14 @@ def load_from_csv(self,
data_point_dict = {}
for key in cleaned_column_map:
map_value = cleaned_column_map[key]
data_point_dict[key] = record.get(map_value, None)
value = record.get(map_value, None)
if value and isinstance(value, str) and ',' in value:
test_value = value.replace(delimiter, '')
if checkers.is_numeric(test_value):
value = test_value

data_point_dict[key] = value

data_point_dicts.append(data_point_dict)

self.data = data_point_dicts
Expand Down Expand Up @@ -650,14 +666,14 @@ def from_csv(cls,
instance = cls(**series_kwargs)
instance.load_from_csv(as_string_or_file,
property_column_map,
has_header_row = True,
delimiter = ',',
null_text = 'None',
wrapper_character = "'",
line_terminator = '\r\n',
wrap_all_strings = False,
double_wrapper_character_when_nested = False,
escape_character = "\\")
has_header_row = has_header_row,
delimiter = delimiter,
null_text = null_text,
wrapper_character = wrapper_character,
line_terminator = line_terminator,
wrap_all_strings = wrap_all_strings,
double_wrapper_character_when_nested = double_wrapper_character_when_nested,
escape_character = escape_character)

return instance

Expand Down
4 changes: 2 additions & 2 deletions highcharts_core/utility_functions.py
Original file line number Diff line number Diff line change
Expand Up @@ -279,11 +279,11 @@ def parse_csv(csv_data,
:rtype: :class:`tuple <python:tuple>` of a :class:`list <python:list>` of column names
and :class:`list <python:list>` of :class:`dict <python:dict>`
"""
csv_data = validators.string(csv_data, allow_empty = True)
if not csv_data:
return [], []

csv_data = csv_data.split(line_terminator)
if isinstance(csv_data, str):
csv_data = csv_data.split(line_terminator)

if not wrapper_character:
wrapper_character = "'"
Expand Down
35 changes: 35 additions & 0 deletions tests/options/series/test_area.py
Original file line number Diff line number Diff line change
Expand Up @@ -2789,6 +2789,41 @@ def test_bugfix32_LineSeries_from_csv(kwargs, error):
assert item.x is not None
assert item.y is not None


@pytest.mark.parametrize('filename, property_map, kwargs, error', [
('test-data-files/nst-est2019-01.csv', {}, {}, ValueError),
('test-data-files/nst-est2019-01.csv',
{
'name': 'Geographic Area',
'x': 'Geographic Area',
'y': '2010'
},
{
'wrapper_character': '"'
},
None),

])
def test_LineSeries_from_csv(input_files, filename, property_map, kwargs, error):
input_file = check_input_file(input_files, filename)

if not error:
result = cls5.from_csv(input_file,
property_column_map = property_map,
**kwargs)
assert result is not None
assert isinstance(result, cls5)
assert result.data is not None
for item in result.data:
for key in property_map:
assert getattr(item, key, None) is not None
else:
with pytest.raises(error):
result = cls5.from_csv(input_file,
property_column_map = property_map,
**kwargs)


#### NEXT CLASS

@pytest.mark.parametrize('kwargs, error', STANDARD_PARAMS)
Expand Down
14 changes: 14 additions & 0 deletions tests/test_chart.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
from json.decoder import JSONDecodeError

from highcharts_core.chart import Chart as cls
from highcharts_core.global_options.shared_options import SharedOptions
from highcharts_core import errors
from tests.fixtures import input_files, check_input_file, to_camelCase, to_js_dict, \
Class__init__, Class__to_untrimmed_dict, Class_from_dict, Class_to_dict, \
Expand All @@ -20,6 +21,19 @@ def test__init__(kwargs, error):
Class__init__(cls, kwargs, error)


@pytest.mark.parametrize('kwargs, error', [
({}, errors.HighchartsValueError),
])
def test_bugfix34_SharedOptions_error(kwargs, error):
shared_options = SharedOptions()
instance = cls(**kwargs)
if not error:
instance.options = shared_options
else:
with pytest.raises(error):
instance.options = shared_options


@pytest.mark.parametrize('kwargs, error', STANDARD_PARAMS)
def test__to_untrimmed_dict(kwargs, error):
Class__to_untrimmed_dict(cls, kwargs, error)
Expand Down