A test fixtures replacement for Python

Overview

factory_boy

Latest Version Supported Python versions Wheel status License

factory_boy is a fixtures replacement based on thoughtbot's factory_bot.

As a fixtures replacement tool, it aims to replace static, hard to maintain fixtures with easy-to-use factories for complex objects.

Instead of building an exhaustive test setup with every possible combination of corner cases, factory_boy allows you to use objects customized for the current test, while only declaring the test-specific fields:

class FooTests(unittest.TestCase):

    def test_with_factory_boy(self):
        # We need a 200€, paid order, shipping to australia, for a VIP customer
        order = OrderFactory(
            amount=200,
            status='PAID',
            customer__is_vip=True,
            address__country='AU',
        )
        # Run the tests here

    def test_without_factory_boy(self):
        address = Address(
            street="42 fubar street",
            zipcode="42Z42",
            city="Sydney",
            country="AU",
        )
        customer = Customer(
            first_name="John",
            last_name="Doe",
            phone="+1234",
            email="[email protected]",
            active=True,
            is_vip=True,
            address=address,
        )
        # etc.

factory_boy is designed to work well with various ORMs (Django, MongoDB, SQLAlchemy), and can easily be extended for other libraries.

Its main features include:

  • Straightforward declarative syntax
  • Chaining factory calls while retaining the global context
  • Support for multiple build strategies (saved/unsaved instances, stubbed objects)
  • Multiple factories per class support, including inheritance

Links

Download

PyPI: https://pypi.org/project/factory-boy/

$ pip install factory_boy

Source: https://github.com/FactoryBoy/factory_boy/

$ git clone git://github.com/FactoryBoy/factory_boy/
$ python setup.py install

Usage

Note

This section provides a quick summary of factory_boy features. A more detailed listing is available in the full documentation.

Defining factories

Factories declare a set of attributes used to instantiate a Python object. The class of the object must be defined in the model field of a class Meta: attribute:

import factory
from . import models

class UserFactory(factory.Factory):
    class Meta:
        model = models.User

    first_name = 'John'
    last_name = 'Doe'
    admin = False

# Another, different, factory for the same object
class AdminFactory(factory.Factory):
    class Meta:
        model = models.User

    first_name = 'Admin'
    last_name = 'User'
    admin = True

ORM integration

factory_boy integration with Object Relational Mapping (ORM) tools is provided through specific factory.Factory subclasses:

  • Django, with factory.django.DjangoModelFactory
  • Mogo, with factory.mogo.MogoFactory
  • MongoEngine, with factory.mongoengine.MongoEngineFactory
  • SQLAlchemy, with factory.alchemy.SQLAlchemyModelFactory

More details can be found in the ORM section.

Using factories

factory_boy supports several different build strategies: build, create, and stub:

# Returns a User instance that's not saved
user = UserFactory.build()

# Returns a saved User instance.
# UserFactory must subclass an ORM base class, such as DjangoModelFactory.
user = UserFactory.create()

# Returns a stub object (just a bunch of attributes)
obj = UserFactory.stub()

You can use the Factory class as a shortcut for the default build strategy:

# Same as UserFactory.create()
user = UserFactory()

No matter which strategy is used, it's possible to override the defined attributes by passing keyword arguments:

# Build a User instance and override first_name
>>> user = UserFactory.build(first_name='Joe')
>>> user.first_name
"Joe"

It is also possible to create a bunch of objects in a single call:

>>> users = UserFactory.build_batch(10, first_name="Joe")
>>> len(users)
10
>>> [user.first_name for user in users]
["Joe", "Joe", "Joe", "Joe", "Joe", "Joe", "Joe", "Joe", "Joe", "Joe"]

Realistic, random values

Demos look better with random yet realistic values; and those realistic values can also help discover bugs. For this, factory_boy relies on the excellent faker library:

class RandomUserFactory(factory.Factory):
    class Meta:
        model = models.User

    first_name = factory.Faker('first_name')
    last_name = factory.Faker('last_name')
>>> RandomUserFactory()
<User: Lucy Murray>

Reproducible random values

The use of fully randomized data in tests is quickly a problem for reproducing broken builds. To that purpose, factory_boy provides helpers to handle the random seeds it uses, located in the factory.random module:

import factory.random

def setup_test_environment():
    factory.random.reseed_random('my_awesome_project')
    # Other setup here

Lazy Attributes

Most factory attributes can be added using static values that are evaluated when the factory is defined, but some attributes (such as fields whose value is computed from other elements) will need values assigned each time an instance is generated.

These "lazy" attributes can be added as follows:

class UserFactory(factory.Factory):
    class Meta:
        model = models.User

    first_name = 'Joe'
    last_name = 'Blow'
    email = factory.LazyAttribute(lambda a: '{}.{}@example.com'.format(a.first_name, a.last_name).lower())
    date_joined = factory.LazyFunction(datetime.now)
>>> UserFactory().email
"[email protected]"

Note

LazyAttribute calls the function with the object being constructed as an argument, when LazyFunction does not send any argument.

Sequences

Unique values in a specific format (for example, e-mail addresses) can be generated using sequences. Sequences are defined by using Sequence or the decorator sequence:

class UserFactory(factory.Factory):
    class Meta:
        model = models.User

    email = factory.Sequence(lambda n: 'person{}@example.com'.format(n))

>>> UserFactory().email
'[email protected]'
>>> UserFactory().email
'[email protected]'

Associations

Some objects have a complex field, that should itself be defined from a dedicated factories. This is handled by the SubFactory helper:

class PostFactory(factory.Factory):
    class Meta:
        model = models.Post

    author = factory.SubFactory(UserFactory)

The associated object's strategy will be used:

# Builds and saves a User and a Post
>>> post = PostFactory()
>>> post.id is None  # Post has been 'saved'
False
>>> post.author.id is None  # post.author has been saved
False

# Builds but does not save a User, and then builds but does not save a Post
>>> post = PostFactory.build()
>>> post.id is None
True
>>> post.author.id is None
True

Support Policy

factory_boy supports active Python versions as well as PyPy3.

Debugging factory_boy

Debugging factory_boy can be rather complex due to the long chains of calls. Detailed logging is available through the factory logger.

A helper, factory.debug(), is available to ease debugging:

with factory.debug():
    obj = TestModel2Factory()


import logging
logger = logging.getLogger('factory')
logger.addHandler(logging.StreamHandler())
logger.setLevel(logging.DEBUG)

This will yield messages similar to those (artificial indentation):

BaseFactory: Preparing tests.test_using.TestModel2Factory(extra={})
  LazyStub: Computing values for tests.test_using.TestModel2Factory(two=<OrderedDeclarationWrapper for <factory.declarations.SubFactory object at 0x1e15610>>)
    SubFactory: Instantiating tests.test_using.TestModelFactory(__containers=(<LazyStub for tests.test_using.TestModel2Factory>,), one=4), create=True
    BaseFactory: Preparing tests.test_using.TestModelFactory(extra={'__containers': (<LazyStub for tests.test_using.TestModel2Factory>,), 'one': 4})
      LazyStub: Computing values for tests.test_using.TestModelFactory(one=4)
      LazyStub: Computed values, got tests.test_using.TestModelFactory(one=4)
    BaseFactory: Generating tests.test_using.TestModelFactory(one=4)
  LazyStub: Computed values, got tests.test_using.TestModel2Factory(two=<tests.test_using.TestModel object at 0x1e15410>)
BaseFactory: Generating tests.test_using.TestModel2Factory(two=<tests.test_using.TestModel object at 0x1e15410>)

Contributing

factory_boy is distributed under the MIT License.

Issues should be opened through GitHub Issues; whenever possible, a pull request should be included. Questions and suggestions are welcome on the mailing-list.

Development dependencies can be installed in a virtualenv with:

$ pip install --editable '.[dev]'

All pull requests should pass the test suite, which can be launched simply with:

$ make testall

In order to test coverage, please use:

$ make coverage

To test with a specific framework version, you may use a tox target:

# list all tox environments
$ tox --listenvs

# run tests inside a specific environment
$ tox -e py36-django20-alchemy13-mongoengine017

Valid options are:

  • DJANGO for Django
  • MONGOENGINE for mongoengine
  • ALCHEMY for SQLAlchemy

To avoid running mongoengine tests (e.g no MongoDB server installed), run:

$ make SKIP_MONGOENGINE=1 test
Issues
  • factory.Trait() cannot get a factory.RelatedFactory override

    factory.Trait() cannot get a factory.RelatedFactory override

    Traits does not seem to allow a related factory override.

    Ex:

    class MyModelFactory(factory.django.DjangoModelFactory):
        class Meta:
              model = models.MyModel
        class Params:
            with_my_other_model = factory.Trait(
                 my_other_model=factory.RelatedFactory(MyOtherModelFactory, 'my_model')
            )
    

    It will complain my_other_model is not a valid field.

    That would be awesome.

    Bug 
    opened by jrobichaud 26
  • Allow SQLAlchemy factories to be committed on create

    Allow SQLAlchemy factories to be committed on create

    It seems like the general consensus is that one should only flush the current session during a test case, and roll back on each tear down. Due to the nature of my testing setup it is more convenient to commit instead of flush on create. Have you considered adding a meta flag similar to force_flush that would allow the session to be committed?

    for example:

    class SQLAlchemyModelFactory(base.Factory):
        """Factory for SQLAlchemy models. """
    
        _options_class = SQLAlchemyOptions
        class Meta:
            abstract = True
    
        @classmethod
        def _create(cls, model_class, *args, **kwargs):
            """Create an instance of the model, and save it to the database."""
            session = cls._meta.sqlalchemy_session
            obj = model_class(*args, **kwargs)
            session.add(obj)
    +       if cls._meta.force_commit:
    +          session.commit()
            elif cls._meta.force_flush:
                session.flush()
            return obj
    

    overriding SQLAlchemyModelFactory._create is my current solution. Any suggestions on how to properly have Factories be committed on creation is welcome! Thanks!

    Feature SQLAlchemy 
    opened by zyskowsk 22
  • SQLAlchemyModelFactory _create should at least flush the session

    SQLAlchemyModelFactory _create should at least flush the session

    SQLAlchemyModelFactory _create (https://github.com/rbarrois/factory_boy/blob/master/factory/alchemy.py#L45-50) should at least flush(I think flush in this context is better than commit) the SQLAlchemy session to produce the behaviour described in the docs:

    >>> session.query(User).all()
    []
    >>> UserFactory()
    <User: User 1>
    >>> session.query(User).all()
    [<User: User 1>]
    
    opened by vesauimonen 20
  • Managing randomness with faker is impossible

    Managing randomness with faker is impossible

    In the case when the fields are specified over faker providers, it's impossible to manage randomness because order of evaluation is not fixed (iterating a dict internally?). Example: Seed the random before of instantiation of

    class CompanyFactory(factory.DjangoModelFactory):
        class Meta:
            model = Company
    
        name = faker.company
        status = 'APR'
    

    with

    import factory
    faker = factory.faker.Faker._get_faker(locale='de_DE')
    faker.random.seed(0)
    

    returns the same result. But adding any other fuzzy field, for instance:

    faker.phone_number
    

    makes both fields to be filled in an unpredictable way. Maybe because the fields are evaluated in the dict iteration. It would be nice to have a work around at least.

    Bug NeedInfo 
    opened by scheparev-moberries 19
  • Add peewee support

    Add peewee support

    It was designed around my branch of peewee https://github.com/cam-stitt/peewee. I have a pull request waiting with my minor changes so hopefully it will be upstream soon. I have not yet completed any documentation regarding the implementation, it was merely a first attempt at getting one working for my own project.

    Edit: My changes have been merged into master for peewee. All tests now pass on master.

    Feature 
    opened by cam-stitt 17
  • DjangoModelFactory's

    DjangoModelFactory's "_setup_next_sequence" assumes that pk is an integer

    Offending code is here:

        @classmethod
        def _setup_next_sequence(cls):
            """Compute the next available PK, based on the 'pk' database field."""
    
            model = cls._associated_class  # pylint: disable=E1101
            manager = cls._get_manager(model)
    
            try:
                return 1 + manager.values_list('pk', flat=True
                    ).order_by('-pk')[0]
            except IndexError:
                return 1
    

    This problem didn't exist in factory_boy 1.3. My field that was using a non-integer PK is using a sequence, which worked fine previously:

    code = factory.Sequence(lambda n: str(n).zfill(3))
    

    I haven't dug into the code enough to know much about the changes that caused this problem, but ultimately I'd like to be able to use the sequence for the field again.

    Q&A Feature 
    opened by AndrewIngram 16
  • faker.py does not install via pip - strange stuff!!

    faker.py does not install via pip - strange stuff!!

    Hi guys,

    now this one is really strange. I just wanted to try the build-in faker and basically I am getting an attribute not found error:

    >>> import factory
    >>> factory.Faker('email')
    Traceback (most recent call last):
      File "<console>", line 1, in <module>
    AttributeError: 'module' object has no attribute 'Faker'
    

    20 minutes later I had a look at the virtualenv/site-packages path and noticed that the file "faker.py" is missing.

    And after doing an...

    pip uninstall factory-boy
    pip install factory-boy
    

    it is still missing!

    Any ideas whats going wrong?

    Q&A 
    opened by thebarty 15
  • ImportError: The ``fake-factory`` package is now called ``Faker``.

    ImportError: The ``fake-factory`` package is now called ``Faker``.

    Trying to import factory, but it looks like since yesterday, one of the required packages has changed it's name:

        import factory
      File "/venv/lib64/python3.5/site-packages/factory/__init__.py", line 46, in <module>
        from .faker import Faker
      File "/venv/lib64/python3.5/site-packages/factory/faker.py", line 41, in <module>
        import faker
      File "/venv/lib64/python3.5/site-packages/faker/__init__.py", line 7, in <module>
        raise ImportError(error)
    ImportError: The ``fake-factory`` package is now called ``Faker``.
    

    Edit: I now see there's already a commit to fix this. Any chance of a release to pypi?

    opened by drodger 14
  • How to handle 'self' Foreign key relation in factory boy

    How to handle 'self' Foreign key relation in factory boy

    Hello,

    I've a django model where i'm using Foreign key with itself. Can you please guide me how i can replicate self relation in factory boy class. e.g.

    class A(models.Model):
        name = models.CharField(max_length=255)
        parent = models.ForeignKey('self', blank=True, null=True)
    

    Please guide how i can create a factory for such type of relations.

    Thanks.

    Q&A 
    opened by muzaffaryousaf 14
  • Include session getter support

    Include session getter support

    As our team tries to migrate our tests to use factory_boy, we found tricky to set the DB sessions during the tests runtime, mocking was tricky and nasty. I found this issue, which closely resemble the problem we are currently facing, and decided to give a shot.

    The idea is to allow passing a callable returning the SQLAlchemy session in a Meta attribute called sqlalchemy_session_factory. This has several use-cases, allowing control of the session on runtime.

    This is my first OSS contribution ever, super excited with it. Any feedback is appreciated :)

    Fixes https://github.com/FactoryBoy/factory_boy/issues/304

    SQLAlchemy 
    opened by hugopellissari 13
  • How to create Profile.username with faker?

    How to create Profile.username with faker?

    I wanna create random value with faker wrapper, however, I can't get extract any value from it.

    # not working
    username = factory.Faker('profile')['username']
    

    Has anyone done this before?

    Q&A 
    opened by legshort 13
  • How to access Params from Post-Create Hook?

    How to access Params from Post-Create Hook?

    Description

    I am using this package with SQLAlchemy models. My goal is to use a factory to create a model instance, along with a number of associated model instances. Both specific and generic associations, like these two use cases:

    # use two new gyms:
    UserFactory(gyms_count=2)
    
    # use specified gym(s)
    gym = GymFactory()
    UserFactory(gyms=[gym])
    

    I am able to use a post_generation hook to create the related objects, but I'm having issues accessing one of the params when doing so. Or maybe I'm misunderstanding how the params work.

    To Reproduce

    Model / Factory code

    Models (many to many association: user has many gyms, and vice versa):

    class Gym(db.Model):
        __tablename__ = "gyms"
    
        id = db.Column(db.Integer, primary_key=True, index=True)
        title = db.Column(db.String, nullable=False) #> "My Gym"
    
        memberships = db.relationship("Membership", back_populates="gym")
    
    
    class User(db.Model):
        __tablename__ = "users"
    
        id = db.Column(db.Integer, primary_key=True, index=True)
        email = db.Column(db.String, index=True, nullable=False, unique=True)
    
        memberships = db.relationship("Membership", back_populates="user")
    
    class Membership(db.Model, MyModel):
        __tablename__ = "memberships"
    
        id = db.Column(db.Integer, primary_key=True, index=True)
        gym_id = db.Column(db.Integer, db.ForeignKey("gyms.id"), nullable=False, index=True)
        user_id = db.Column(db.Integer, db.ForeignKey("users.id"), nullable=False, index=True)
    
        gym = db.relationship("Gym", back_populates="memberships", uselist=False)
        user = db.relationship("User", back_populates="memberships", uselist=False)
    
    
    

    Factories:

    class BaseFactory(SQLAlchemyModelFactory):
        class Meta(object):
            sqlalchemy_session = db.session
    
    class UserFactory(BaseFactory):
        class Meta:
            model = User
    
        id = Sequence(lambda n: n+1)
        email = Sequence(lambda n: f"u{n+1}@example.com")
    
        class Params:
            gyms_count = 0
    
        @post_generation
        def gyms(obj, create, extracted, **kwargs):
            if not create:
                # Simple build, do nothing.
                return
    
            if extracted:
                for gym in extracted:
                    Membership.find_or_create(gym_id=gym.id, user_id=obj.id)
    
            gyms_count = kwargs.get("gyms_count") or 0
            #gyms_count = obj.gyms_count
            # I tried `kwargs.get("gyms_count")` and `obj.gyms_count` but neither was successful.
            # how to get the gyms count param here?
    
            for _ in range(0, gyms_count):
                gym = GymFactory()
                Membership.find_or_create(gym_id=gym.id, user_id=obj.id)
    
    The issue

    How to access the gyms_count param from within the post_generation hook?

    opened by s2t2 0
  • post_generation method not auto-committing in SQLAlchemy

    post_generation method not auto-committing in SQLAlchemy

    Description

    I am using the post_generation method to set a many-to-many relationship. I have sqlalchemy_session_persistence = 'commit', however the many-to-many relationship is not being saved to the DB.

    To Reproduce

    Set sqlalchemy_session_persistence = 'commit' Set up many-to-many relationship between two models Create factory for both models Create post_generation method to set many-to-many Call factory.create()

    Model / Factory code
    class TaskTypeFactory(BaseCustomFactory):
        class Meta:
            model = models.TaskType
    
        cms_slug = factory.Faker('word')
        section = factory.LazyAttribute(lambda _: random.choice(list(constants.TaskTypeSections)).value)
    
        @factory.post_generation
        def journey_versions(self, create, extracted, **kwargs):
            """
            Creates a JourneyVersion and associates it with the TaskType object after creation, or add a list of
            JourneyVersion objects that are passed into the factory declaration with the `journey_versions` attribute.
            Ex. TaskTypeFactory.create(journey_versions=(v1, v2, v3))
            Ref: https://factoryboy.readthedocs.io/en/stable/recipes.html#simple-many-to-many-relationship
    
            @param create: a boolean indicating which strategy was used -- .build() or .create()
            @type create: bool
            @param extracted: extracted is None unless a value was passed in for the PostGeneration declaration at Factory
            declaration time
            @type extracted: Any
            @param kwargs: any extra parameters passed as attr__key=value when calling the Factory
            @type kwargs: Any
            """
            if not create:
                # Simple build, do nothing.
                return
    
            if extracted:
                if isinstance(extracted, Iterable):
                    # A list of JourneyVersion were passed in
                    for journey_version in extracted:
                        self.journey_versions.append(journey_version)
                elif isinstance(extracted, models.JourneyVersion):
                    # A single JourneyVersion was passed in
                    self.journey_versions.append(extracted)
            else:
                # Nothing was passed in so we will just create a new JourneyVersion
                journey_version = JourneyVersionFactory.create()
                self.journey_versions.append(journey_version)
    
    
    class TaskType(BaseIntPKModel):
        __tablename__ = "task_types"
    
        # Properties
        cms_slug = Column(String, nullable=False)
        section = Column(Enum(constants.TaskTypeSections), nullable=False, index=True)
    
        # Relationships
        journey_versions = relationship(
            "JourneyVersion", secondary=journey_version_task_types_table, cascade="all", back_populates="task_types",
            passive_deletes=True
        )
        triggers = relationship("Trigger", back_populates="task_type", cascade="all, delete-orphan", passive_deletes=True)
        tasks = relationship("Task", back_populates="task_type", cascade="all, delete-orphan", passive_deletes=True)
    
    
    class JourneyVersion(BaseIntPKModel):
        __tablename__ = "journey_versions"
    
        # Properties
        name = Column(String, unique=True, nullable=False)
        deal_type = Column(Enum(constants.DealTypes), nullable=False)
        description = Column(String, nullable=True)
        language = Column(Enum(constants.Languages), default=constants.Languages.en.value, nullable=False)
        current = Column(Boolean, default=False, nullable=False)
    
        # Relationships
        journeys = relationship(
            "Journey", back_populates="journey_version", cascade="all, delete-orphan", passive_deletes=True
        )
        task_types = relationship(
            "TaskType", secondary=journey_version_task_types_table, cascade="all", back_populates="journey_versions",
            passive_deletes=True
        )
    
    journey_version_task_types_table = Table('journey_version_task_types', Base.metadata,
                                             Column('journey_version_id',
                                                    ForeignKey('journey_versions.id', ondelete="CASCADE"),
                                                    primary_key=True),
                                             Column('task_type_id', ForeignKey('task_types.id', ondelete="CASCADE"),
                                                    primary_key=True)
                                             )
    
    The issue

    Once the create method is called, it should save the model objects to the DB along with the many-to-many relationship. However, after running create, there is no DB entry in the association table between the two newly created objects.

    factories.TaskTypeFactory.create()  # after this executes, the association table entry is missing
    session.commit()  # after this executes, the association table entry is present
    
    opened by colton-flyhomes 0
  • objection creation error with factory-boy and sql server identity columns

    objection creation error with factory-boy and sql server identity columns

    Description

    Edit - title to reflect possible updated problem

    Does factory-boy do anything internally with the db user connecting to the database? I'm getting strange errors when trying to set this up for a new project, when the factory tries to create the object, that looks like permissions errors. But the user I connect with in my db connection string for the test suite is the same as in my regular code. The user has the correct permissions, and can successfully write to the database.

    Trying to set up factory-boy with pytest-factoryboy for a new project to test a SQL Server database. I've previously used factory-boy successfully on other projects, with other dbs, e.g. postgres. This is the first project with a SQL Server db. I can't for the life of me get this working correctly for a single table test.

    To Reproduce

    Running the test_mission pytest below with the setup below results in the error

    E       sqlalchemy.exc.ProgrammingError: (raised as a result of Query-invoked autoflush; consider using a session.no_autoflush block if this flush is occurring prematurely)
    E       (pyodbc.ProgrammingError) ('42000', '[42000] [Microsoft][ODBC Driver 17 for SQL Server][SQL Server]Cannot find the object "Mission" because it does not exist or you do not have permissions. (1088) (SQLExecDirectW)')
    E       [SQL: SET IDENTITY_INSERT [Mission] ON]
    E       (Background on this error at: http://sqlalche.me/e/13/f405)
    
    Model / Factory code

    I'm auto-reflecting my models with automap_base.

    # auto-reflected models
    Base = automap_base(cls=BaseModel)
    Base.prepare(engine, reflect=True)
    
    # my session    
    url = get_url('test').     # my db connection string 
    engine = sqlalchemy.create_engine(url)
    session_factory = sessionmaker(bind=engine, expire_on_commit=True, autocommit=True)
    Session = scoped_session(session_factory)
    

    but I also tried a declarative base model. The model only has two columns, an auto-incrementing identity unique key missionID, and a string column label.

    # declarative base model
    Base = declarative_base(bind=engine)
    class Mission(Base):
        __tablename__ = 'Mission'
        __table_args__ = {'schema': 'dbo', 'autoload': True}
    
        def __repr__(self):
            return f'<Mission id={self.missionID}, label={self.label}>'
    
    

    Factory

    # factory
    class MissionFactory(factory.alchemy.SQLAlchemyModelFactory):
        class Meta:
            model = Base.classes.Mission
            sqlalchemy_session = Session
        missionID = factory.Sequence(lambda n: n)
        label = factory.Faker('name')
    
    
    The issue

    I tried the simple test_mission and get the error above, with full traceback below. The table already has an existing row in it (id=1, label="A").

    pytest fixtures

    
    @pytest.fixture(scope='session')
    def connection():
        url = get_url('test').     # my db connection string 
        engine = sqlalchemy.create_engine(url)
        connection = engine.connect()
        yield connection
        connection.close()
    
    @pytest.fixture(autouse=True)
    def session(connection):
        session = Session(bind=connection)
        session.begin()
        yield session
        session.rollback()
        session.close()
    

    Simple test that fails

    
    def test_mission(session, mission_factory):
        missions = session.query(Base.classes.Mission.label).all()
        assert missions == [('A',)]
        mission = mission_factory(label="B")
        assert isinstance(mission, Base.classes.Mission)
        missions = session.query(Base.classes.Mission.label).all()
        assert missions == [('A'), ("B")]
    

    I thought it was a flushing issue, so I turned off autoflush in session_factory = sessionmaker(bind=engine, expire_on_commit=True, autocommit=True, autoflush=False). When I do that, I don't get the error but the object is not saved to the database, probably since only a session.add is happening. I also tried setting on MissionFactory the sqlalchemy_session_persistence to both flush and commit, and I get a similar error.

    self = <sqlalchemy.dialects.mssql.pyodbc.MSDialect_pyodbc object at 0x7ff02aeea460>, cursor = <pyodbc.Cursor object at 0x7ff01861b430>, statement = 'SET IDENTITY_INSERT [Mission] ON'
    parameters = (), context = <sqlalchemy.dialects.mssql.pyodbc.MSExecutionContext_pyodbc object at 0x7ff018627280>
    
        def do_execute(self, cursor, statement, parameters, context=None):
    >       cursor.execute(statement, parameters)
    E       sqlalchemy.exc.ProgrammingError: (pyodbc.ProgrammingError) ('42000', '[42000] [Microsoft][ODBC Driver 17 for SQL Server][SQL Server]Cannot find the object "Mission" because it does not exist or you do not have permissions. (1088) (SQLExecDirectW)')
    E       [SQL: SET IDENTITY_INSERT [Mission] ON]
    E       (Background on this error at: http://sqlalche.me/e/13/f405)
    

    Notes

    Full traceback

    session.query(Base.classes.Mission).all()
    ---------------------------------------------------------------------------
    ProgrammingError                          Traceback (most recent call last)
    ~/anaconda3/envs/jwstdb/lib/python3.8/site-packages/sqlalchemy/engine/base.py in _cursor_execute(self, cursor, statement, parameters, context)
       1350             else:
    -> 1351                 self.dialect.do_execute(cursor, statement, parameters, context)
       1352         except BaseException as e:
    
    ~/anaconda3/envs/jwstdb/lib/python3.8/site-packages/sqlalchemy/engine/default.py in do_execute(self, cursor, statement, parameters, context)
        607     def do_execute(self, cursor, statement, parameters, context=None):
    --> 608         cursor.execute(statement, parameters)
        609
    
    ProgrammingError: ('42000', '[42000] [Microsoft][ODBC Driver 17 for SQL Server][SQL Server]Cannot find the object "Mission" because it does not exist or you do not have permissions. (1088) (SQLExecDirectW)')
    
    The above exception was the direct cause of the following exception:
    
    ProgrammingError                          Traceback (most recent call last)
    <ipython-input-12-8dca229657eb> in <module>
    ----> 1 session.query(Base.classes.Mission).all()
    
    ~/anaconda3/envs/jwstdb/lib/python3.8/site-packages/sqlalchemy/orm/query.py in all(self)
       3371                 :ref:`faq_query_deduplicating`
       3372         """
    -> 3373         return list(self)
       3374
       3375     @_generative(_no_clauseelement_condition)
    
    ~/anaconda3/envs/jwstdb/lib/python3.8/site-packages/sqlalchemy/orm/query.py in __iter__(self)
       3532         context.statement.use_labels = True
       3533         if self._autoflush and not self._populate_existing:
    -> 3534             self.session._autoflush()
       3535         return self._execute_and_instances(context)
       3536
    
    ~/anaconda3/envs/jwstdb/lib/python3.8/site-packages/sqlalchemy/orm/session.py in _autoflush(self)
       1631                     "flush is occurring prematurely"
       1632                 )
    -> 1633                 util.raise_(e, with_traceback=sys.exc_info()[2])
       1634
       1635     def refresh(
    
    ~/anaconda3/envs/jwstdb/lib/python3.8/site-packages/sqlalchemy/util/compat.py in raise_(***failed resolving arguments***)
        180
        181         try:
    --> 182             raise exception
        183         finally:
        184             # credit to
    
    ~/anaconda3/envs/jwstdb/lib/python3.8/site-packages/sqlalchemy/orm/session.py in _autoflush(self)
       1620         if self.autoflush and not self._flushing:
       1621             try:
    -> 1622                 self.flush()
       1623             except sa_exc.StatementError as e:
       1624                 # note we are reraising StatementError as opposed to
    
    ~/anaconda3/envs/jwstdb/lib/python3.8/site-packages/sqlalchemy/orm/session.py in flush(self, objects)
       2538         try:
       2539             self._flushing = True
    -> 2540             self._flush(objects)
       2541         finally:
       2542             self._flushing = False
    
    ~/anaconda3/envs/jwstdb/lib/python3.8/site-packages/sqlalchemy/orm/session.py in _flush(self, objects)
       2680         except:
       2681             with util.safe_reraise():
    -> 2682                 transaction.rollback(_capture_exception=True)
       2683
       2684     def bulk_save_objects(
    
    ~/anaconda3/envs/jwstdb/lib/python3.8/site-packages/sqlalchemy/util/langhelpers.py in __exit__(self, type_, value, traceback)
         66             self._exc_info = None  # remove potential circular references
         67             if not self.warn_only:
    ---> 68                 compat.raise_(
         69                     exc_value,
         70                     with_traceback=exc_tb,
    
    ~/anaconda3/envs/jwstdb/lib/python3.8/site-packages/sqlalchemy/util/compat.py in raise_(***failed resolving arguments***)
        180
        181         try:
    --> 182             raise exception
        183         finally:
        184             # credit to
    
    ~/anaconda3/envs/jwstdb/lib/python3.8/site-packages/sqlalchemy/orm/session.py in _flush(self, objects)
       2640             self._warn_on_events = True
       2641             try:
    -> 2642                 flush_context.execute()
       2643             finally:
       2644                 self._warn_on_events = False
    
    ~/anaconda3/envs/jwstdb/lib/python3.8/site-packages/sqlalchemy/orm/unitofwork.py in execute(self)
        420         else:
        421             for rec in topological.sort(self.dependencies, postsort_actions):
    --> 422                 rec.execute(self)
        423
        424     def finalize_flush_changes(self):
    
    ~/anaconda3/envs/jwstdb/lib/python3.8/site-packages/sqlalchemy/orm/unitofwork.py in execute(self, uow)
        584
        585     def execute(self, uow):
    --> 586         persistence.save_obj(
        587             self.mapper,
        588             uow.states_for_mapper_hierarchy(self.mapper, False, False),
    
    ~/anaconda3/envs/jwstdb/lib/python3.8/site-packages/sqlalchemy/orm/persistence.py in save_obj(base_mapper, states, uowtransaction, single)
        237         )
        238
    --> 239         _emit_insert_statements(
        240             base_mapper,
        241             uowtransaction,
    
    ~/anaconda3/envs/jwstdb/lib/python3.8/site-packages/sqlalchemy/orm/persistence.py in _emit_insert_statements(base_mapper, uowtransaction, cached_connections, mapper, table, insert, bookkeeping)
       1081             multiparams = [rec[2] for rec in records]
       1082
    -> 1083             c = cached_connections[connection].execute(statement, multiparams)
       1084             if bookkeeping:
       1085                 for (
    
    ~/anaconda3/envs/jwstdb/lib/python3.8/site-packages/sqlalchemy/engine/base.py in execute(self, object_, *multiparams, **params)
       1009             )
       1010         else:
    -> 1011             return meth(self, multiparams, params)
       1012
       1013     def _execute_function(self, func, multiparams, params):
    
    ~/anaconda3/envs/jwstdb/lib/python3.8/site-packages/sqlalchemy/sql/elements.py in _execute_on_connection(self, connection, multiparams, params)
        296     def _execute_on_connection(self, connection, multiparams, params):
        297         if self.supports_execution:
    --> 298             return connection._execute_clauseelement(self, multiparams, params)
        299         else:
        300             raise exc.ObjectNotExecutableError(self)
    
    ~/anaconda3/envs/jwstdb/lib/python3.8/site-packages/sqlalchemy/engine/base.py in _execute_clauseelement(self, elem, multiparams, params)
       1122             )
       1123
    -> 1124         ret = self._execute_context(
       1125             dialect,
       1126             dialect.execution_ctx_cls._init_compiled,
    
    ~/anaconda3/envs/jwstdb/lib/python3.8/site-packages/sqlalchemy/engine/base.py in _execute_context(self, dialect, constructor, statement, parameters, *args)
       1209
       1210         if context.compiled:
    -> 1211             context.pre_exec()
       1212
       1213         cursor, statement, parameters = (
    
    ~/anaconda3/envs/jwstdb/lib/python3.8/site-packages/sqlalchemy/dialects/mssql/pyodbc.py in pre_exec(self)
        310         """
        311
    --> 312         super(MSExecutionContext_pyodbc, self).pre_exec()
        313
        314         # don't embed the scope_identity select into an
    
    ~/anaconda3/envs/jwstdb/lib/python3.8/site-packages/sqlalchemy/dialects/mssql/base.py in pre_exec(self)
       1492
       1493             if self._enable_identity_insert:
    -> 1494                 self.root_connection._cursor_execute(
       1495                     self.cursor,
       1496                     self._opt_encode(
    
    ~/anaconda3/envs/jwstdb/lib/python3.8/site-packages/sqlalchemy/engine/base.py in _cursor_execute(self, cursor, statement, parameters, context)
       1351                 self.dialect.do_execute(cursor, statement, parameters, context)
       1352         except BaseException as e:
    -> 1353             self._handle_dbapi_exception(
       1354                 e, statement, parameters, cursor, context
       1355             )
    
    ~/anaconda3/envs/jwstdb/lib/python3.8/site-packages/sqlalchemy/engine/base.py in _handle_dbapi_exception(self, e, statement, parameters, cursor, context)
       1508                 util.raise_(newraise, with_traceback=exc_info[2], from_=e)
       1509             elif should_wrap:
    -> 1510                 util.raise_(
       1511                     sqlalchemy_exception, with_traceback=exc_info[2], from_=e
       1512                 )
    
    ~/anaconda3/envs/jwstdb/lib/python3.8/site-packages/sqlalchemy/util/compat.py in raise_(***failed resolving arguments***)
        180
        181         try:
    --> 182             raise exception
        183         finally:
        184             # credit to
    
    ~/anaconda3/envs/jwstdb/lib/python3.8/site-packages/sqlalchemy/engine/base.py in _cursor_execute(self, cursor, statement, parameters, context)
       1349                     break
       1350             else:
    -> 1351                 self.dialect.do_execute(cursor, statement, parameters, context)
       1352         except BaseException as e:
       1353             self._handle_dbapi_exception(
    
    ~/anaconda3/envs/jwstdb/lib/python3.8/site-packages/sqlalchemy/engine/default.py in do_execute(self, cursor, statement, parameters, context)
        606
        607     def do_execute(self, cursor, statement, parameters, context=None):
    --> 608         cursor.execute(statement, parameters)
        609
        610     def do_execute_no_params(self, cursor, statement, context=None):
    
    ProgrammingError: (raised as a result of Query-invoked autoflush; consider using a session.no_autoflush block if this flush is occurring prematurely)
    (pyodbc.ProgrammingError) ('42000', '[42000] [Microsoft][ODBC Driver 17 for SQL Server][SQL Server]Cannot find the object "Mission" because it does not exist or you do not have permissions. (1088) (SQLExecDirectW)')
    [SQL: SET IDENTITY_INSERT [Mission] ON]
    (Background on this error at: http://sqlalche.me/e/13/f405)
    
    opened by havok2063 1
  • 3.2.1 sphinx warnings `reference target not found`

    3.2.1 sphinx warnings `reference target not found`

    Firs of all currently it is npt possible to use spraight sphinx-build because missing path to module in copy.py

    + /usr/bin/sphinx-build -n -T -b man docs build/sphinx/man
    Running Sphinx v4.5.0
    
    Traceback (most recent call last):
      File "/usr/lib/python3.8/site-packages/sphinx/config.py", line 332, in eval_config_file
        exec(code, namespace)
      File "/home/tkloczko/rpmbuild/BUILD/factory_boy-3.2.1/docs/conf.py", line 12, in <module>
        import factory
    ModuleNotFoundError: No module named 'factory'
    
    The above exception was the direct cause of the following exception:
    
    Traceback (most recent call last):
      File "/usr/lib/python3.8/site-packages/sphinx/cmd/build.py", line 272, in build_main
        app = Sphinx(args.sourcedir, args.confdir, args.outputdir,
      File "/usr/lib/python3.8/site-packages/sphinx/application.py", line 202, in __init__
        self.config = Config.read(self.confdir, confoverrides or {}, self.tags)
      File "/usr/lib/python3.8/site-packages/sphinx/config.py", line 165, in read
        namespace = eval_config_file(filename, tags)
      File "/usr/lib/python3.8/site-packages/sphinx/config.py", line 345, in eval_config_file
        raise ConfigError(msg % traceback.format_exc()) from exc
    sphinx.errors.ConfigError: There is a programmable error in your configuration file:
    
    Traceback (most recent call last):
      File "/usr/lib/python3.8/site-packages/sphinx/config.py", line 332, in eval_config_file
        exec(code, namespace)
      File "/home/tkloczko/rpmbuild/BUILD/factory_boy-3.2.1/docs/conf.py", line 12, in <module>
        import factory
    ModuleNotFoundError: No module named 'factory'
    
    
    Configuration error:
    There is a programmable error in your configuration file:
    
    Traceback (most recent call last):
      File "/usr/lib/python3.8/site-packages/sphinx/config.py", line 332, in eval_config_file
        exec(code, namespace)
      File "/home/tkloczko/rpmbuild/BUILD/factory_boy-3.2.1/docs/conf.py", line 12, in <module>
        import factory
    ModuleNotFoundError: No module named 'factory'
    

    Thi can be fixed by patch like below

    --- a/docs/conf.py~     2021-10-26 14:02:25.000000000 +0000
    +++ b/docs/conf.py      2022-05-14 17:15:28.667904146 +0000
    @@ -9,13 +9,12 @@
     import os
     import sys
    
    -import factory
    -
     # If extensions (or modules to document with autodoc) are in another directory,
     # add these directories to sys.path here. If the directory is relative to the
     # documentation root, use os.path.abspath to make it absolute, like shown here.
    -sys.path.insert(0, os.path.dirname(os.path.abspath('.')))
    +sys.path.insert(0, os.path.abspath('..'))
    
    +import factory
    
     # -- Project information -----------------------------------------------------
    

    Tan .. on building my packages I'm using sphinx-build command with -n switch which shows warmings about missing references. These are not critical issues. Here is the output with warnings:

    + /usr/bin/sphinx-build -n -T -b man docs build/sphinx/man
    Running Sphinx v4.5.0
    making output directory... done
    loading intersphinx inventory from https://docs.python.org/objects.inv...
    loading intersphinx inventory from https://docs.djangoproject.com/en/dev/_objects/...
    loading intersphinx inventory from https://docs.sqlalchemy.org/en/latest/objects.inv...
    intersphinx inventory has moved: https://docs.python.org/objects.inv -> https://docs.python.org/3/objects.inv
    intersphinx inventory has moved: https://docs.sqlalchemy.org/en/latest/objects.inv -> https://docs.sqlalchemy.org/en/14/objects.inv
    building [mo]: targets for 0 po files that are out of date
    building [man]: all manpages
    updating environment: [new config] 11 added, 0 changed, 0 removed
    reading sources... [100%] reference
    looking for now-outdated files... none found
    pickling environment... done
    checking consistency... done
    writing... python-factory-boy.3 { introduction reference orms recipes fuzzy examples internals changelog credits ideas } /home/tkloczko/rpmbuild/BUILD/factory_boy-3.2.1/docs/introduction.rst:107: WARNING: py:meth reference target not found: [email protected]
    /home/tkloczko/rpmbuild/BUILD/factory_boy-3.2.1/docs/introduction.rst:145: WARNING: py:meth reference target not found: [email protected]_attribute
    /home/tkloczko/rpmbuild/BUILD/factory_boy-3.2.1/docs/introduction.rst:179: WARNING: py:meth reference target not found: [email protected]_attribute
    /home/tkloczko/rpmbuild/BUILD/factory_boy-3.2.1/docs/reference.rst:206: WARNING: py:obj reference target not found: size
    /home/tkloczko/rpmbuild/BUILD/factory_boy-3.2.1/docs/reference.rst:216: WARNING: py:obj reference target not found: size
    /home/tkloczko/rpmbuild/BUILD/factory_boy-3.2.1/docs/reference.rst:226: WARNING: py:obj reference target not found: size
    /home/tkloczko/rpmbuild/BUILD/factory_boy-3.2.1/docs/reference.rst:231: WARNING: py:obj reference target not found: strategy
    /home/tkloczko/rpmbuild/BUILD/factory_boy-3.2.1/docs/reference.rst:235: WARNING: py:obj reference target not found: size
    /home/tkloczko/rpmbuild/BUILD/factory_boy-3.2.1/docs/reference.rst:244: WARNING: py:obj reference target not found: size
    /home/tkloczko/rpmbuild/BUILD/factory_boy-3.2.1/docs/reference.rst:599: WARNING: py:obj reference target not found: strategy
    /home/tkloczko/rpmbuild/BUILD/factory_boy-3.2.1/docs/reference.rst:668: WARNING: py:class reference target not found: file
    /home/tkloczko/rpmbuild/BUILD/factory_boy-3.2.1/docs/reference.rst:835: WARNING: py:meth reference target not found: LazyAttribute.lazy_attribute
    /home/tkloczko/rpmbuild/BUILD/factory_boy-3.2.1/docs/reference.rst:868: WARNING: py:class reference target not found: builder.Resolver
    /home/tkloczko/rpmbuild/BUILD/factory_boy-3.2.1/docs/reference.rst:1127: WARNING: py:attr reference target not found: factory.SubFactory.factory
    /home/tkloczko/rpmbuild/BUILD/factory_boy-3.2.1/docs/reference.rst:1334: WARNING: py:attr reference target not found: builder.Resolver.factory_parent
    /home/tkloczko/rpmbuild/BUILD/factory_boy-3.2.1/docs/reference.rst:1788: WARNING: py:attr reference target not found: size
    /home/tkloczko/rpmbuild/BUILD/factory_boy-3.2.1/docs/reference.rst:2008: WARNING: py:mod reference target not found: factory
    /home/tkloczko/rpmbuild/BUILD/factory_boy-3.2.1/docs/reference.rst:2016: WARNING: py:class reference target not found: factory.base.Factory
    /home/tkloczko/rpmbuild/BUILD/factory_boy-3.2.1/docs/reference.rst:2024: WARNING: py:obj reference target not found: klass
    /home/tkloczko/rpmbuild/BUILD/factory_boy-3.2.1/docs/reference.rst:2024: WARNING: py:obj reference target not found: size
    /home/tkloczko/rpmbuild/BUILD/factory_boy-3.2.1/docs/reference.rst:2034: WARNING: py:class reference target not found: class
    /home/tkloczko/rpmbuild/BUILD/factory_boy-3.2.1/docs/reference.rst:2038: WARNING: py:obj reference target not found: klass
    /home/tkloczko/rpmbuild/BUILD/factory_boy-3.2.1/docs/reference.rst:2038: WARNING: py:obj reference target not found: size
    /home/tkloczko/rpmbuild/BUILD/factory_boy-3.2.1/docs/reference.rst:2048: WARNING: py:class reference target not found: class
    /home/tkloczko/rpmbuild/BUILD/factory_boy-3.2.1/docs/reference.rst:2052: WARNING: py:obj reference target not found: klass
    /home/tkloczko/rpmbuild/BUILD/factory_boy-3.2.1/docs/reference.rst:2052: WARNING: py:obj reference target not found: size
    /home/tkloczko/rpmbuild/BUILD/factory_boy-3.2.1/docs/reference.rst:2062: WARNING: py:class reference target not found: class
    /home/tkloczko/rpmbuild/BUILD/factory_boy-3.2.1/docs/reference.rst:2066: WARNING: py:obj reference target not found: klass
    /home/tkloczko/rpmbuild/BUILD/factory_boy-3.2.1/docs/reference.rst:2066: WARNING: py:obj reference target not found: strategy
    /home/tkloczko/rpmbuild/BUILD/factory_boy-3.2.1/docs/reference.rst:2066: WARNING: py:obj reference target not found: size
    /home/tkloczko/rpmbuild/BUILD/factory_boy-3.2.1/docs/reference.rst:2077: WARNING: py:class reference target not found: class
    /home/tkloczko/rpmbuild/BUILD/factory_boy-3.2.1/docs/reference.rst:2081: WARNING: py:obj reference target not found: klass
    /home/tkloczko/rpmbuild/BUILD/factory_boy-3.2.1/docs/reference.rst:2081: WARNING: py:obj reference target not found: size
    /home/tkloczko/rpmbuild/BUILD/factory_boy-3.2.1/docs/reference.rst:2091: WARNING: py:class reference target not found: class
    /home/tkloczko/rpmbuild/BUILD/factory_boy-3.2.1/docs/reference.rst:2100: WARNING: py:mod reference target not found: factory.random
    /home/tkloczko/rpmbuild/BUILD/factory_boy-3.2.1/docs/reference.rst:2116: WARNING: py:meth reference target not found: random.seed
    /home/tkloczko/rpmbuild/BUILD/factory_boy-3.2.1/docs/orms.rst:129: WARNING: py:class reference target not found: file
    /home/tkloczko/rpmbuild/BUILD/factory_boy-3.2.1/docs/orms.rst:129: WARNING: py:class reference target not found: func
    /home/tkloczko/rpmbuild/BUILD/factory_boy-3.2.1/docs/orms.rst:166: WARNING: py:class reference target not found: file
    /home/tkloczko/rpmbuild/BUILD/factory_boy-3.2.1/docs/orms.rst:166: WARNING: py:class reference target not found: func
    /home/tkloczko/rpmbuild/BUILD/factory_boy-3.2.1/docs/orms.rst:270: WARNING: py:attr reference target not found: associated class <factory.FactoryOptions.model
    /home/tkloczko/rpmbuild/BUILD/factory_boy-3.2.1/docs/orms.rst:270: WARNING: py:class reference target not found: mongoengine.EmbeddedDocument
    /home/tkloczko/rpmbuild/BUILD/factory_boy-3.2.1/docs/orms.rst:270: WARNING: py:meth reference target not found: MongoEngineFactory.create
    /home/tkloczko/rpmbuild/BUILD/factory_boy-3.2.1/docs/orms.rst:322: WARNING: py:meth reference target not found: sqlalchemy.orm.session.Session.add
    /home/tkloczko/rpmbuild/BUILD/factory_boy-3.2.1/docs/orms.rst:327: WARNING: py:class reference target not found: factory.base.FactoryOptions
    /home/tkloczko/rpmbuild/BUILD/factory_boy-3.2.1/docs/orms.rst:342: WARNING: py:meth reference target not found: sqlalchemy.orm.session.Session.flush
    /home/tkloczko/rpmbuild/BUILD/factory_boy-3.2.1/docs/orms.rst:343: WARNING: py:meth reference target not found: sqlalchemy.orm.session.Session.commit
    /home/tkloczko/rpmbuild/BUILD/factory_boy-3.2.1/docs/orms.rst:351: WARNING: py:meth reference target not found: sqlalchemy.orm.query.Query.one_or_none
    /home/tkloczko/rpmbuild/BUILD/factory_boy-3.2.1/docs/orms.rst:351: WARNING: py:meth reference target not found: sqlalchemy.orm.session.Session.add
    /home/tkloczko/rpmbuild/BUILD/factory_boy-3.2.1/docs/recipes.rst:90: WARNING: py:class reference target not found: UserFactory
    /home/tkloczko/rpmbuild/BUILD/factory_boy-3.2.1/docs/recipes.rst:102: WARNING: py:meth reference target not found: factory.Factory._generate
    /home/tkloczko/rpmbuild/BUILD/factory_boy-3.2.1/docs/recipes.rst:213: WARNING: py:class reference target not found: RelatedFactory
    /home/tkloczko/rpmbuild/BUILD/factory_boy-3.2.1/docs/recipes.rst:213: WARNING: py:class reference target not found: RelatedFactory
    /home/tkloczko/rpmbuild/BUILD/factory_boy-3.2.1/docs/fuzzy.rst:364: WARNING: py:obj reference target not found: factory.random.randgen
    /home/tkloczko/rpmbuild/BUILD/factory_boy-3.2.1/docs/fuzzy.rst:364: WARNING: py:meth reference target not found: get_random_state
    /home/tkloczko/rpmbuild/BUILD/factory_boy-3.2.1/docs/examples.rst:80: WARNING: py:class reference target not found: Account
    /home/tkloczko/rpmbuild/BUILD/factory_boy-3.2.1/docs/examples.rst:80: WARNING: py:class reference target not found: Profile
    /home/tkloczko/rpmbuild/BUILD/factory_boy-3.2.1/docs/internals.rst:56: WARNING: py:meth reference target not found: Factory.__call__
    /home/tkloczko/rpmbuild/BUILD/factory_boy-3.2.1/docs/internals.rst:60: WARNING: py:meth reference target not found: Factory._generate
    /home/tkloczko/rpmbuild/BUILD/factory_boy-3.2.1/docs/internals.rst:62: WARNING: py:meth reference target not found: Factory._generate_batch`
    /home/tkloczko/rpmbuild/BUILD/factory_boy-3.2.1/docs/internals.rst:64: WARNING: py:meth reference target not found: Factory._generate
    /home/tkloczko/rpmbuild/BUILD/factory_boy-3.2.1/docs/internals.rst:84: WARNING: py:meth reference target not found: FactoryOptions.instantiate
    /home/tkloczko/rpmbuild/BUILD/factory_boy-3.2.1/docs/changelog.rst:17: WARNING: py:meth reference target not found: factory.alchemy.SQLAlchemyModelFactory._save
    /home/tkloczko/rpmbuild/BUILD/factory_boy-3.2.1/docs/changelog.rst:17: WARNING: py:meth reference target not found: factory.alchemy.SQLAlchemyModelFactory._get_or_create
    /home/tkloczko/rpmbuild/BUILD/factory_boy-3.2.1/docs/changelog.rst:103: WARNING: py:attr reference target not found: factory.Factory.model
    /home/tkloczko/rpmbuild/BUILD/factory_boy-3.2.1/docs/changelog.rst:105: WARNING: py:meth reference target not found: get_random_state
    /home/tkloczko/rpmbuild/BUILD/factory_boy-3.2.1/docs/changelog.rst:110: WARNING: py:class reference target not found: factory.declarations.SubFactory
    /home/tkloczko/rpmbuild/BUILD/factory_boy-3.2.1/docs/changelog.rst:128: WARNING: py:attr reference target not found: factory.fuzzy.FuzzyChoice.getter
    /home/tkloczko/rpmbuild/BUILD/factory_boy-3.2.1/docs/changelog.rst:130: WARNING: py:meth reference target not found: factory.faker.Faker.generate
    /home/tkloczko/rpmbuild/BUILD/factory_boy-3.2.1/docs/changelog.rst:132: WARNING: py:class reference target not found: factory.faker.Faker
    /home/tkloczko/rpmbuild/BUILD/factory_boy-3.2.1/docs/changelog.rst:154: WARNING: py:class reference target not found: factory.declarations.ParameteredAttribute
    /home/tkloczko/rpmbuild/BUILD/factory_boy-3.2.1/docs/changelog.rst:169: WARNING: py:class reference target not found: factory.PostGenerationDeclaration
    /home/tkloczko/rpmbuild/BUILD/factory_boy-3.2.1/docs/changelog.rst:291: WARNING: py:func reference target not found: django.apps.apps.get_model
    /home/tkloczko/rpmbuild/BUILD/factory_boy-3.2.1/docs/changelog.rst:292: WARNING: py:meth reference target not found: mogo.model.Model.new
    /home/tkloczko/rpmbuild/BUILD/factory_boy-3.2.1/docs/changelog.rst:401: WARNING: py:attr reference target not found: factory.Factory.FACTORY_FOR
    /home/tkloczko/rpmbuild/BUILD/factory_boy-3.2.1/docs/changelog.rst:402: WARNING: py:attr reference target not found: factory.Factory.ABSTRACT_FACTORY
    /home/tkloczko/rpmbuild/BUILD/factory_boy-3.2.1/docs/changelog.rst:403: WARNING: py:attr reference target not found: factory.Factory.FACTORY_STRATEGY
    /home/tkloczko/rpmbuild/BUILD/factory_boy-3.2.1/docs/changelog.rst:404: WARNING: py:attr reference target not found: factory.Factory.FACTORY_ARG_PARAMETERS
    /home/tkloczko/rpmbuild/BUILD/factory_boy-3.2.1/docs/changelog.rst:405: WARNING: py:attr reference target not found: factory.Factory.FACTORY_HIDDEN_ARGS
    /home/tkloczko/rpmbuild/BUILD/factory_boy-3.2.1/docs/changelog.rst:409: WARNING: py:attr reference target not found: factory.django.DjangoModelFactory.FACTORY_DJANGO_GET_OR_CREATE
    /home/tkloczko/rpmbuild/BUILD/factory_boy-3.2.1/docs/changelog.rst:413: WARNING: py:attr reference target not found: factory.alchemy.SQLAlchemyModelFactory.FACTORY_SESSION
    /home/tkloczko/rpmbuild/BUILD/factory_boy-3.2.1/docs/changelog.rst:435: WARNING: py:class reference target not found: mongoengine.EmbeddedDocument
    /home/tkloczko/rpmbuild/BUILD/factory_boy-3.2.1/docs/changelog.rst:454: WARNING: py:mod reference target not found: factory
    /home/tkloczko/rpmbuild/BUILD/factory_boy-3.2.1/docs/changelog.rst:475: WARNING: py:class reference target not found: factory.Factory.ABSTRACT_FACTORY
    /home/tkloczko/rpmbuild/BUILD/factory_boy-3.2.1/docs/changelog.rst:475: WARNING: py:class reference target not found: factory.Factory.FACTORY_FOR
    /home/tkloczko/rpmbuild/BUILD/factory_boy-3.2.1/docs/changelog.rst:498: WARNING: py:attr reference target not found: factory.builder.Resolver.factory_parent
    /home/tkloczko/rpmbuild/BUILD/factory_boy-3.2.1/docs/changelog.rst:498: WARNING: py:class reference target not found: factory.builder.Resolver
    /home/tkloczko/rpmbuild/BUILD/factory_boy-3.2.1/docs/changelog.rst:501: WARNING: py:mod reference target not found: factory.django
    /home/tkloczko/rpmbuild/BUILD/factory_boy-3.2.1/docs/changelog.rst:501: WARNING: py:mod reference target not found: factory.mogo
    /home/tkloczko/rpmbuild/BUILD/factory_boy-3.2.1/docs/changelog.rst:530: WARNING: py:attr reference target not found: factory.django.DjangoModelFactory.FACTORY_DJANGO_GET_OR_CREATE
    /home/tkloczko/rpmbuild/BUILD/factory_boy-3.2.1/docs/changelog.rst:541: WARNING: py:attr reference target not found: factory.django.DjangoModelFactory.FACTORY_DJANGO_GET_OR_CREATE
    /home/tkloczko/rpmbuild/BUILD/factory_boy-3.2.1/docs/changelog.rst:554: WARNING: py:attr reference target not found: factory.Sequence.type
    /home/tkloczko/rpmbuild/BUILD/factory_boy-3.2.1/docs/changelog.rst:555: WARNING: py:attr reference target not found: factory.Factory.FACTORY_HIDDEN_ARGS
    /home/tkloczko/rpmbuild/BUILD/factory_boy-3.2.1/docs/changelog.rst:557: WARNING: py:attr reference target not found: factory.django.DjangoModelFactory.FACTORY_DJANGO_GET_OR_CREATE
    /home/tkloczko/rpmbuild/BUILD/factory_boy-3.2.1/docs/changelog.rst:566: WARNING: py:class reference target not found: factory.InfiniteIterator
    /home/tkloczko/rpmbuild/BUILD/factory_boy-3.2.1/docs/changelog.rst:566: WARNING: py:func reference target not found: factory.infinite_iterator
    /home/tkloczko/rpmbuild/BUILD/factory_boy-3.2.1/docs/changelog.rst:567: WARNING: py:class reference target not found: factory.CircularSubFactory
    /home/tkloczko/rpmbuild/BUILD/factory_boy-3.2.1/docs/changelog.rst:571: WARNING: py:meth reference target not found: factory.Factory.set_building_function
    /home/tkloczko/rpmbuild/BUILD/factory_boy-3.2.1/docs/changelog.rst:571: WARNING: py:meth reference target not found: factory.Factory.set_creation_function
    /home/tkloczko/rpmbuild/BUILD/factory_boy-3.2.1/docs/changelog.rst:594: WARNING: py:attr reference target not found: factory.Factory.FACTORY_ARG_PARAMETERS
    /home/tkloczko/rpmbuild/BUILD/factory_boy-3.2.1/docs/changelog.rst:596: WARNING: py:attr reference target not found: factory.Factory.FACTORY_FOR
    /home/tkloczko/rpmbuild/BUILD/factory_boy-3.2.1/docs/changelog.rst:617: WARNING: py:class reference target not found: factory.InfiniteIterator
    /home/tkloczko/rpmbuild/BUILD/factory_boy-3.2.1/docs/changelog.rst:618: WARNING: py:class reference target not found: factory.CircularSubFactory
    /home/tkloczko/rpmbuild/BUILD/factory_boy-3.2.1/docs/changelog.rst:622: WARNING: py:meth reference target not found: factory.Factory.set_creation_function
    /home/tkloczko/rpmbuild/BUILD/factory_boy-3.2.1/docs/changelog.rst:622: WARNING: py:meth reference target not found: factory.Factory.set_building_function
    /home/tkloczko/rpmbuild/BUILD/factory_boy-3.2.1/docs/changelog.rst:624: WARNING: py:attr reference target not found: factory.Factory.FACTORY_FOR
    /home/tkloczko/rpmbuild/BUILD/factory_boy-3.2.1/docs/changelog.rst:661: WARNING: py:class reference target not found: factory.CircularSubFactory
    /home/tkloczko/rpmbuild/BUILD/factory_boy-3.2.1/docs/changelog.rst:671: WARNING: py:class reference target not found: factory.PostGenerationDeclaration
    /home/tkloczko/rpmbuild/BUILD/factory_boy-3.2.1/docs/changelog.rst:705: WARNING: py:class reference target not found: factory.InfiniteIterator
    /home/tkloczko/rpmbuild/BUILD/factory_boy-3.2.1/docs/changelog.rst:728: WARNING: py:class reference target not found: factory.ContainerAttribute
    /home/tkloczko/rpmbuild/BUILD/factory_boy-3.2.1/docs/changelog.rst:738: WARNING: py:attr reference target not found: factory.Factory.FACTORY_FOR
    /home/tkloczko/rpmbuild/BUILD/factory_boy-3.2.1/docs/changelog.rst:751: WARNING: py:data reference target not found: factory.MOGO_BUILD
    /home/tkloczko/rpmbuild/BUILD/factory_boy-3.2.1/docs/changelog.rst:753: WARNING: py:attr reference target not found: factory.Factory.ABSTRACT_FACTORY
    /home/tkloczko/rpmbuild/BUILD/factory_boy-3.2.1/docs/ideas.rst:7: WARNING: py:class reference target not found: Factory
    done
    build succeeded, 114 warnings.
    

    You can peak on fixes that kind of issues in other projects https://github.com/latchset/jwcrypto/pull/289 https://github.com/click-contrib/sphinx-click/commit/abc31069

    Doc BeginnerFriendly 
    opened by kloczek 0
  • Please improve the documentation for Subfactory

    Please improve the documentation for Subfactory

    The problem

    It isn't clear what Subfactory actually does from the docs

    This attribute declaration calls another Factory subclass, selecting the same build strategy and collecting extra kwargs in the process.

    Its not clear what it means by "selecting the same build strategy" - the same build strategy as the passed subclass? This as the primary description doesn't explain anything about why using Subfactory is different from using the passed factory directly.

    Proposed solution

    I don't know what Subfactory is still, so I can't propose a solution. But I think a more substantial explanation at the top of the section for that is warranted.

    Doc 
    opened by billytetrud 3
Owner
FactoryBoy project
Contributors to the factory_boy Python library, and related projects
FactoryBoy project
A drop-in replacement for Django's runserver.

About A drop in replacement for Django's built-in runserver command. Features include: An extendable interface for handling things such as real-time l

David Cramer 1.3k Apr 13, 2022
Green is a clean, colorful, fast python test runner.

Green -- A clean, colorful, fast python test runner. Features Clean - Low redundancy in output. Result statistics for each test is vertically aligned.

Nathan Stocks 737 May 23, 2022
splinter - python test framework for web applications

splinter - python tool for testing web applications splinter is an open source tool for testing web applications using Python. It lets you automate br

Cobra Team 2.5k Jun 10, 2022
create custom test databases that are populated with fake data

About Generate fake but valid data filled databases for test purposes using most popular patterns(AFAIK). Current support is sqlite, mysql, postgresql

Emir Ozer 2.1k Jun 8, 2022
Scalable user load testing tool written in Python

Locust Locust is an easy to use, scriptable and scalable performance testing tool. You define the behaviour of your users in regular Python code, inst

Locust.io 19k Jun 7, 2022
A cross-platform GUI automation Python module for human beings. Used to programmatically control the mouse & keyboard.

PyAutoGUI PyAutoGUI is a cross-platform GUI automation Python module for human beings. Used to programmatically control the mouse & keyboard. pip inst

Al Sweigart 6.7k Jun 7, 2022
Let your Python tests travel through time

FreezeGun: Let your Python tests travel through time FreezeGun is a library that allows your Python tests to travel through time by mocking the dateti

Steve Pulec 3.3k Jun 6, 2022
HTTP client mocking tool for Python - inspired by Fakeweb for Ruby

HTTPretty 1.0.5 HTTP Client mocking tool for Python created by Gabriel Falcão . It provides a full fake TCP socket module. Inspired by FakeWeb Github

Gabriel Falcão 2k May 31, 2022
A utility for mocking out the Python Requests library.

Responses A utility library for mocking out the requests Python library. Note Responses requires Python 2.7 or newer, and requests >= 2.0 Installing p

Sentry 3.6k Jun 6, 2022
Faker is a Python package that generates fake data for you.

Faker is a Python package that generates fake data for you. Whether you need to bootstrap your database, create good-looking XML documents, fill-in yo

Daniele Faraglia 14.2k May 29, 2022
Mimesis is a high-performance fake data generator for Python, which provides data for a variety of purposes in a variety of languages.

Mimesis - Fake Data Generator Description Mimesis is a high-performance fake data generator for Python, which provides data for a variety of purposes

Isaak Uchakaev 3.6k Jun 1, 2022
Coroutine-based concurrency library for Python

gevent Read the documentation online at http://www.gevent.org. Post issues on the bug tracker, discuss and ask open ended questions on the mailing lis

gevent 5.8k Jun 9, 2022
Radically simplified static file serving for Python web apps

WhiteNoise Radically simplified static file serving for Python web apps With a couple of lines of config WhiteNoise allows your web app to serve its o

Dave Evans 2k Jun 9, 2022
livereload server in python (MAINTAINERS NEEDED)

LiveReload Reload webpages on changes, without hitting refresh in your browser. Installation python-livereload is for web developers who know Python,

Hsiaoming Yang 966 May 31, 2022
A screamingly fast Python 2/3 WSGI server written in C.

bjoern: Fast And Ultra-Lightweight HTTP/1.1 WSGI Server A screamingly fast, ultra-lightweight WSGI server for CPython 2 and CPython 3, written in C us

Jonas Haag 2.8k May 31, 2022
Waitress - A WSGI server for Python 2 and 3

Waitress Waitress is a production-quality pure-Python WSGI server with very acceptable performance. It has no dependencies except ones which live in t

Pylons Project 1.1k Jun 3, 2022
Python HTTP Server

Python HTTP Server Preview Languange and Code Editor: How to run? Download the zip first. Open the http.py and wait 1-2 seconds. You will see __pycach

SonLyte 16 Oct 21, 2021
PyQaver is a PHP like WebServer for Python.

PyQaver is a PHP like WebServer for Python.

Dev Bash 7 Apr 25, 2022
Robyn is an async Python backend server with a runtime written in Rust, btw.

Robyn is an async Python backend server with a runtime written in Rust, btw. Python server running on top of of Rust Async RunTime. Installation

Sanskar Jethi 1.4k Jun 8, 2022