Skip to content

Commit

Permalink
Release 3.11.0.0 (#80)
Browse files Browse the repository at this point in the history
* Release 3.11.0.0
  • Loading branch information
avanov authored Mar 8, 2023
1 parent fdc6157 commit 21b5ae8
Show file tree
Hide file tree
Showing 14 changed files with 190 additions and 96 deletions.
4 changes: 3 additions & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,9 @@ jobs:
tests:
strategy:
matrix:
python-version: [ 310 ]
python-version:
- 310
- 311
runs-on: ubuntu-latest
steps:
- uses: actions/[email protected]
Expand Down
6 changes: 6 additions & 0 deletions CHANGELOG.rst
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,12 @@
CHANGELOG
=========

3.11.0.0
========

* Support for Python 3.11


3.9.1.9
=======

Expand Down
58 changes: 58 additions & 0 deletions default.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
{ pyVersion ? "311"
, isDevEnv ? true
}:

let
commonEnv = import ./nixpkgs {};
pkgs = commonEnv.pkgs;

python = pkgs."python${pyVersion}";
pythonPkgs = pkgs."python${pyVersion}Packages";
devLibs = if isDevEnv then [ pythonPkgs.twine pythonPkgs.wheel ] else [ pythonPkgs.coveralls ];

# Make a new "derivation" that represents our shell
devEnv = pkgs.mkShellNoCC {
name = "typeit";

# The packages in the `buildInputs` list will be added to the PATH in our shell
# Python-specific guide:
# https://github.com/NixOS/nixpkgs/blob/master/doc/languages-frameworks/python.section.md
nativeBuildInputs = with pkgs; [
# see https://nixos.org/nixos/packages.html
# Python distribution
python
pythonPkgs.virtualenv
ncurses
libxml2
libxslt
libzip
zlib
which
] ++ devLibs;
shellHook = ''
# set SOURCE_DATE_EPOCH so that we can use python wheels
export SOURCE_DATE_EPOCH=$(date +%s)
export VENV_DIR="$PWD/.venv${pyVersion}"
export PATH=$VENV_DIR/bin:$PATH
export PYTHONPATH=""
export LANG=en_US.UTF-8
# https://python-poetry.org/docs/configuration/
export PIP_CACHE_DIR="$PWD/.local/pip-cache${pyVersion}"
# Setup virtualenv
if [ ! -d $VENV_DIR ]; then
virtualenv $VENV_DIR
pip install -r requirements/minimal.txt
pip install -r requirements/test.txt
pip install -r requirements/extras/third_party.txt
fi
'';
};
in

{
inherit devEnv;
}
19 changes: 19 additions & 0 deletions nixpkgs/default.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
{}:

let

common-src = builtins.fetchTarball {
name = "common-2023-03-03";
url = https://github.com/avanov/nix-common/archive/a30f466f3ac73842d111e80f40f287d8aa13e929.tar.gz;
# Hash obtained using `nix-prefetch-url --unpack <url>`
sha256 = "sha256:1dimd334ay4jx4n81n5ms8p4i9kpyn0z7mm8xa0kcy2cpdlbq798";
};

overlays = import ./overlays.nix {};
pkgs = (import common-src { projectOverlays = [ overlays.globalPackageOverlay ]; }).pkgs;

in

{
inherit pkgs;
}
13 changes: 13 additions & 0 deletions nixpkgs/overlays.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{}:

let

globalPackageOverlay = (self: original: rec {
# Place overrides here as described in https://nixos.wiki/wiki/Overlays#Examples_of_overlays
});

in

{
inherit globalPackageOverlay;
}
8 changes: 4 additions & 4 deletions requirements/minimal.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
inflection>=0.4.0,<0.6.0
colander>=1.7.0,<1.9.0
pyrsistent>=0.18.1,<0.19
typing-inspect>=0.7.1,<0.8.0
typing-extensions>=4.2,<4.3
colander>=1.7.0,<2.1
pyrsistent>=0.19.3
typing-inspect>=0.7.1,<0.9
typing-extensions>=4.2,<4.6
6 changes: 3 additions & 3 deletions requirements/test.txt
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
-r ./minimal.txt
pytest>=7.1,<7.2
coverage>=6.4,<6.5
pytest>=7.1,<7.3
coverage>=6.4,<7.3
coveralls>=3.3,<3.4
pytest-cov>=3.0,<3.1
pytest-cov>=3.0,<4.1
mypy==0.961
py-money==0.5.0
requests>=2.28
Expand Down
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ def requirements(at_path: Path):
# ----------------------------

setup(name='typeit',
version='3.10.0.0',
version='3.11.0.0',
description='typeit brings typed data into your project',
long_description=README,
classifiers=[
Expand Down
58 changes: 2 additions & 56 deletions shell.nix
Original file line number Diff line number Diff line change
@@ -1,58 +1,4 @@
{
pkgs ? (import (builtins.fetchGit {
url = "https://github.com/avanov/nix-common.git";
ref = "master";
rev = "be2dc05bf6beac92fc12da9a2adae6994c9f2ee6";
}) {}).pkgs
, pyVersion ? "310"
, isDevEnv ? true
}:

let

python = pkgs."python${pyVersion}";
pythonPkgs = pkgs."python${pyVersion}Packages";
devLibs = if isDevEnv then [ pythonPkgs.twine pythonPkgs.wheel ] else [ pythonPkgs.coveralls ];
repository = import ./default.nix {};
in

# Make a new "derivation" that represents our shell
pkgs.mkShellNoCC {
name = "typeit";

# The packages in the `buildInputs` list will be added to the PATH in our shell
# Python-specific guide:
# https://github.com/NixOS/nixpkgs/blob/master/doc/languages-frameworks/python.section.md
nativeBuildInputs = with pkgs; [
# see https://nixos.org/nixos/packages.html
# Python distribution
python
pythonPkgs.virtualenv
ncurses
libxml2
libxslt
libzip
zlib
which
] ++ devLibs;
shellHook = ''
# set SOURCE_DATE_EPOCH so that we can use python wheels
export SOURCE_DATE_EPOCH=$(date +%s)
export VENV_DIR="$PWD/.venv${pyVersion}"
export PATH=$VENV_DIR/bin:$PATH
export PYTHONPATH=""
export LANG=en_US.UTF-8
# https://python-poetry.org/docs/configuration/
export PIP_CACHE_DIR="$PWD/.local/pip-cache${pyVersion}"
# Setup virtualenv
if [ ! -d $VENV_DIR ]; then
virtualenv $VENV_DIR
pip install -r requirements/minimal.txt
pip install -r requirements/test.txt
pip install -r requirements/extras/third_party.txt
fi
'';
}
repository.devEnv
6 changes: 4 additions & 2 deletions tests/test_pyrsistent.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,15 @@ class X(NamedTuple):
a: ps.typing.PMap[str, Any]
b: ps.typing.PVector[ps.typing.PMap[str, Any]]
c: Optional[ps.typing.PMap[str, Any]]
d: Optional[ps.typing.PMap]

mk_x, serialize_x = ty.TypeConstructor ^ X
mk_x, serialize_x = ty.type_constructor ^ X

data = {
'a': {'x': 'x', 'y': 'y'},
'b': [{'x': 'x', 'y': 'y'}],
'c': None
'c': None,
'd': {'a': 1}
}
x = mk_x(data)
assert isinstance(x.a, ps.PMap)
Expand Down
16 changes: 15 additions & 1 deletion tests/test_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -75,4 +75,18 @@ class X(NamedTuple):
try:
serialize_x(x)
except typeit.Error as e:
x = list(e)
x = list(e)


def test_new_init():
class X(NamedTuple):
a: int
b: bool

a = 1
b = True
res = utils.new(X)
assert res.a == a
assert res.b == b

res1 = utils.new(X, res)
46 changes: 20 additions & 26 deletions typeit/parser/__init__.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
from types import UnionType
from typing import (
Type, Tuple, Optional, Any, Union, List, Set,
Dict, Sequence, get_type_hints,
MutableSet, TypeVar, FrozenSet, Mapping, NamedTuple, ForwardRef, NewType,
Dict, Sequence, MutableSet, TypeVar, FrozenSet, Mapping, ForwardRef, NewType,
)

import inspect
Expand All @@ -12,6 +11,8 @@
from pyrsistent import pmap, pvector
from pyrsistent import typing as pyt

from .type_info import get_type_attribute_info, AttrInfo, NoneType

from ..compat import Literal
from ..definitions import OverridesT
from ..utils import is_named_tuple, clone_schema_node, get_global_name_overrider
Expand All @@ -25,9 +26,6 @@
T = TypeVar('T')
MemoType = TypeVar('MemoType')

NoneType = type(None)


OverrideT = ( flags._Flag # flag override
| TypeExtension # new type extension
| Union[
Expand Down Expand Up @@ -442,15 +440,23 @@ def _maybe_node_for_dict(
if typ in supported_type or get_origin_39(typ) in supported_origin or are_generic_bases_match(generic_bases, supported_origin):
schema_node_type = schema.nodes.PMapSchema if is_pmap(typ) else schema.nodes.SchemaNode

if generic_bases:
# python 3.9 args
key_type, value_type = typ.__args__
else:
def maybe_non_specified_arguments(mappingType):
try:
key_type, value_type = insp.get_args(typ)
kt, kv = insp.get_args(mappingType)
except ValueError:
# Mapping doesn't provide key/value types
key_type, value_type = Any, Any
kt, kv = Any, Any
return kt, kv

if generic_bases:
# python 3.9 args
try:
key_type, value_type = typ.__args__
except AttributeError:
# PMap without clarifying type arguments will cause this branch
key_type, value_type = maybe_non_specified_arguments(typ)
else:
key_type, value_type = maybe_non_specified_arguments(typ)

key_node, memo, forward_refs = decide_node_type(key_type, overrides, memo, forward_refs)
value_node, memo, forward_refs = decide_node_type(value_type, overrides, memo, forward_refs)
Expand All @@ -459,18 +465,6 @@ def _maybe_node_for_dict(
return rv, memo, forward_refs


class AttrInfo(NamedTuple):
name: str
resolved_type: Type
raw_type: Union[Type, ForwardRef]


def _type_hints_getter(typ: Type) -> Sequence[AttrInfo]:
raw = getattr(typ, '__annotations__', {})
existing_only = lambda x: x[1] is not NoneType
return [AttrInfo(name, t, raw.get(name, t)) for name, t in filter(existing_only, get_type_hints(typ).items())]


def _maybe_node_for_user_type(
typ: Type[iface.IType],
overrides: OverridesT,
Expand All @@ -495,7 +489,7 @@ def _maybe_node_for_user_type(
type_var_to_type = pmap(zip(generic_vars_ordered, bound_type_args))
# resolve type hints
attribute_hints = [(field_name, type_var_to_type[type_var])
for field_name, type_var in ((x, raw_type) for x, _resolved_type, raw_type in _type_hints_getter(hints_source))]
for field_name, type_var in ((x, raw_type) for x, _resolved_type, raw_type in get_type_attribute_info(hints_source))]
# Generic types should not have default values
defaults_source = lambda: ()
# Overrides should be the same as class-based ones, as Generics are not NamedTuple classes,
Expand All @@ -516,7 +510,7 @@ def _maybe_node_for_user_type(

elif is_named_tuple(typ):
hints_source = typ
attribute_hints = [(x, raw_type) for x, y, raw_type in _type_hints_getter(hints_source)]
attribute_hints = [(x, raw_type) for x, y, raw_type in get_type_attribute_info(hints_source)]
get_override_identifier = lambda x: getattr(typ, x)
defaults_source = typ.__new__

Expand All @@ -537,7 +531,7 @@ def _maybe_node_for_user_type(
else:
# use init-based types
hints_source = typ.__init__
attribute_hints = [(x, raw_type) for x, y, raw_type in _type_hints_getter(hints_source)]
attribute_hints = [(x, raw_type) for x, y, raw_type in get_type_attribute_info(hints_source)]
get_override_identifier = lambda x: (typ, x)
defaults_source = typ.__init__

Expand Down
15 changes: 15 additions & 0 deletions typeit/parser/type_info.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
from typing import Type, get_type_hints, NamedTuple, Union, ForwardRef, Any, Generator

NoneType = type(None)


class AttrInfo(NamedTuple):
name: str
resolved_type: Type
raw_type: Union[Type, ForwardRef]


def get_type_attribute_info(typ: Type) -> Generator[AttrInfo, Any, None]:
raw = getattr(typ, '__annotations__', {})
existing_only = lambda x: x[1] is not NoneType
return (AttrInfo(name, t, raw.get(name, t)) for name, t in filter(existing_only, get_type_hints(typ).items()))
Loading

0 comments on commit 21b5ae8

Please sign in to comment.