diff --git a/schema_salad/codegen.py b/schema_salad/codegen.py index b0c1ab07..7196f7ee 100644 --- a/schema_salad/codegen.py +++ b/schema_salad/codegen.py @@ -43,6 +43,11 @@ def codegen( gen = None # type: Optional[CodeGenBase] base = schema_metadata.get("$base", schema_metadata.get("id")) + # ``urlsplit`` decides whether to return an encoded result based + # on the object type. To ensure the code behaves the same for Py + # 3.6+, we enforce that the input value is of type ``str``. + if base is None: + base = "" sp = urlsplit(base) pkg = ( package diff --git a/schema_salad/tests/basket.yml b/schema_salad/tests/basket.yml new file mode 100644 index 00000000..bd8efc72 --- /dev/null +++ b/schema_salad/tests/basket.yml @@ -0,0 +1,9 @@ +# N.B.: this example is used in a test that needs a file without $base, +# so please do not include $base here. +- name: Basket + doc: A basket of products. + type: record + documentRoot: true + fields: + product: string + price: float diff --git a/schema_salad/tests/test_java_codegen.py b/schema_salad/tests/test_java_codegen.py index 20e53ba1..6692093b 100644 --- a/schema_salad/tests/test_java_codegen.py +++ b/schema_salad/tests/test_java_codegen.py @@ -2,10 +2,10 @@ from pathlib import Path from typing import Any, Dict, List, Optional, cast -from schema_salad import codegen, ref_resolver +from schema_salad import codegen from schema_salad.schema import load_schema -from .util import get_data +from .util import cwl_file_uri, metaschema_file_uri, get_data def test_cwl_gen(tmp_path: Path) -> None: @@ -41,16 +41,6 @@ def test_meta_schema_gen(tmp_path: Path) -> None: assert src_dir.exists() -def get_data_uri(resource_path: str) -> str: - path = get_data(resource_path) - assert path - return ref_resolver.file_uri(path) - - -cwl_file_uri = get_data_uri("tests/test_schema/CommonWorkflowLanguage.yml") -metaschema_file_uri = get_data_uri("metaschema/metaschema.yml") - - def java_codegen(file_uri: str, target: Path, examples: Optional[Path] = None) -> None: document_loader, avsc_names, schema_metadata, metaschema_loader = load_schema( file_uri diff --git a/schema_salad/tests/test_python_codegen.py b/schema_salad/tests/test_python_codegen.py index dcb11798..3f504590 100644 --- a/schema_salad/tests/test_python_codegen.py +++ b/schema_salad/tests/test_python_codegen.py @@ -8,7 +8,7 @@ from schema_salad.avro.schema import Names from schema_salad.schema import load_schema -from .test_java_codegen import cwl_file_uri, metaschema_file_uri +from .util import cwl_file_uri, metaschema_file_uri, basket_file_uri def test_cwl_gen(tmp_path: Path) -> None: @@ -35,6 +35,14 @@ def test_meta_schema_gen_up_to_date(tmp_path: Path) -> None: assert f.read() == inspect.getsource(cg_metaschema) +def test_meta_schema_gen_no_base(tmp_path: Path) -> None: + src_target = tmp_path / "src.py" + python_codegen(basket_file_uri, src_target) + assert os.path.exists(src_target) + with open(src_target) as f: + assert "class Basket" in f.read() + + def python_codegen( file_uri: str, target: Path, diff --git a/schema_salad/tests/util.py b/schema_salad/tests/util.py index 53d1c38d..13b9548b 100644 --- a/schema_salad/tests/util.py +++ b/schema_salad/tests/util.py @@ -2,9 +2,15 @@ from typing import Optional, Text from pkg_resources import Requirement, ResolutionError, resource_filename +from schema_salad import ref_resolver def get_data(filename): # type: (Text) -> Optional[Text] + """Get the file path for a given schema file name. + + It is able to find file names in the ``schema_salad`` namespace, but + also able to load schema files from the ``tests`` directory. + """ filename = os.path.normpath(filename) # normalizing path depending on OS # or else it will cause problem when joining path filepath = None @@ -13,5 +19,25 @@ def get_data(filename): # type: (Text) -> Optional[Text] except ResolutionError: pass if not filepath or not os.path.isfile(filepath): - filepath = os.path.join(os.path.dirname(__file__), os.pardir, filename) + # First try to load it from the local directory, probably ``./tests/``. + filepath = os.path.join(os.path.dirname(__file__), filename) + if not os.path.isfile(filepath): + # If that didn't work, then default to tests/../${filename}, + # note that we return the parent as it is expected that __file__ + # is a test file. + filepath = os.path.join(os.path.dirname(__file__), os.pardir, filename) return filepath + + +def get_data_uri(resource_path: str) -> str: + """Get the file URI for tests.""" + path = get_data(resource_path) + assert path + return ref_resolver.file_uri(path) + + +# Schemas used in tests + +cwl_file_uri = get_data_uri("tests/test_schema/CommonWorkflowLanguage.yml") +metaschema_file_uri = get_data_uri("metaschema/metaschema.yml") +basket_file_uri = get_data_uri("basket.yml")