Skip to content

Commit

Permalink
AVRO-2921: Strict Type Checking
Browse files Browse the repository at this point in the history
  • Loading branch information
kojiromike committed Aug 30, 2020
1 parent caa3a42 commit e1cd422
Show file tree
Hide file tree
Showing 43 changed files with 2,353 additions and 159 deletions.
57 changes: 57 additions & 0 deletions lang/py/avro/codecs.pyi
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
#!/usr/bin/env python3
# -*- mode: python -*-
# -*- coding: utf-8 -*-

##
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
# https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

"""
Contains Codecs for Python Avro.
Note that the word "codecs" means "compression/decompression algorithms" in the
Avro world (https://avro.apache.org/docs/current/spec.html#Object+Container+Files),
so don't confuse it with the Python's "codecs", which is a package mainly for
converting charsets (https://docs.python.org/3/library/codecs.html).
"""

import abc
from typing import List

import avro.io

class Codec(abc.ABC):
"""Abstract base class for all Avro codec classes."""

def compress(self, data: bytes) -> bytes:
...

def decompress(self, readers_decoder: avro.io.BinaryDecoder) -> avro.io.BinaryDecoder:
...


class SnappyCodec(Codec):

def check_crc32(self, bytes_: bytes, checksum: bytes) -> None:
...


def get_codec(codec_name: str) -> Codec:
...


def supported_codec_names() -> List[str]:
...
130 changes: 130 additions & 0 deletions lang/py/avro/datafile.pyi
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
#!/usr/bin/env python3
# -*- mode: python -*-
# -*- coding: utf-8 -*-

##
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
# https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

from types import TracebackType
from typing import *

from avro.io import BinaryDecoder, BinaryEncoder, DatumReader, DatumWriter
from avro.schema import Schema
from avro.types import AvroAny

VALID_CODECS = () # type: Sequence[str]


class _DataFile:
def __exit__(self, type: Type[BaseException], value: BaseException, traceback: TracebackType) -> None:
...
def get_meta(self, key: str) -> bytes:
...
def set_meta(self, key: str, val: bytes) -> None:
...
@property
def sync_marker(self) -> int:
...
@property
def meta(self) -> Dict[str, bytes]:
...
@property
def codec(self) -> str:
...
@codec.setter
def codec(self, value: str) -> None:
...
@property
def schema(self) -> Schema:
...
@schema.setter
def schema(self, value: Schema) -> None:
...


class DataFileWriter(_DataFile):
def __init__(self, writer: BinaryIO, datum_writer: DatumWriter, writers_schema: Optional[Schema], codec: str) -> None:
...
def __enter__(self) -> "DataFileWriter":
...
@property
def writer(self) -> BinaryIO:
...
@property
def encoder(self) -> BinaryEncoder:
...
@property
def datum_writer(self) -> DatumWriter:
...
@property
def buffer_writer(self) -> BinaryIO:
...
@property
def buffer_encoder(self) -> BinaryEncoder:
...
def _write_header(self) -> None:
...
def _write_block(self) -> None:
...
def append(self, datum: AvroAny) -> None:
...
def sync(self) -> int:
...
def flush(self) -> None:
...
def close(self) -> None:
...

class DataFileReader(_DataFile):
def __init__(self, reader: BinaryIO, datum_reader: DatumReader) -> None:
...
def __iter__(self) -> "DataFileReader":
...
def __enter__(self) -> "DataFileReader":
...
@property
def reader(self) -> BinaryIO:
...
@property
def raw_decoder(self) -> BinaryDecoder:
...
@property
def datum_decoder(self) -> BinaryDecoder:
...
@property
def datum_reader(self) -> DatumReader:
...
@property
def file_length(self) -> int:
...
def determine_file_length(self) -> int:
...
def is_EOF(self) -> bool:
...
def _read_header(self) -> None:
...
def _read_block_header(self) -> None:
...
def _skip_sync(self) -> bool:
...
def __next__(self) -> AvroAny:
...
def close(self) -> None:
...

def generate_sixteen_random_bytes() -> bytes:
...
83 changes: 83 additions & 0 deletions lang/py/avro/errors.pyi
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
#!/usr/bin/env python3
# -*- mode: python -*-
# -*- coding: utf-8 -*-

##
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
# https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

from typing import Optional

import avro.schema
import avro.types

class AvroException(Exception):
"""The base class for exceptions in avro."""


class SchemaParseException(AvroException):
"""Raised when a schema failed to parse."""


class InvalidName(SchemaParseException):
"""User attempted to parse a schema with an invalid name."""


class AvroWarning(UserWarning):
"""Base class for warnings."""


class IgnoredLogicalType(AvroWarning):
"""Warnings for unknown or invalid logical types."""


class AvroTypeException(AvroException):
def __init__(self,
expected_schema: avro.schema.Schema,
datum: avro.types.AvroAny) -> None:
...


class SchemaResolutionException(AvroException):
def __init__(self,
fail_msg: str,
writers_schema: Optional[avro.schema.Schema]=None,
readers_schema: Optional[avro.schema.Schema]=None) -> None:
...


class DataFileException(AvroException):
"""Raised when there's a problem reading or writing file object containers."""


class AvroRemoteException(AvroException):
"""Raised when an error message is sent by an Avro requestor or responder."""


class ConnectionClosedException(AvroException):
"""Raised when attempting IPC on a closed connection."""


class ProtocolParseException(AvroException):
"""Raised when a protocol failed to parse."""


class UnsupportedCodec(NotImplementedError, AvroException):
"""Raised when the compression named cannot be used."""


class UsageError(RuntimeError, AvroException):
"""An exception raised when incorrect arguments were passed."""
18 changes: 10 additions & 8 deletions lang/py/avro/io.py
Original file line number Diff line number Diff line change
Expand Up @@ -432,8 +432,9 @@ def __init__(self, writer):
"""
self._writer = writer

# read-only properties
writer = property(lambda self: self._writer)
@property
def writer(self):
return self._writer

def write(self, datum):
"""Write an arbitrary datum."""
Expand All @@ -443,7 +444,6 @@ def write_null(self, datum):
"""
null is written as zero bytes
"""
pass

def write_boolean(self, datum):
"""
Expand Down Expand Up @@ -991,11 +991,13 @@ class DatumWriter:
def __init__(self, writers_schema=None):
self._writers_schema = writers_schema

# read/write properties
def set_writers_schema(self, writers_schema):
self._writers_schema = writers_schema
writers_schema = property(lambda self: self._writers_schema,
set_writers_schema)
@property
def writers_schema(self):
return self._writers_schema

@writers_schema.setter
def writers_schema(self, schema):
self._writers_schema = schema

def write(self, datum, encoder):
validate(self.writers_schema, datum, raise_on_error=True)
Expand Down
Loading

0 comments on commit e1cd422

Please sign in to comment.