[issue45158] Refactor traceback.py to make TracebackException more extensible.

2021-09-09 Thread Anton Abrosimov


Anton Abrosimov  added the comment:

I think now is a good time for such a change. `FrameSummary`,` StackSummary` 
and `TracebackException` can be left backward compatible. And PEP 657 already 
breaks backward compatibility of output parsers.

--

___
Python tracker 
<https://bugs.python.org/issue45158>
___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue45158] Refactor traceback.py to make TracebackException more extensible.

2021-09-09 Thread Anton Abrosimov


New submission from Anton Abrosimov :

1. Move internal dependencies (`FrameSummary`, `StackSummary`) to class 
attributes. Reduce coupling.
2. Separate receiving, processing and presenting traceback information.
How to replace `repr` with `pformat` in `FrameSummary`?
def __init__(...):
...
self.locals = {k: repr(v) for k, v in locals.items()} if locals else None
...
3. Move formatting templates to class attributes.
4. ...

Motivation:
1. For the sake of small changes to the view, you have to rewrite the entire 
`TracebackException` hierarchy. Or use string parsing.
2.1. During development, I want to see as much information as possible.
2.2. During production, displaying unnecessary information can lead to security 
problems.
2.3. In large projects, it is more convenient to use JSON for further 
processing in the system environment.

I have not found any PEPs describing `traceback.py`.
I can make a prototype of the changes if anyone is interested.

--
components: Library (Lib)
messages: 401528
nosy: abrosimov.a.a
priority: normal
severity: normal
status: open
title: Refactor traceback.py to make TracebackException more extensible.
type: enhancement
versions: Python 3.11

___
Python tracker 
<https://bugs.python.org/issue45158>
___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue42742] Add abc.Mapping to dataclass

2020-12-29 Thread Anton Abrosimov


Anton Abrosimov  added the comment:

Link to python-ideas thread:
https://mail.python.org/archives/list/python-id...@python.org/thread/XNXCUJVNOOVPAPL6LF627EOCBUUUX2DG/

--

___
Python tracker 
<https://bugs.python.org/issue42742>
___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue42742] Add abc.Mapping to dataclass

2020-12-25 Thread Anton Abrosimov


Anton Abrosimov  added the comment:

Thanks for the good offer, I will definitely use it.

--

___
Python tracker 
<https://bugs.python.org/issue42742>
___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue42742] Add abc.Mapping to dataclass

2020-12-25 Thread Anton Abrosimov


Anton Abrosimov  added the comment:

This Mixin only works with dataclass objects. And uses the private 
functionality of the dataclasses. So dataclasses.py is the right place for 
this. I think I can do enough tests.

And I think that this is too little for a standalone project.

--

___
Python tracker 
<https://bugs.python.org/issue42742>
___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue42742] Add abc.Mapping to dataclass

2020-12-25 Thread Anton Abrosimov


Anton Abrosimov  added the comment:

I think the second option looks better.
More pythonic.
No need to create new classes
No typing hacks.
Mixin can be easily expanded.

Yes, I will do refactoring, typing, documentation and tests in PR.

--

___
Python tracker 
<https://bugs.python.org/issue42742>
___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue42742] Add abc.Mapping to dataclass

2020-12-25 Thread Anton Abrosimov


Anton Abrosimov  added the comment:

An alternative way:

from collections.abc import Mapping
from dataclasses import dataclass, fields, _FIELDS, _FIELD

class DataclassMappingMixin(Mapping):
def __iter__(self):
return (f.name for f in fields(self))

def __getitem__(self, key):
field = getattr(self, _FIELDS)[key]
if field._field_type is not _FIELD:
raise KeyError(f"'{key}' is not a dataclass field.")
return getattr(self, field.name)

def __len__(self):
return len(fields(self))


@dataclass
class MyDataclass(DataclassMappingMixin):
a: int = 1
b: int = 2


my_dataclass = MyDataclass(a='3')
print(my_dataclass.__class__.__mro__)
print(my_dataclass.__class__.__name__)
print(my_dataclass['a'])
print(my_dataclass['b'])
print(dict(my_dataclass))
print(dict(**my_dataclass))
print(fields(my_dataclass))


Result:
(,
 ,
 ,
 ,
 ,
 ,
 ,
 )
MyDataclass
3
2
{'a': '3', 'b': 2}
{'a': '3', 'b': 2}
(Field(name='a',type=, ...),
 Field(name='b',type=, ...))

--

___
Python tracker 
<https://bugs.python.org/issue42742>
___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue42742] Add abc.Mapping to dataclass

2020-12-25 Thread Anton Abrosimov


Anton Abrosimov  added the comment:

Thanks for the answer, I agree.
The implementation should be like this?


from collections.abc import Mapping
from dataclasses import dataclass, fields, _FIELDS, _FIELD

class _DataclassMappingMixin(Mapping):
def __iter__(self):
return (f.name for f in fields(self))

def __getitem__(self, key):
fields = getattr(self, _FIELDS)
f = fields[key]
if f._field_type is not _FIELD:
raise KeyError(f"'{key}' is not a dataclass field.")
return getattr(self, f.name)

def __len__(self):
return len(fields(self))


def dataclass_mapping(cls=None, **kwargs):
def apply_dataclass(cls):
dataclass_wrap = dataclass(**kwargs)
return dataclass_wrap(cls)

def check_mapping_attrs(cls):
mapping_attrs = (i for i in dir(_DataclassMappingMixin) if i[0] != '_')
for key in mapping_attrs:
if hasattr(cls, key):
raise AttributeError(f"'{key}' is the Mapping reserved 
attribute.")

def apply_mapping(cls):
return type(cls.__name__ + 'Mapping',
(cls, _DataclassMappingMixin),
{})

def wrap(cls):
check_mapping_attrs(cls)
cls_dataclass = apply_dataclass(cls)
return apply_mapping(cls_dataclass)

# See if we're being called as @dataclass or @dataclass().
if cls is None:
# We're called with parens.
return wrap

# We're called as @dataclass without parens.
return wrap(cls)


@dataclass_mapping
class MyDataclass:
a: int = 1
b: int = 2


my_dataclass = MyDataclass(b='3')
print(my_dataclass.__class__.__name__)
print(my_dataclass['a'])
print(my_dataclass['b'])
print(dict(my_dataclass))
print(dict(**my_dataclass))

--

___
Python tracker 
<https://bugs.python.org/issue42742>
___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue42742] Add abc.Mapping to dataclass

2020-12-25 Thread Anton Abrosimov


New submission from Anton Abrosimov :

I want to add `abc.Mapping` extension to `dataclasses.dataclass`.

Motivation:

1. `asdict` makes a deep copy of the `dataclass` object. If I only want to 
iterate over the `field` attributes, I don't want to do a deep copy.
2. `dict(my_dataclass)` can be used as a `dict` representation of 
`my_dataclass` class without deep copying.
3. `myfunc(**my_dataclass)` looks better and is faster then 
`myfunc(**asdict(my_dataclass))`.
4. `len(my_dataclass) == len(asdict(my_dataclass))` is expected behavior.
5. `my_dataclass.my_field is my_dataclass['my_field']` is expected behavior.


Looks like a prototype:

from collections.abc import Mapping
from dataclasses import dataclass, fields, _FIELDS, _FIELD


@dataclass  # `(mapping=True)` creates such a class:
class MyDataclass(Mapping):
a: int = 1
b: int = 2

# In `dataclasses._process_class`:
# if `mapping` is `True`.
# Make sure 'get', 'items', 'keys', 'values' is not in `MyDataclass` fields.

def __iter__(self):
return (f.name for f in fields(self))

def __getitem__(self, key):
fields = getattr(self, _FIELDS)
f = fields[key]
if f._field_type is not _FIELD:
raise KeyError(f"'{key}' is not a field of the dataclass.")
return getattr(self, f.name)

def __len__(self):
return len(fields(self))


my_dataclass = MyDataclass(b=3)
print(my_dataclass['a'])
print(my_dataclass['b'])
print(dict(my_dataclass))
print(dict(**my_dataclass))

Stdout:
1
3
{'a': 1, 'b': 3}
{'a': 1, 'b': 3}


Realisation:

Updating the `dataclasses.py`: `dataclass`, `_process_class`, 
`_DataclassParams`.
Set `mapping` argument to default `False`.


Can this enhancement be accepted?

--
components: Library (Lib)
messages: 383752
nosy: abrosimov.a.a
priority: normal
severity: normal
status: open
title: Add abc.Mapping to dataclass
type: enhancement
versions: Python 3.10

___
Python tracker 
<https://bugs.python.org/issue42742>
___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com