Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Overriding __len__ fails #331

Closed
hewei100 opened this issue Feb 3, 2018 · 2 comments
Closed

Overriding __len__ fails #331

hewei100 opened this issue Feb 3, 2018 · 2 comments
Labels
Milestone

Comments

@hewei100
Copy link

hewei100 commented Feb 3, 2018

This is not working under 0.7.3

from pony.orm import *

db = Database('sqlite', ':memory:')

class Person(db.Entity):
    name = Required(str)
    team = Set('Team')

class Team(db.Entity):
    name = Required(str)
    members = Set(Person)
    
    def add(self, member):
        self.members.add(member)
        return self
        
    def count(self):
        return self.members.count()
        
    def __len__(self):
        return len(self.members)

db.generate_mapping(create_tables=True)

with db_session:
    team_boy = Team(name='Boy Team')
    # AttributeError: _vals_  in pony/orm/core.py, line 3098
    team_boy.add(Person(name='Bob')).add(Person(name='David'))
    print(team_boy.count())
    print(len(team_boy))

But after this patch, it works as expected

--- lib/python3.5/dist-packages/pony/orm/core.py.orig   2018-01-30 02:01:45.049469709 +0000
+++ lib/python3.5/dist-packages/pony/orm/core.py        2018-02-03 07:10:27.122080144 +0000
@@ -4099,7 +4099,9 @@
 
         if obj is None:
             with cache.flush_disabled():
-                obj = obj_to_init or object.__new__(entity)
+                obj = obj_to_init
+                if obj is None:
+                   obj = object.__new__(entity)
                 cache.objects.add(obj)
                 obj._pkval_ = pkval
                 obj._status_ = status

@stanislavkozlovski
Copy link

stanislavkozlovski commented Feb 18, 2018

Yeah, wow.
Seems like the truthy evaluation of a class calls the __len__ method.

Here is the following code sample on Python 3.6

class TestClass:
    def __len__(self):
        print("LEN CALLED")
        return False

a = TestClass()
b = a or 1  # calls __len__
if a:  # calls __len__
  pass
else:
  print(b)

Output:

LEN CALLED
LEN CALLED
1

@sashaaero
Copy link
Member

Hi! Thanks for reporting.
We've fixed it. Will be released soon.

@kozlovsky kozlovsky added this to the 0.7.4 milestone Mar 17, 2018
@kozlovsky kozlovsky added the bug label Mar 17, 2018
kozlovsky added a commit that referenced this issue Jul 23, 2018
# Major features

* Hybrid methods and properties added: https://docs.ponyorm.com/entities.html#hybrid-methods-and-properties
* Allow to base queries on another queries: `select(x.a for x in prev_query if x.b)`
* Added support of Python 3.7
* Added support of PyPy
* `group_concat()` aggregate function added
* pony.flask subpackage added for integration with Flask

# Other features

* `distinct` option added to aggregate functions
* Support of explicit casting to `float` and `bool` in queries

# Improvements

* Apply @cut_traceback decorator only when pony.MODE is 'INTERACTIVE'

# Bugfixes

* In SQLite3 `LIKE` is case sensitive now
* #249: Fix incorrect mixin used for Timedelta
* #251: correct dealing with qualified table names
* #301: Fix aggregation over JSON Column
* #306: Support of frozenset constants added
* #308: Fixed an error when assigning JSON attribute value to the same attribute: obj.json_attr = obj.json_attr
* #313: Fix missed retry on exception raised during db_session.__exit__
* #314: Fix AttributeError: 'NoneType' object has no attribute 'seeds'
* #315: Fix attribute lifting for JSON attributes
* #321: Fix KeyError on obj.delete()
* #325: duplicating percentage sign in raw SQL queries without parameters
* #331: Overriding __len__ in entity fails
* #336: entity declaration serialization
* #357: reconnect after PostgreSQL server closed the connection unexpectedly
* Fix Python implementation of between() function and rename arguments: between(a, x, y) -> between(x, a, b)
* Fix retry handling: in PostgreSQL and Oracle an error can be raised during commit
* Fix optimistic update checks for composite foreign keys
* Don't raise OptimisticCheckError if db_session is not optimistic
* Handling incorrect datetime values in MySQL
* Improved ImportError exception messages when MySQLdb, pymysql, psycopg2 or psycopg2cffi driver was not found
* desc() function fixed to allow reverse its effect by calling desc(desc(x))
* __contains__ method should check if objects belong to the same db_session
* Fix pony.MODE detection; mod_wsgi detection according to official doc
* A lot of inner fixes
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

4 participants