Skip to content

Commit

Permalink
Merge branch 'develop'
Browse files Browse the repository at this point in the history
  • Loading branch information
svituz committed Mar 13, 2024
2 parents 71afb42 + 54572c4 commit 9550b6e
Show file tree
Hide file tree
Showing 48 changed files with 44,731 additions and 1,753 deletions.
17 changes: 10 additions & 7 deletions .github/workflows/run_tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,20 +8,23 @@ on:

jobs:
build:
runs-on: ubuntu-latest
runs-on: ${{ matrix.os }}
strategy:
matrix:
python-version: [2.7, 3.4, 3.5, 3.6, 3.7, 3.8, 3.9]
os: [ubuntu-latest]
python-version: ["3.7", "3.8", "3.9", "3.10", "3.11", "3.12"]

steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v4
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v2
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install coveralls nose
- name: Test with nosetests
pip install coveralls nose2 nose2[coverage_plugin]>=0.6.5
- name: Test with nose2
run: |
nosetests tests hl7apy --with-doctest --with-coverage --cover-package hl7apy
nose2 tests hl7apy
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ Documentation can be found [here](http://crs4.github.io/hl7apy/).
Installation
------------

HL7apy is platform independent and supports Python 2.7 and Python 3.4, 3.5, 3.6, 3.7
HL7apy is platform independent and supports Python 2.7 and Python 3.[4-12]

To install it get the latest release from [GitHub](https://github.com/crs4/hl7apy/releases) and launch the following command:

Expand Down
2 changes: 1 addition & 1 deletion VERSION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
1.3.4
1.3.5
4 changes: 2 additions & 2 deletions docs/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ The main features includes:

Currently supported HL7 versions are: 2.1, 2.2, 2.3, 2.3.1, 2.4, 2.5, 2.5.1, 2.6, 2.7, 2.8, 2.8.1, 2.8.2

Current version is 1.3.4
Current version is 1.3.5

To get started visit the :ref:`Getting started <tutorial>` section

Expand All @@ -28,7 +28,7 @@ This project is not affiliated with the HL7 organization: the library is just co
Installation
============

HL7apy is platform independent and supports Python 2.7 and Python 3.4, 3.5, 3.6, 3.7
HL7apy is platform independent and supports Python 2.7 and Python 3.[4-12]

To install it get the latest release from `GitHub <https://github.com/crs4/hl7apy/releases>`_ and launch the following
command:
Expand Down
6 changes: 6 additions & 0 deletions docs/release_notes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,12 @@

Release Notes
=============
New in 1.3.5

* Fix multithreading issue (#95)
* Fix SIU structures (#104)
* Removes print statement (#106)

New in 1.3.4

* Bug fixes regarding dates
Expand Down
10 changes: 6 additions & 4 deletions hl7apy/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,18 +20,22 @@
# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

from __future__ import absolute_import

import os
import sys

try:
from collections.abc import MutableMapping
except ImportError:
from collections import MutableMapping

import importlib

try:
import cPickle as pickle
except ImportError:
import pickle


from hl7apy.exceptions import UnsupportedVersion, InvalidEncodingChars, UnknownValidationLevel
from hl7apy.consts import DEFAULT_ENCODING_CHARS, DEFAULT_ENCODING_CHARS_27, DEFAULT_VERSION, VALIDATION_LEVEL

Expand Down Expand Up @@ -233,9 +237,7 @@ def load_library(version):
"""
check_version(version)
module_name = SUPPORTED_LIBRARIES[version]
lib = sys.modules.get(module_name)
if lib is None:
lib = importlib.import_module(module_name)
lib = importlib.import_module(module_name)
return lib


Expand Down
20 changes: 16 additions & 4 deletions hl7apy/base_datatypes.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,9 @@
"""

from __future__ import absolute_import
import re

import numbers
import re
from datetime import datetime
from decimal import Decimal
from functools import cmp_to_key
Expand Down Expand Up @@ -65,6 +66,7 @@ class BaseDataType(object):
greater than the :attr:`max_length`. Only if :attr:`validation_level` is
:attr:`STRICT <VALIDATION_LEVEL.STRICT>`
"""

def __init__(self, value, max_length=None, validation_level=None):
if validation_level is None:
validation_level = get_default_validation_level()
Expand Down Expand Up @@ -113,6 +115,7 @@ class TextualDataType(BaseDataType):
:raise: :exc:`MaxLengthReached <hl7apy.exceptions.MaxLengthReached>` When the :attr:`value`'s length is
greater than :attr:`max_length`
"""

def __init__(self, value, max_length=32, highlights=None,
validation_level=None):
self.highlights = highlights
Expand All @@ -132,7 +135,7 @@ def _get_translations(self, encoding_chars):
(encoding_chars['REPETITION'], '{esc}R{esc}'.format(esc=escape_char)),)

def _get_escape_char_regex(self, escape_char):
return r'(?<!%s[HNFSTRE])%s(?![HNFSTRE]%s)' % tuple(3*[re.escape(escape_char)])
return r'(?<!%s[HNFSTRE])%s(?![HNFSTRE]%s)' % tuple(3 * [re.escape(escape_char)])

def _escape_value(self, value, encoding_chars=None):
escape_char = encoding_chars['ESCAPE']
Expand Down Expand Up @@ -196,6 +199,7 @@ class NumericDataType(BaseDataType):
:raise: :exc:`hl7apy.exceptions.MaxLengthReached` When the `value`'s length is greater than `max_length`
"""

def __init__(self, value=None, max_length=16,
validation_level=None):
super(NumericDataType, self).__init__(value, max_length,
Expand Down Expand Up @@ -238,6 +242,7 @@ class WD(TextualDataType):
:attr:`max_length` is 0
"""

def __init__(self, value, highlights=None,
validation_level=None):
super(WD, self).__init__(value, 199, highlights, validation_level)
Expand Down Expand Up @@ -332,6 +337,7 @@ class ST(TextualDataType):
:attr:`max_length` is 199
"""

def __init__(self, value, highlights=None,
validation_level=None):
super(ST, self).__init__(value, 199, highlights, validation_level)
Expand All @@ -344,6 +350,7 @@ class FT(TextualDataType):
:attr:`max_length` is 65536
"""

def __init__(self, value, highlights=None,
validation_level=None):
super(FT, self).__init__(value, 65536, highlights, validation_level)
Expand All @@ -356,6 +363,7 @@ class ID(TextualDataType):
:attr:`max_length` None
"""

def __init__(self, value, highlights=None,
validation_level=None):
# max_length is None bacause it depends from the HL7 table
Expand All @@ -370,6 +378,7 @@ class IS(TextualDataType):
:attr:`max_length` is 20
"""

def __init__(self, value, highlights=None,
validation_level=None):
super(IS, self).__init__(value, 20, highlights, validation_level)
Expand All @@ -383,6 +392,7 @@ class TX(TextualDataType):
:attr:`max_length` is 65536
"""

def __init__(self, value, highlights=None,
validation_level=None):
super(TX, self).__init__(value, 65536, highlights, validation_level)
Expand All @@ -395,6 +405,7 @@ class GTS(TextualDataType):
:attr:`max_length` is 199
"""

def __init__(self, value, highlights=None,
validation_level=None):
super(GTS, self).__init__(value, 199, highlights, validation_level)
Expand Down Expand Up @@ -423,14 +434,15 @@ def __init__(self, value=None,

class SI(NumericDataType):
"""
Class for NM datatype. It extends NumericDatatype and the parameters are the same of the superclass
Class for SI datatype. It extends NumericDatatype and the parameters are the same of the superclass
:attr:`max_length` is 4.
The type of ``value`` must be `int` or :class:`numbers.Integral`
:raise: :exc:`ValueError` raised when the value is not of one of the correct type
"""

def __init__(self, value=None,
validation_level=None):
if value is not None and not isinstance(value, numbers.Integral):
Expand All @@ -450,8 +462,8 @@ class TN(TextualDataType):
:raise: :exc:`ValueError` raised when the value does not match the expected format
"""
def __init__(self, value, validation_level=None):

def __init__(self, value, validation_level=None):
regexp = r'(\d\d\s)?(\(\d+\))?(\d+-?\d+)(X\d+)?(B\d+)?(C.+)?'
if not re.match(regexp, value):
raise ValueError('Invalid value for TN data')
Expand Down
4 changes: 2 additions & 2 deletions hl7apy/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ def _valid_child_name(child_name, expected_parent):
def _valid_z_message_name(name):
if name is None:
return False
regex = '^z[a-z0-9]{2}_z[a-z0-9]{2}$'
regex = r'^z[a-z0-9]{2}_z[a-z0-9]{2}$'
return re.match(regex, name, re.IGNORECASE) is not None


Expand All @@ -114,7 +114,7 @@ def _valid_z_segment_name(name):


def _valid_z_field_name(name):
regex = '^z[a-z1-9]{2}_\d+$'
regex = r'^z[a-z1-9]{2}_\d+$'
return re.match(regex, name, re.IGNORECASE) is not None


Expand Down
2 changes: 1 addition & 1 deletion hl7apy/exceptions.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ class ValidationError(HL7apyException):
>>> from hl7apy.parser import parse_message
>>> from hl7apy.validation import VALIDATION_LEVEL
>>> msh = 'MSH|^~\&|SENDING APP|SENDING FAC|REC APP|REC FAC|20080115153000||ADT^A01^ADT_A01|' \
>>> msh = 'MSH|^~\\&|SENDING APP|SENDING FAC|REC APP|REC FAC|20080115153000||ADT^A01^ADT_A01|' \
'0123456789|P|2.5||||AL\\r'
>>> evn = 'EVN||20080115153000||AAA|AAA|20080114003000\\r'
>>> pid = 'PID|1||123-456-789^^^HOSPITAL^MR||SURNAME^NAME^A|||M|||1111 SOMEWHERE STREET^^SOMEWHERE^^^USA||' \
Expand Down
1 change: 0 additions & 1 deletion hl7apy/factories.py
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,6 @@ def datatype_factory(datatype, value, version=None, validation_level=None):
except KeyError:
raise InvalidDataType(datatype)
except ValueError as e:
print(e)
if Validator.is_strict(validation_level):
raise e
# TODO: Do we really want this? In that case the parent's datatype must be changed accordingly
Expand Down
4 changes: 2 additions & 2 deletions hl7apy/parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ def parse_message(message, validation_level=None, find_groups=True, message_prof
:return: an instance of :class:`Message <hl7apy.core.Message>`
>>> message = "MSH|^~\&|GHH_ADT||||20080115153000||OML^O33^OML_O33|0123456789|P|2.5||||AL\\rPID|1||" \
>>> message = "MSH|^~\\&|GHH_ADT||||20080115153000||OML^O33^OML_O33|0123456789|P|2.5||||AL\\rPID|1||" \
"566-554-3423^^^GHH^MR||EVERYMAN^ADAM^A|||M|||2222 HOME STREET^^ANN ARBOR^MI^^USA||555-555-2004|||M\\r"
>>> m = parse_message(message)
>>> print(m)
Expand Down Expand Up @@ -634,7 +634,7 @@ def parse_subcomponent(text, name=None, datatype='ST', version=None, validation_


def _split_msh(content):
m = re.match("^MSH(?P<field_sep>\S)", content)
m = re.match(r"^MSH(?P<field_sep>\S)", content)
if m is not None: # if the regular expression matches, it is an HL7 message
field_sep = m.group('field_sep') # get the field separator (first char after MSH)
msh = content.split("\r", 1)[0] # get the first segment
Expand Down
2 changes: 1 addition & 1 deletion hl7apy/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ def get_datetime_info(value):


def _split_offset(value):
offset = re.search('\d*((\+(1[0-4]|0[0-9])|(-(1[0-2]|0[0-9])))([0-5][0-9]))$', value)
offset = re.search(r'\d*((\+(1[0-4]|0[0-9])|(-(1[0-2]|0[0-9])))([0-5][0-9]))$', value)
if offset:
offset = offset.groups()[0]
return value.replace(offset, ''), offset
Expand Down
Loading

0 comments on commit 9550b6e

Please sign in to comment.