Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update code/test to work with latest Python 3.12 and add CI #68

Merged
merged 9 commits into from
Jan 23, 2025
Merged
Show file tree
Hide file tree
Changes from 8 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
35 changes: 35 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
name: Run Unit Tests

on:
push:
branches:
- main
pull_request:
workflow_dispatch:

jobs:
test:
runs-on: ubuntu-latest

steps:
# Step 1: Check out the code
- name: Checkout code
uses: actions/checkout@v3

# Step 2: Set up Python
- name: Set up Python
uses: actions/setup-python@v4
with:
python-version: '3.12' # Specify the Python version you want to use

# Step 3: Install dependencies
- name: Install dependencies
run: |
python -m pip install --upgrade pip setuptools pytest
pip install -r requirements.txt || true # In case requirements.txt doesn't exist

# Step 4: Run tests
- name: Run tests
run: |
pip3 install ".[tests]"
pytest
9 changes: 5 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
ZSchema
=======

[![Build Status](https://travis-ci.org/zmap/zschema.svg?branch=master)](https://travis-ci.org/zmap/zschema)

ZSchema is a generic (meta-)schema language for defining database schemas. It
facilitates (1) validating JSON documents against a schema definition and (2)
compilating a schema to multiple database engines. For example, if you wanted
Expand Down Expand Up @@ -188,8 +186,11 @@ https://github.com/zmap/zschema/blob/master/zschema/leaves.py#L25.
Running Tests
=============

Tests are run with [nose](http://nose.readthedocs.io/en/latest/). Run them via
`python setup.py test`.
Tests are run with [pytest](https://docs.pytest.org/en/stable/). Run them via:
```zsh
pip3 install ".[tests]"
pytest
```


License and Copyright
Expand Down
26 changes: 26 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
[build-system]
requires = ["setuptools>=42"]
build-backend = "setuptools.build_meta"

[project]
name = "zschema"
description = "A schema language for JSON documents that allows validation and compilation into various database engines"
version = "0.11.0"
authors = [ { name = "ZMap Team"} ]
license = { text = "Apache License, Version 2.0" } # Replace with the actual license
keywords = ["python", "json", "schema", "bigquery", "elasticsearch"]

dependencies = [
"future",
"python-dateutil",
"pytz",
"six"
]

[project.optional-dependencies]
tests = [
"pytest"
]

[project.scripts]
zschema = "zschema.__main__:main"
41 changes: 0 additions & 41 deletions setup.py

This file was deleted.

2 changes: 1 addition & 1 deletion zschema/keys.py
Original file line number Diff line number Diff line change
Expand Up @@ -211,7 +211,7 @@ def _handle_validation_exception(policy, e):
logging.error(e.message)
raise e
elif policy == "warn":
logging.warn(e.message)
logging.warning(e.message)
elif policy == "ignore":
pass
else:
Expand Down
21 changes: 14 additions & 7 deletions zschema/leaves.py
Original file line number Diff line number Diff line change
Expand Up @@ -516,6 +516,13 @@ class DateTime(Leaf):
# dateutil.parser.parse(int) throws...? is this intended to be a unix epoch offset?
EXPECTED_CLASS = string_types + (int, datetime.datetime)

TZINFOS = {
"EDT": datetime.timezone(datetime.timedelta(hours=-4)), # Eastern Daylight Time
"EST": datetime.timezone(datetime.timedelta(hours=-5)), # Eastern Standard Time
'CDT': datetime.timezone(datetime.timedelta(hours=-5)), # Central Daylight Time
'CST': datetime.timezone(datetime.timedelta(hours=-6)), # Central Standard Time
}

VALID = "Wed Jul 8 08:52:01 EDT 2015"
INVALID = "Wed DNE 35 08:52:01 EDT 2015"

Expand All @@ -526,23 +533,23 @@ def __init__(self, *args, **kwargs):
super(DateTime, self).__init__(*args, **kwargs)

if self.min_value:
self._min_value_dt = dateutil.parser.parse(self.min_value)
self._min_value_dt = dateutil.parser.parse(self.min_value, tzinfos=self.TZINFOS)
else:
self._min_value_dt = dateutil.parser.parse(self.MIN_VALUE)
self._min_value_dt = dateutil.parser.parse(self.MIN_VALUE, tzinfos=self.TZINFOS)

if self.max_value:
self._max_value_dt = dateutil.parser.parse(self.max_value)
self._max_value_dt = dateutil.parser.parse(self.max_value, tzinfos=self.TZINFOS)
else:
self._max_value_dt = dateutil.parser.parse(self.MAX_VALUE)
self._max_value_dt = dateutil.parser.parse(self.MAX_VALUE, tzinfos=self.TZINFOS)

def _validate(self, name, value, path=_NO_ARG):
try:
if isinstance(value, datetime.datetime):
dt = value
elif isinstance(value, int):
dt = datetime.datetime.utcfromtimestamp(value)
dt = datetime.datetime.fromtimestamp(value, datetime.timezone.utc)
else:
dt = dateutil.parser.parse(value)
dt = dateutil.parser.parse(value, tzinfos=self.TZINFOS)
except (ValueError, TypeError):
# Either `datetime.utcfromtimestamp` or `dateutil.parser.parse` above
# may raise on invalid input.
Expand Down Expand Up @@ -577,7 +584,7 @@ class OID(String):
VALID = "1.3.6.1.4.868.2.4.1"
INVALID = "hello"

OID_REGEX = re.compile("[[0-9]+\\.]*")
OID_REGEX = re.compile(r"^(\d+\.)+\d+$")

def _is_oid(self, data):
return bool(self.OID_REGEX.match(data))
Expand Down
16 changes: 8 additions & 8 deletions zschema/tests.py → zschema/test_zschema.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import collections
from collections.abc import Sized
import datetime
import json
import os
Expand Down Expand Up @@ -352,10 +352,10 @@ def assertBigQuerySchemaEqual(self, a, b):
if a == b:
return
else:
self.assertEquals(type(a), type(b))
if isinstance(a, collections.Sized) \
and isinstance(b, collections.Sized):
self.assertEquals(len(a), len(b))
self.assertEqual(type(a), type(b))
if isinstance(a, Sized) \
and isinstance(b, Sized):
self.assertEqual(len(a), len(b))
if isinstance(a, list) and isinstance(b, list):
name_ordered_a = sorted(a, key=lambda x: x['name'])
name_ordered_b = sorted(b, key=lambda x: x['name'])
Expand All @@ -366,7 +366,7 @@ def assertBigQuerySchemaEqual(self, a, b):
self.assertIn(k, b)
self.assertBigQuerySchemaEqual(a[k], b[k])
else:
self.assertEquals(a, b)
self.assertEqual(a, b)

def setUp(self):
self.maxDiff=10000
Expand Down Expand Up @@ -514,7 +514,7 @@ def test_merge_recursive(self):
"b":String()
})
})
self.assertEquals(a.merge(b).to_dict(), c.to_dict())
self.assertEqual(a.merge(b).to_dict(), c.to_dict())

def test_extends(self):
host = Record({
Expand Down Expand Up @@ -988,7 +988,7 @@ def test_bad_root(self):
self.SCHEMA.validate(bad1, policy="error")
self.assertTrue(False, "bad1 failed to fail")
except DataValidationException as e:
self.assertEquals(e.path, ["b"])
self.assertEqual(e.path, ["b"])


def test_bad_a_key(self):
Expand Down
Loading