Skip to content

Commit

Permalink
Merge pull request #236 from daler-sz/sqlalchemy-introspection
Browse files Browse the repository at this point in the history
Sqlalchemy introspection
  • Loading branch information
zhPavel authored Feb 12, 2024
2 parents 9f15132 + a093ca8 commit c1b8cfa
Show file tree
Hide file tree
Showing 70 changed files with 2,762 additions and 1,590 deletions.
2 changes: 2 additions & 0 deletions .flake8
Original file line number Diff line number Diff line change
Expand Up @@ -41,3 +41,5 @@ per-file-ignores=

*_312.py:E999
*tests/unit/morphing/model/shape_provider/data_gen_models.py:F821

tests/unit/provider/test_loc_stack_filtering.py:A001,A002
5 changes: 5 additions & 0 deletions docs/changelog/fragments/+loc_stack.breaking.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
Due to refactoring of predicate system required for new features:

1. ``create_request_checker`` was renamed to ``create_loc_stack_checker``
2. ``LocStackPattern`` (class of ``P``) was renamed ``RequestPattern``
3. method ``RequestPattern.build_request_checker()`` was renamed to ``LocStackPattern.build_loc_stack_checker()``
4 changes: 4 additions & 0 deletions docs/changelog/fragments/197.feature.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
Added flags support

Now adaptix has two different ways to process flags: :func:`.flag_by_exact_value` (by default)
and :func:`.flag_by_member_names`.
1 change: 1 addition & 0 deletions docs/changelog/fragments/216.feature.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Added defaultdict support
2 changes: 1 addition & 1 deletion docs/changelog/fragments/README.rst
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
This directory contains "news fragments" which are short files that contain a small **ReST**-formatted
text that will be added to the next ``CHANGELOG``.

The ``CHANGELOG`` will be read by **users**, so this description should be aimed to pytest users
The ``CHANGELOG`` will be read by **users**, so this description should be aimed to users
instead of describing internal changes which are only relevant to the developers.

Make sure to use full sentences in the **past or present tense** and use punctuation, examples::
Expand Down
1 change: 0 additions & 1 deletion docs/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,6 @@
add_function_parentheses = False

repo = git.Repo(search_parent_directories=True)
sha = repo.head.object.hexsha
benchmark_data_submodule = next(submodule for submodule in repo.submodules if submodule.name == 'benchmark-data')

extlinks = {
Expand Down
19 changes: 18 additions & 1 deletion docs/loading-and-dumping/specific-types-behavior.rst
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,18 @@ timedelta
Loader accepts instance of ``int``, ``float`` or ``Decimal`` representing seconds,
dumper serialize value via ``total_seconds`` method.

Enum subclasses

Flag subclasses
'''''''''''''''''''''''

Flag members by default are represented by their value. Note that flags with skipped
bits and negative values are not supported, so it is highly recommended to define flag
values via ``enum.auto()`` instead of manually specifying them.
Besides, adaptix provides another way to process flags: by list using their names.
See: :func:`.flag_by_member_names` for details.


Other Enum subclasses
'''''''''''''''''''''''

Enum members are represented by their value without any conversion.
Expand Down Expand Up @@ -216,6 +227,11 @@ Dict and Mapping
Loader accepts any other ``Mapping`` and makes ``dict`` instances.
Dumper also constructs dict with converted keys and values.

DefaultDict
'''''''''''''''''''''
Loader makes instances of ``defaultdict`` with the ``default_factory`` parameter set to ``None``.
To customize this behavior, there are factory :func:`.default_dict` that have :paramref:`.default_dict.default_factory` parameter that can be overridden.

Models
''''''''''

Expand Down Expand Up @@ -249,3 +265,4 @@ Known limitations:
- ``__init__`` introspection or using :func:`.constructor`

- Fields of unpacked typed dict (``**kwargs: Unpack[YourTypedDict]``) cannot collide with parameters of function

2 changes: 2 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@ classifiers = [
[project.optional-dependencies]
attrs = ['attrs >= 21.3.0']
attrs-strict = ['attrs >= 21.3.0, <= 23.1.0']
sqlalchemy = ['sqlalchemy >= 2.0.0']
sqlalchemy-strict = ['sqlalchemy >= 2.0.0, <= 2.0.25']

[project.urls]
'Homepage' = 'https://github.com/reagento/dataclass_factory'
Expand Down
2 changes: 1 addition & 1 deletion requirements/bench.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
#
# This file is autogenerated by pip-compile with Python 3.12
# This file is autogenerated by pip-compile with Python 3.11
# by the following command:
#
# pip-compile --allow-unsafe --output-file=requirements/bench.txt --strip-extras requirements/raw/bench.txt
Expand Down
8 changes: 5 additions & 3 deletions requirements/dev.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
#
# This file is autogenerated by pip-compile with Python 3.12
# This file is autogenerated by pip-compile with Python 3.11
# by the following command:
#
# pip-compile --allow-unsafe --output-file=requirements/dev.txt --strip-extras requirements/raw/dev.txt
Expand Down Expand Up @@ -323,8 +323,10 @@ sphinxcontrib-serializinghtml==1.1.9
# via sphinx
sphinxext-opengraph==0.9.1
# via -r requirements/raw/doc.txt
sqlalchemy==2.0.23
# via -r requirements/raw/test_extra_none.txt
sqlalchemy==2.0.25
# via
# -r requirements/raw/test_extra_new.txt
# -r requirements/raw/test_extra_none.txt
stevedore==5.1.0
# via bandit
tenacity==8.2.3
Expand Down
2 changes: 1 addition & 1 deletion requirements/doc.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
#
# This file is autogenerated by pip-compile with Python 3.12
# This file is autogenerated by pip-compile with Python 3.11
# by the following command:
#
# pip-compile --allow-unsafe --output-file=requirements/doc.txt --strip-extras requirements/raw/doc.txt
Expand Down
8 changes: 5 additions & 3 deletions requirements/lint.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
#
# This file is autogenerated by pip-compile with Python 3.12
# This file is autogenerated by pip-compile with Python 3.11
# by the following command:
#
# pip-compile --allow-unsafe --output-file=requirements/lint.txt --strip-extras requirements/raw/lint.txt
Expand Down Expand Up @@ -290,8 +290,10 @@ sphinxcontrib-serializinghtml==1.1.9
# via sphinx
sphinxext-opengraph==0.9.1
# via -r requirements/raw/doc.txt
sqlalchemy==2.0.23
# via -r requirements/raw/test_extra_none.txt
sqlalchemy==2.0.25
# via
# -r requirements/raw/test_extra_new.txt
# -r requirements/raw/test_extra_none.txt
stevedore==5.1.0
# via bandit
tenacity==8.2.3
Expand Down
2 changes: 1 addition & 1 deletion requirements/pre.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
#
# This file is autogenerated by pip-compile with Python 3.12
# This file is autogenerated by pip-compile with Python 3.11
# by the following command:
#
# pip-compile --allow-unsafe --output-file=requirements/pre.txt --strip-extras requirements/raw/pre.txt
Expand Down
1 change: 1 addition & 0 deletions requirements/raw/test_extra_new.txt
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
-r test_extra_none.txt
attrs==23.1.0
sqlalchemy==2.0.25
2 changes: 1 addition & 1 deletion requirements/raw/test_extra_none.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ pytest==7.4.2
-e ./tests/tests_helpers

phonenumberslite==8.13.26
sqlalchemy==2.0.23
sqlalchemy>=2.0.0

dirty-equals==0.7.1.post0

Expand Down
1 change: 1 addition & 0 deletions requirements/raw/test_extra_old.txt
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
-r test_extra_none.txt
attrs==21.3.0
sqlalchemy==2.0.0
2 changes: 1 addition & 1 deletion requirements/runner.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
#
# This file is autogenerated by pip-compile with Python 3.12
# This file is autogenerated by pip-compile with Python 3.11
# by the following command:
#
# pip-compile --allow-unsafe --output-file=requirements/runner.txt --strip-extras requirements/raw/runner.txt
Expand Down
8 changes: 5 additions & 3 deletions requirements/test_extra_new.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
#
# This file is autogenerated by pip-compile with Python 3.12
# This file is autogenerated by pip-compile with Python 3.11
# by the following command:
#
# pip-compile --allow-unsafe --output-file=requirements/test_extra_new.txt --strip-extras requirements/raw/test_extra_new.txt
Expand All @@ -26,8 +26,10 @@ pytest==7.4.2
# via -r requirements/raw/test_extra_none.txt
pytz==2023.3.post1
# via dirty-equals
sqlalchemy==2.0.23
# via -r requirements/raw/test_extra_none.txt
sqlalchemy==2.0.25
# via
# -r requirements/raw/test_extra_new.txt
# -r requirements/raw/test_extra_none.txt
typing-extensions==4.9.0
# via
# -r requirements/raw/test_extra_none.txt
Expand Down
2 changes: 1 addition & 1 deletion requirements/test_extra_none.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
#
# This file is autogenerated by pip-compile with Python 3.12
# This file is autogenerated by pip-compile with Python 3.11
# by the following command:
#
# pip-compile --allow-unsafe --output-file=requirements/test_extra_none.txt --strip-extras requirements/raw/test_extra_none.txt
Expand Down
8 changes: 5 additions & 3 deletions requirements/test_extra_old.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
#
# This file is autogenerated by pip-compile with Python 3.12
# This file is autogenerated by pip-compile with Python 3.11
# by the following command:
#
# pip-compile --allow-unsafe --output-file=requirements/test_extra_old.txt --strip-extras requirements/raw/test_extra_old.txt
Expand All @@ -26,8 +26,10 @@ pytest==7.4.2
# via -r requirements/raw/test_extra_none.txt
pytz==2023.3.post1
# via dirty-equals
sqlalchemy==2.0.23
# via -r requirements/raw/test_extra_none.txt
sqlalchemy==2.0.0
# via
# -r requirements/raw/test_extra_none.txt
# -r requirements/raw/test_extra_old.txt
typing-extensions==4.9.0
# via
# -r requirements/raw/test_extra_none.txt
Expand Down
14 changes: 10 additions & 4 deletions src/adaptix/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,13 @@
as_is_loader,
bound,
constructor,
default_dict,
dumper,
enum_by_exact_value,
enum_by_name,
enum_by_value,
flag_by_exact_value,
flag_by_member_names,
loader,
name_mapping,
validator,
Expand All @@ -33,12 +36,12 @@
AggregateCannotProvide,
CannotProvide,
Chain,
LocStackPattern,
Mediator,
P,
Provider,
Request,
RequestPattern,
create_request_checker,
create_loc_stack_checker,
)
from .retort import NoSuitableProvider

Expand All @@ -58,7 +61,10 @@
'enum_by_exact_value',
'enum_by_name',
'enum_by_value',
'flag_by_exact_value',
'flag_by_member_names',
'name_mapping',
'default_dict',
'AdornedRetort',
'FilledRetort',
'Retort',
Expand All @@ -78,10 +84,10 @@
'ExtraSkip',
'Mediator',
'NameStyle',
'RequestPattern',
'LocStackPattern',
'P',
'Saturator',
'create_request_checker',
'create_loc_stack_checker',
'retort',
'Provider',
'NoSuitableProvider',
Expand Down
43 changes: 43 additions & 0 deletions src/adaptix/_internal/datastructures.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,18 @@
Mapping,
Optional,
Protocol,
Sequence,
Tuple,
Type,
TypeVar,
Union,
ValuesView,
overload,
runtime_checkable,
)

from .common import VarTuple

K = TypeVar('K', bound=Hashable)
V = TypeVar('V')
_VT_co = TypeVar("_VT_co", covariant=True)
Expand Down Expand Up @@ -210,3 +214,42 @@ def discard(self: CM, *classes: Type[H]) -> CM:
value for key, value in self._mapping.items()
if key not in classes
)


T = TypeVar('T')
CustomTupleT = TypeVar('CustomTupleT', bound='CustomTuple')


class CustomTuple(Sequence[T], Generic[T]):
__slots__ = ('_tuple', )

def __init__(self, *args: T):
self._tuple = args

@classmethod
def from_tuple(cls: Type[CustomTupleT], tpl: VarTuple[T]) -> CustomTupleT:
self = cls.__new__(cls)
self._tuple = tpl
return self

def __repr__(self):
return f"{type(self).__name__}{self._tuple!r}"

@overload
def __getitem__(self, index: int) -> T:
...

@overload
def __getitem__(self: CustomTupleT, index: slice) -> CustomTupleT:
...

def __getitem__(self, index):
if isinstance(index, int):
return self._tuple[index]
return self.from_tuple(self._tuple[index])

def __len__(self):
return len(self._tuple)

def append_with(self: CustomTupleT, item: T) -> CustomTupleT:
return self.from_tuple(self._tuple + (item, ))
3 changes: 3 additions & 0 deletions src/adaptix/_internal/feature_requirement.py
Original file line number Diff line number Diff line change
Expand Up @@ -171,5 +171,8 @@ def fail_reason(self) -> str:
HAS_SUPPORTED_ATTRS_PKG = DistributionVersionRequirement('attrs', '21.3.0')
HAS_ATTRS_PKG = DistributionRequirement('attrs')

HAS_SUPPORTED_SQLALCHEMY_PKG = DistributionVersionRequirement('sqlalchemy', '2.0.0')
HAS_SQLALCHEMY_PKG = DistributionRequirement('sqlalchemy')

IS_CPYTHON = PythonImplementationRequirement('cpython')
IS_PYPY = PythonImplementationRequirement('pypy')
2 changes: 1 addition & 1 deletion src/adaptix/_internal/model_tools/definitions.py
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@ def __hash__(self):

def __repr__(self):
return (
"{type(self).__qualname__}"
f"{type(self).__qualname__}"
f"(key={self.key!r}, access_error={self.access_error}, path_element={self.trail_element!r})"
)

Expand Down
Loading

0 comments on commit c1b8cfa

Please sign in to comment.