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: 1 addition & 1 deletion .github/workflows/packaging_test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ jobs:
runs-on: ${{ matrix.os }}
strategy:
matrix:
python-version: ["3.8", "3.9", "3.10", "3.11", "3.12"]
python-version: ["3.10", "3.11", "3.12", "3.13"]
os: [ubuntu-latest]
steps:
- uses: actions/checkout@v4
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/unittests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ jobs:
runs-on: ${{ matrix.os }}
strategy:
matrix:
python-version: ["3.8", "3.9", "3.10", "3.11", "3.12"]
python-version: ["3.10", "3.11", "3.12", "3.13"]
os: [ubuntu-latest]
steps:
- uses: actions/checkout@v4
Expand Down
3 changes: 1 addition & 2 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
language: python
python:
- 3.8
- 3.9
- 3.10
- 3.11
- 3.12
- 3.13
before_install:
- python --version
- pip install -U pip
Expand Down
5 changes: 3 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,14 @@ install:
build: dev
python -m build


upload: build
twine upload dist/*

test:
pytest --ignore tests/test_huge_message.py

mypy:
mypy --pretty pydifact

test-extended:
pytest

8 changes: 4 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ interchange = Interchange.from_str(
)
for message in interchange.get_messages():
for segment in message.segments:
print("Segment tag: {}, content: {}".format(segment.tag, segment.elements))
print(f"Segment tag: {segment.tag}, content: {segment.elements}")
```

You may also want to iterate directly on segments :
Expand All @@ -68,7 +68,7 @@ interchange = Interchange.from_str(
)

for segment in interchange.segments:
print("Segment tag: {}, content: {}".format(segment.tag, segment.elements))
print(f"Segment tag: {segment.tags}, content: {segment.elements}")
```

Or you can create an EDI interchange on the fly:
Expand Down Expand Up @@ -100,7 +100,7 @@ from pydifact.segmentcollection import RawSegmentCollection
collection = RawSegmentCollection.from_str("UNH+1+ORDERS:D:96A:UN:EAN008'")

for segment in collection.segments:
print("Segment tag: {}, content: {}".format(segment.tag, segment.elements))
print(f"Segment tag: {segment.tags}, content: {segment.elements}")
```


Expand All @@ -124,7 +124,7 @@ To develop pydifact, clone the repository and install the dev requirements:

```bash
make dev
# or
# or
# pip install -e .[dev]
```

Expand Down
5 changes: 1 addition & 4 deletions TODO.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,4 @@

* Translation of following files:
* Parser, ParserTest
* Message, MessageTest
* When Python 3.10 is adapted:
* replace Union[x,y] with x|y and Optional[x] with x|None in annotations
* use f-strings instead of .format-strings
* Message, MessageTest
4 changes: 0 additions & 4 deletions docs/API.rst
Original file line number Diff line number Diff line change
@@ -1,10 +1,6 @@
API
===

SegmentCollection
------------------
.. automodule:: pydifact.segmentcollection
:members:

Parser
------
Expand Down
1 change: 0 additions & 1 deletion pydifact/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@
__version__ = "0.1.8"

from .control.characters import Characters
from .segmentcollection import SegmentCollection
from .parser import Parser
from .segments import Segment
from .serializer import Serializer
Expand Down
7 changes: 3 additions & 4 deletions pydifact/control/characters.py
Original file line number Diff line number Diff line change
Expand Up @@ -82,13 +82,12 @@ def with_control_character(self, cc_type: str, char: str):
# set the attribute dynamically.
if not hasattr(self, cc_type):
raise AttributeError(
"{} doesn't have an attribute with the name '{}'".format(self, cc_type)
f"{self} doesn't have an attribute with the name '{cc_type}'"
)

other = copy(self)
setattr(other, cc_type, char)

# return clone
return other

@property
Expand All @@ -115,10 +114,10 @@ def __str__(self) -> str:
)

def __repr__(self):
return "'{}'".format(self.__str__())
return f"'{self.__str__()}'"

def __eq__(self, other):
if type(other) == str:
if isinstance(other, str):
other = Characters.from_str(other)
return (
(self.component_separator == other.component_separator)
Expand Down
51 changes: 28 additions & 23 deletions pydifact/parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,11 @@
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.
from typing import Optional, Generator, Any
from collections.abc import Iterator

from pydifact.tokenizer import Tokenizer
from pydifact.token import Token
from pydifact.segments import Segment, SegmentFactory
from pydifact.segments import Element, Elements, Segment, SegmentFactory
from pydifact.control import Characters


Expand All @@ -32,15 +32,15 @@ class Parser:

def __init__(
self,
factory: Optional[SegmentFactory] = None,
characters: Optional[Characters] = None,
):
factory: SegmentFactory | None = None,
characters: Characters | None = None,
) -> None:
self.factory = factory or SegmentFactory()
self.characters = characters or Characters()

def parse(
self, message: str, characters: Characters = None
) -> Generator[Segment, Any, None]:
self, message: str, characters: Characters | None = None
) -> Iterator[Segment]:
"""Parse the message into a list of segments.

:param characters: the control characters to use, if there is no
Expand Down Expand Up @@ -87,8 +87,8 @@ def parse(

@staticmethod
def get_control_characters(
message: str, characters: Characters = None
) -> Optional[Characters]:
message: str, characters: Characters | None = None
) -> Characters | None:
"""Read the UNA segment from the passed string and extract/store the control characters from it.

:param message: a valid EDI message string, or UNA segment string,
Expand All @@ -112,7 +112,6 @@ def get_control_characters(

# Get the character definitions
chars = message[3:9]
characters.is_extracted_from_message = True

characters.component_separator = chars[0]
characters.data_separator = chars[1]
Expand All @@ -124,8 +123,8 @@ def get_control_characters(
return characters

def convert_tokens_to_segments(
self, tokens: list, characters: Characters, with_una: bool = False
):
self, tokens: Iterator[Token], characters: Characters, with_una: bool = False
) -> Iterator[Segment]:
"""Convert the tokenized message into an array of segments.
:param tokens: The tokens that make up the message
:param characters: the control characters to use
Expand All @@ -134,9 +133,10 @@ def convert_tokens_to_segments(
:rtype list of Segment
"""

segments = []
current_segment = []
data_element = None
segments: list[Elements] = []
current_segment: Elements = []
data_element: list[str] = []
data_element_value: Element
in_segment = False
empty_component_counter = 0

Expand All @@ -149,12 +149,14 @@ def convert_tokens_to_segments(
if token.type == Token.Type.TERMINATOR:
in_segment = False
if len(data_element) == 0: # empty element
data_element = ""
if len(data_element) == 1:
data_element_value = ""
elif len(data_element) == 1:
# use a str instead of a list
data_element = data_element[0]
data_element_value = data_element[0]
else:
data_element_value = data_element

current_segment.append(data_element)
current_segment.append(data_element_value)
data_element = []
continue

Expand All @@ -174,11 +176,13 @@ def convert_tokens_to_segments(
# data_element to an empty list []
if token.type == Token.Type.DATA_SEPARATOR:
if len(data_element) == 0: # empty element
data_element = ""
data_element_value = ""
elif len(data_element) == 1:
data_element = data_element[0]
data_element_value = data_element[0]
else:
data_element_value = data_element

current_segment.append(data_element)
current_segment.append(data_element_value)

data_element = []
empty_component_counter = 0
Expand Down Expand Up @@ -210,4 +214,5 @@ def convert_tokens_to_segments(

for segment in segments:
name = segment.pop(0)
yield self.factory.create_segment(name, *segment)
# create_segment tests name type
yield self.factory.create_segment(name, *segment) # type: ignore
Empty file added pydifact/py.typed
Empty file.
Loading