Git Product home page Git Product logo

cleverdict's People

Contributors

dpbarrett avatar eggplants avatar felixthec avatar pfython avatar salabim avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar

cleverdict's Issues

Instantiate from more sources

Enable:

CleverDict({"1": "one"}')
E.g. look for string in init and attempt to convert using json.loads

CleverDict(file)
Where file is INI, YAML, TOML, JSON or .py with e.g. variable = value lines

Wrong method used in example in README.md

In Section 8, you have the following:

To deactivate .save() or .delete() separately:

>>> x.set_autosave()
>>> x.set_deleve()

At first I thought it was a typo that was supposed to be .set_delete(), but I think it might actually be intended as .set_autodelete().

Method for specifying aliases

A nice feature enhancement to CleverDict would be to offer a method for setting aliases directly; once the _alias dictionary is updated (I think) the existing functionality would automatically update all aliases whenever values change, which would be fantastic.

Incomplete set of aliases for Keys True and False

Aliases for True/False in __str__. Given that 1, 1.0, and True are considered equivalent as dictionary keys, it would be helpfully explicit to create all possibilities as aliases regardless of which Key is given initially. Likewise False.

>>> x = CleverDict({True: "Is this?"})

>>> print(x)

CleverDict
    x[True] == x['_True'] == x._True == x[1] == x[1.0] == 'Is this?'

Autosave not triggered with list.extend() / list.append()

When a CleverDict attribute or value is changed using "=" assignment it triggers the .save() method as intended.

list.append() and list.extend() do NOT trigger the autosave function however... not sure why, and I don't have any understanding of the internals, but just wondered if there it might be desirable/possible to specify a list of methods (outside of the CleverDict class) which, if called, would also trigger a mapped CleverDict method... mainly .save and .delete but could be other things as well.

That might be overly complicated, or it might provide another rich layer of cleverness to CleverDict. Please let me know your initial thoughts?

More elegant solution for CleverDict.ignore

Currently it's possible to set dictionary items with the same (key) names as existing methods e.g.

x=CleverDict()
x['save']="What a great save!"
x['save']
'What a great save!'

They don't overwrite the existing method (a good thing!) but there is some potentially confusing behaviour:

x
CleverDict({}, _aliases={}, _vars={})

This is because CleverDict.ignore includes {'save_path', 'delete', 'save', '_aliases'}.

Furthermore, although a user is unlikely to import their own data with an existing key of "_aliases", the other three ignored attributes might quite plausibly feature. In this case the solution is just to rename the keys before importing to CleverDict but the danger is that a user might not even know/expect this to be an issue until it becomes one...

Remove dependency on Click

Click is used by CleverDict solely for the purpose of locating the best (operating system specific) folder to save the autosave JSON files.

If it were possible to replicate this function (only) in CleverDict itself, it would make CleverDict completely dependency-free again.

Behaviour of @x.setter and @x.deleter

In using a CleverDict instance to hold passwords (in conjunction with keyring) I noticed the setter and delete decorators didn't appear to be working:

    @property
    def password(self):
        return keyring.get_password(account, self.username)

    @password.setter
    def password(self, value):
        print("Setting!")
        keyring.set_password(account, self.username, value)

    @password.deleter
    def password(self):
        keyring.delete_password(account, username)
>>> value = "mysecret"
>>> keyring.set_password(CleverSession.choices[self.url], self.username, value)
>>> self.password
'mysecret'

# set
>>> self.password = "newpassword"
>>> self.password
'mysecret'
>>> self['password']
'newpassword'

# delete
>>> del self.password
>>> self.password
'mysecret'
>>> self['password']
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "C:\Users\Peter\AppData\Roaming\Python\Python39\site-packages\cleverdict\cleverdict.py", line 168, in __getitem__
    name = self.get_key(name)
  File "C:\Users\Peter\AppData\Roaming\Python\Python39\site-packages\cleverdict\cleverdict.py", line 310, in get_key
    raise KeyError(name)
KeyError: 'password'

So I'm just wondering if this is something that has to be worked around, a limitation of CleverDict, or if there's something even more Clever we can do in CleverDict itself so that @x.setter and @x.deleter work as expected right out of the box?

.data is reserved by UserDict but can be overwritten

The .data attribute is reserved by UserDict and it shouldn't be possible to overwrite/break it, but it is currently, but test_data_attribute() fails consistently. Also since data is a relatively common Key/Attribute name it's likely to feature in people's existing dictionaries or objects. I don't know how, but wonder if we can change the (inherited) behaviour of UserDict such that it accesses _data rather than data, which would also be consistent with our use of _alias. I tried various ways to change this in both in normalise() and in the main class, but got into a recursion tangle!

Create converter for nested dictionaries / objects

Create a new utility method (or enhance init?) to convert nested dictionaries into nested CleverDicts, so that deeper levels can be accesses easily with "." notation. For example:

>>> d = CleverDict({"level1": {"level2A": "A", "level2B": "B"}})
>>> d.level1.level2B
'B'
>>> d
CleverDict({'level1': CleverDict({'level2A': 'A', 'level2B': 'B'}, _aliases={}, _vars={})}, _aliases={}, _vars={})

I'd also like to extend this functionality to attributes, which might be trickier. For example:

>>> ac1 = AnotherClass()
>>> ac2 = AnotherClass()
>>> ac1.level2 = "Level Two"
>>> ac2.level1 = "Level One"
>>> d = CleverDict(ac1, ac2)
>>> d.ac1.level2
"Level Two"
>>> d.ac2.level1
"Level One"

And the absolute ideal would be to handle any mixture of dictionaries and objects/attributes. For example:

>>> d = CleverDict({"First Item":  {"level1": {"level2A": "A", "level2B": "B"}}},
                     ac1, {"Second Item": {"obj": ac2}}}
>>> d.First_Item.level1.level2A
"A"
>>> d.ac1.level2
"Level Two"
>>> d.Second_Item.obj.level1
"Level One"

change current code style to be valid with black, isort and flake8

  • create a pyprojects.toml
  • add necessary settings for black, isort and flake8 (see below)
  • run all linters to change the style initialy before merging #38
[tool.black]
line-length = 100
target-version = ['py39']

[tool.isort]
combine_as_imports = true
line_length = 100
profile = "black"

Ability to auto-delete

Just as the dummy .save() method is called every time a CleverDict values changes, how about a dummy .delete() method for when a value is deleted?

This came to light when using CleverDict to auto-save to a JSON config file... updates were happening beautifully behind the scenes but when an value was deleted, it remained in the config file, meaning that the next time the script was run and the default values were loaded from the config file, the old unwanted value was still there.

Pass value to custom delete function

.delete() currently just takes a key/attribute name argument which means the actual value will be deleted before any custom delete function is called. It may be important to have that value available (e.g. backup?)

Alternatively ensure custom delete (and save) are called BEFORE delitem etc.

Can we override how {...} is interpretted?

Is it possible/desirable to override curly brackets e.g.

from cleverdict import CleverDict
x = {"a": "First letter"}

... would result in x being a CleverDict object not a regular dict?

Combining CleverDict functionality with other classes

It would be great if CleverDict behaviour could be easily 'grafted on' to existing classes using inheritance, without causing recursion or requiring a rewrite/overwrite of the original class.

For example if it were as easy as:

```
>>> class MyDatetime(datetime.datetime, CleverDict):
...     pass

>>> mdt = MyDatetime.now()
>>> mdt.hour
4
>>> mdt['hour']
4
```

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.