Repository: python-poetry/poetry

Issue:
Export command produces requirements.txt with git dev dependency
<!--
  Hi there! Thank you for discovering and submitting an issue.

  Before you submit this; let's make sure of a few things.
  Please make sure the following boxes are ticked if they are correct.
  If not, please try and fulfill these first.
-->

<!-- Checked checkbox should look like this: [x] -->
- [x] I am on the [latest](https://github.com/sdispater/poetry/releases/latest) Poetry version.
- [x] I have searched the [issues](https://github.com/sdispater/poetry/issues) of this repo and believe that this is not a duplicate.
- [x] If an exception occurs when executing a command, I executed it again in debug mode (`-vvv` option).

<!--
  Once those are done, if you're able to fill in the following list with your information,
  it'd be very helpful to whoever handles the issue.
-->

- **OS version and name**: Ubuntu 18.04
- **Poetry version**: 1.0.0a2
- **Link of a [Gist](https://gist.github.com/) with the contents of your pyproject.toml file**: <!-- Gist Link Here -->
```toml
[tool.poetry]
name = "poetry_bug"
version = "0.1.0"
description = ""
authors = ["Steven Pate <steven@laac.dev>"]

[tool.poetry.dependencies]
python = "^3.6"
django = "^2.1"

[tool.poetry.dev-dependencies]
pytest = "^4.2"
webassets = {git = "https://github.com/miracle2k/webassets.git"}

[build-system]
requires = ["poetry>=0.12"]
build-backend = "poetry.masonry.api"
```

## Issue
<!-- Now feel free to write your issue, but please be descriptive! Thanks again 🙌 ❤️ -->

First off, poetry is awesome. Thank you for a great step forward in Python dependency management.

Using the above pyproject.toml, I run `poetry export -f requirements.txt`, and it produces this `requirements.txt`

```
django==2.1.5 \
    --hash=sha256:a32c22af23634e1d11425574dce756098e015a165be02e4690179889b207c7a8 \
    --hash=sha256:d6393918da830530a9516bbbcbf7f1214c3d733738779f06b0f649f49cc698c3
pytz==2018.9 \
    --hash=sha256:32b0891edff07e28efe91284ed9c31e123d84bea3fd98e1f72be2508f43ef8d9 \
    --hash=sha256:d5f05e487007e29e03409f9398d074e158d920d36eb82eaf66fb1136b0c5374c
-e git+https://github.com/miracle2k/webassets.git@d1f3455e383446ca4ab0c644f326ee937e68e809#egg=webassets
```

`webassets` is included in the requirements.txt without adding the `--dev` to the `export` command.


Discussion:
Also:
```
$ poetry export --no-dev --without-hashes -f requirements.txt

[NoSuchOptionException]
The "--no-dev" option does not exist.
```

We would like to use the export function for production builds, using Serverless Framework.

Any such feature on the horizon?
TODO has been added for fixing this.

https://github.com/sdispater/poetry/issues/313
> Also:
> 
> ```
> $ poetry export --no-dev --without-hashes -f requirements.txt
> 
> [NoSuchOptionException]
> The "--no-dev" option does not exist.
> ```
> 
> We would like to use the export function for production builds, using Serverless Framework.
> 
> Any such feature on the horizon?

The argument should be `--dev` to include development dependencies. Development dependencies are excluded from the `export` by default.

Using `1.0.0a3`, I run `poetry export --help`, and it shows `--dev`
Just ran into this using `1.0.0b1` - still active. Needs to be solved.
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

[An activity against robot auto-closing (which won't solve the issue at all)]
I'd like to add extra debugging info to this issue. Using `poetry-1.0.0b9-linux` calling `poetry export -f requirements.txt --without-hashes` with the following `pyproject.toml` results in optional dependencies such as `pytest` being included even though no `--extras` flag was used.

----------------------------

## `pyproject.toml`

```toml
[tool.poetry]
name = "pymedphys"
version = "0.13.2"
readme = "README.rst"
description = "Medical Physics library"
authors = [
    "PyMedPhys Contributors <developers@pymedphys.com>",
    "Simon Biggs <sbiggs@pymedphys.com>",
    "Matthew Jennings <mjennings@pymedphys.com>>",
    "Phillip Chlap",
    "Paul King <pking@pymedphys.com>",
    "Matthew Sobolewski <msobolewski@pymedphys.com>",
    "Jacob McAloney",
    "Pedro Martinez"
]
license = "AGPL-3.0-or-later"
homepage = "https://pymedphys.com"
repository = "https://github.com/pymedphys/pymedphys"
documentation = "https://pymedphys.com"
classifiers = [
    "Development Status :: 4 - Beta",
    "Topic :: Scientific/Engineering :: Medical Science Apps.",
    "Topic :: Scientific/Engineering :: Physics",
    "Intended Audience :: Science/Research",
    "Intended Audience :: Healthcare Industry",
]

[tool.poetry.dependencies]
python = "^3.7"

attrs = "*"
keyring = "*"
packaging = "*"
PyYAML = "*"

numpy = "^1.12"
matplotlib = "*"
scipy = "*"
pandas = "*"

dbfread = "*"

pydicom = "*"
pynetdicom = "*"

pymssql = "< 3.0.0"
shapely = { version = "*", optional = true }

# labs
tqdm = "*"
python_dateutil = "*"
Pillow = "*"
imageio = "*"
scikit-image = "*"

# docs
sphinx = { version = ">= 1.4, < 1.8", optional = true }
sphinx-rtd-theme  = { version = "^0.4.3", optional = true }
sphinx-autobuild = { version = "*", optional = true }
sphinxcontrib-napoleon = { version = "*", optional = true }
sphinx-argparse  = { version = "*", optional = true }
nbsphinx  = { version = "*", optional = true }
jupyter_client = { version = "*", optional = true }
ipython = { version = "*", optional = true }
ipykernel = { version = "*", optional = true }
m2r = { version = "*", optional = true }

# pytest
pytest = { version = "*", optional = true }
pytest-sugar  = { version = "*", optional = true }
hypothesis  = { version = "*", optional = true }

# pylint
pylint  = { version = "*", optional = true }
pytest-pylint  = { version = "*", optional = true }


[tool.poetry.dev-dependencies]
# Testing
tox = "*"
pytest = "*"
pytest-sugar = "*"
pylint = "*"
pytest-pylint = "*"
hypothesis = "*"

# Git Management
pre-commit = "*"

# VSCode linting and formatting
black = "^19.3b0"
mypy = "*"
rope = "*"

# Building documentation
sphinx = ">= 1.4, < 1.8"
sphinx-rtd-theme = "*"
sphinx-autobuild = "*"
sphinxcontrib-napoleon = "*"
sphinx-argparse = "*"
nbsphinx = "*"
jupyter_client = "*"
ipython = "*"
ipykernel = "*"
m2r = "*"

# Supporting JupyterLab usage
pywin32 = { version = "224", platform = "win32" }

# VSCode extension dependencies
doc8 = "*"

# gui
cefpython3 = "66.0"
jupyterlab_server = "*"

# Packages to include later
# pytest-cov = "^2.5"
# pytest-mock = "^1.9"

[tool.poetry.extras]
docs = [
    "sphinx", "sphinx-rtd-theme",
    "sphinx-autobuild", "sphinxcontrib-napoleon", "sphinx-argparse",
    "nbsphinx", "jupyter_client", "ipython", "ipykernel",
    "m2r"
]

extras = [
    "shapely"
]

pytest = [
    "pytest", "pytest-sugar", "hypothesis"
]

pylint = [
    "pylint", "pytest-pylint"
]

[tool.poetry.scripts]
pymedphys = "pymedphys.cli.main:pymedphys_cli"

[tool.isort]
multi_line_output = 3
line_length = 88
include_trailing_comma = true
known_third_party = [
    "attr", "tqdm", "pytest", "hypothesis", "cefpython3", "notebook",
    "jupyterlab", "traitlets", "jupyterlab_server", "packaging", "dateutil"
]
known_scicore = [
    "numpy", "scipy", "pandas"
]
known_matplotlib = [
    "matplotlib", "mpl_toolkits"
]
known_sci_other = [
    "imageio", "PIL", "skimage"
]
known_medphys = [
    "pydicom", "pylinac"
]
known_first_party = ["pymedphys"]
sections = [
    "FUTURE", "STDLIB", "THIRDPARTY", "SCICORE", "MATPLOTLIB", "SCI_OTHER",
    "MEDPHYS", "FIRSTPARTY", "LOCALFOLDER"
]

[build-system]
requires = ["poetry >= 0.12", "setuptools >= 35.0.2", "wheel >= 0.29.0"]
build-backend = "poetry.masonry.api"
```

-----------------------

## `poetry export -f requirements.txt --without-hashes`

```requirements.txt
alabaster==0.7.12
appnope==0.1.0; sys_platform == "darwin" or platform_system == "Darwin"
argh==0.26.2
astroid==2.3.3
atomicwrites==1.3.0; sys_platform == "win32"
attrs==19.3.0
babel==2.7.0
backcall==0.1.0
bleach==3.1.0
certifi==2019.11.28
cffi==1.13.2; sys_platform == "linux"
chardet==3.0.4
colorama==0.4.1; sys_platform == "win32"
cryptography==2.8; sys_platform == "linux"
cycler==0.10.0
dbfread==2.0.7
decorator==4.4.1
defusedxml==0.6.0
docutils==0.15.2
entrypoints==0.3
hypothesis==4.50.6
idna==2.8
imageio==2.6.1
imagesize==1.1.0
importlib-metadata==0.23; python_version < "3.8"
ipykernel==5.1.3
ipython==7.10.1
ipython-genutils==0.2.0
isort==4.3.21
jedi==0.15.1
jeepney==0.4.1; sys_platform == "linux"
jinja2==2.10.3
jsonschema==3.2.0
jupyter-client==5.3.4
jupyter-core==4.6.1
keyring==19.3.0
kiwisolver==1.1.0
lazy-object-proxy==1.4.3
livereload==2.6.1
m2r==0.2.1
markupsafe==1.1.1
matplotlib==3.1.2
mccabe==0.6.1
mistune==0.8.4
more-itertools==8.0.0
nbconvert==5.6.1
nbformat==4.4.0
nbsphinx==0.4.3
networkx==2.4
numpy==1.17.4
packaging==19.2
pandas==0.25.3
pandocfilters==1.4.2
parso==0.5.1
pathtools==0.1.2
pexpect==4.7.0; sys_platform != "win32"
pickleshare==0.7.5
pillow==6.2.1
pluggy==0.13.1
pockets==0.9.1
port-for==0.3.1
prompt-toolkit==3.0.2
ptyprocess==0.6.0; sys_platform != "win32" or os_name != "nt"
py==1.8.0
pycparser==2.19; sys_platform == "linux"
pydicom==1.3.0
pygments==2.5.2
pylint==2.4.4
pymssql==2.1.4
pynetdicom==1.4.1
pyparsing==2.4.5
pyrsistent==0.15.6
pytest==5.3.1
pytest-pylint==0.14.1
pytest-sugar==0.9.2
python-dateutil==2.8.1
pytz==2019.3
pywavelets==1.1.1
pywin32==224; sys_platform == "win32"
pywin32-ctypes==0.2.0; sys_platform == "win32"
pyyaml==5.1.2
pyzmq==18.1.1
requests==2.22.0
scikit-image==0.16.2
scipy==1.3.3
secretstorage==3.1.1; sys_platform == "linux"
six==1.13.0
snowballstemmer==2.0.0
sphinx==1.7.9
sphinx-argparse==0.2.5
sphinx-autobuild==0.7.1
sphinx-rtd-theme==0.4.3
sphinxcontrib-napoleon==0.7
sphinxcontrib-websupport==1.1.2
termcolor==1.1.0
testpath==0.4.4
tornado==6.0.3
tqdm==4.40.0
traitlets==4.3.3
typed-ast==1.4.0
urllib3==1.25.7
watchdog==0.9.0
wcwidth==0.1.7
webencodings==0.5.1
wrapt==1.11.2
zipp==0.6.0; python_version < "3.8"
```

------------------------------
The problem seems to be that the Git dependency belongs to category `main` in `poetry.lock` although it is listed under `[tool.poetry.dev-dependencies]` in `pyproject.toml`. It looks like the locker has a bug.
In fact, it's not the locker, but when the `VCSDependency` instance of a Git package is created, `category` is not passed as an argument to the class constructor. In `VCSDependency`'s parent class constructor `Dependency.__init__`, `category` has a default value `"main"`. That's why any VCS dependency has category `"main"`.

I'd be happy to create a PR to fix this issue.

Resolving patch:
diff --git a/poetry/packages/package.py b/poetry/packages/package.py
--- a/poetry/packages/package.py
+++ b/poetry/packages/package.py
@@ -297,6 +297,7 @@ def add_dependency(
                     branch=constraint.get("branch", None),
                     tag=constraint.get("tag", None),
                     rev=constraint.get("rev", None),
+                    category=category,
                     optional=optional,
                 )
             elif "file" in constraint:
diff --git a/poetry/packages/vcs_dependency.py b/poetry/packages/vcs_dependency.py
--- a/poetry/packages/vcs_dependency.py
+++ b/poetry/packages/vcs_dependency.py
@@ -7,7 +7,15 @@ class VCSDependency(Dependency):
     """
 
     def __init__(
-        self, name, vcs, source, branch=None, tag=None, rev=None, optional=False
+        self,
+        name,
+        vcs,
+        source,
+        branch=None,
+        tag=None,
+        rev=None,
+        category="main",
+        optional=False,
     ):
         self._vcs = vcs
         self._source = source
@@ -21,7 +29,7 @@ def __init__(
         self._rev = rev
 
         super(VCSDependency, self).__init__(
-            name, "*", optional=optional, allows_prereleases=True
+            name, "*", category=category, optional=optional, allows_prereleases=True
         )
 
     @property


Test patch:
diff --git a/tests/packages/test_package.py b/tests/packages/test_package.py
--- a/tests/packages/test_package.py
+++ b/tests/packages/test_package.py
@@ -1,6 +1,8 @@
 # -*- coding: utf-8 -*-
 from __future__ import unicode_literals
 
+import pytest
+
 from poetry.packages import Package
 
 
@@ -14,3 +16,24 @@ def test_package_authors():
     package.authors.insert(0, "John Doe")
     assert package.author_name == "John Doe"
     assert package.author_email is None
+
+
+@pytest.mark.parametrize("category", ["main", "dev"])
+def test_package_add_dependency_vcs_category(category):
+    package = Package("foo", "0.1.0")
+
+    dependency = package.add_dependency(
+        "poetry",
+        constraint={"git": "https://github.com/python-poetry/poetry.git"},
+        category=category,
+    )
+    assert dependency.category == category
+
+
+def test_package_add_dependency_vcs_category_default_main():
+    package = Package("foo", "0.1.0")
+
+    dependency = package.add_dependency(
+        "poetry", constraint={"git": "https://github.com/python-poetry/poetry.git"}
+    )
+    assert dependency.category == "main"
diff --git a/tests/packages/test_vcs_dependency.py b/tests/packages/test_vcs_dependency.py
--- a/tests/packages/test_vcs_dependency.py
+++ b/tests/packages/test_vcs_dependency.py
@@ -1,3 +1,5 @@
+import pytest
+
 from poetry.packages.vcs_dependency import VCSDependency
 
 
@@ -49,3 +51,14 @@ def test_to_pep_508_in_extras():
     expected = 'poetry @ git+https://github.com/python-poetry/poetry.git@b;ar; ; extra == "foo;"'
 
     assert expected == dependency.to_pep_508()
+
+
+@pytest.mark.parametrize("category", ["main", "dev"])
+def test_category(category):
+    dependency = VCSDependency(
+        "poetry",
+        "git",
+        "https://github.com/python-poetry/poetry.git",
+        category=category,
+    )
+    assert category == dependency.category