[Feature request] Support react-native

What version of bluebird is the issue happening on?
3.3.1 (latest)
What platform and version? (For example Node.js 0.12 or Google Chrome 32)
React Native 0.20 (using react-native packager), node 5.4.1, npm 3.3.12
Did this issue happen with earlier version of bluebird?
Probably, yes

When bluebird is required inside of a react-native project, it crashes because it assumes when it is not running on node.js that it is running in a browser.
In react-native the document is not present and it throws an error.

@vespakoen can you please share the error and stack trace?
I think it's a platform we generally want to support.

Ah, I had "Pause On Caught Exceptions" enabled, it seems to catch / handle it fine when I play through the error.
My mistake (btw, it did seem to be an actual problem in the past: https://github.com/petkaantonov/bluebird/issues/550)


python311Packages.xsdata: 23.8 -> 24.1

Description of changes
Changelog: https://github.com/tefra/xsdata/blob/v24.1/CHANGES.rst

Things done

Built on platform(s)

[x] x86_64-linux
[ ] aarch64-linux
[ ] x86_64-darwin
[ ] aarch64-darwin

For non-Linux: Is sandboxing enabled in nix.conf? (See Nix manual)

[ ] sandbox = relaxed
[ ] sandbox = true

[ ] Tested, as applicable:

NixOS test(s) (look inside nixos/tests)
and/or package tests
or, for functions and "core" functionality, tests in lib/tests or pkgs/test
made sure NixOS tests are linked to the relevant packages

[ ] Tested compilation of all packages that depend on this change using nix-shell -p nixpkgs-review --run "nixpkgs-review rev HEAD". Note: all changes have to be committed, also see nixpkgs-review usage
[ ] Tested basic functionality of all binary files (usually in ./result/bin/)
24.05 Release Notes (or backporting 23.05 and 23.11 Release notes)

[ ] (Package updates) Added a release notes entry if the change is major or breaking
[ ] (Module updates) Added a release notes entry if the change is significant
[ ] (Module addition) Added a release notes entry if adding a new NixOS module

[x] Fits CONTRIBUTING.md.

Add a :+1: reaction to pull requests you find important.

I don't really get why ruff is needed now and my mailserver now depends on a python linter/formatter (I've seen the code, I mean the reasoning), but 17M in a ~200M closure of Python code doesn't matter much, so that's not a hill I'd like to die on.

@Ma27 Your comment pointed me to a problem with this change:
https://github.com/tefra/xsdata/pull/892/files#diff-50c86b7ed8ac2cf95bd48334961bf0530cdc77b5a56f852c5c61b89d735fd711R51
Technically ruff is only an optional dependency installed with xsdata[cli]  Thus I should have added it to passthru.optional-dependencies.cli. It is however called using subprocess.run() rather than imported.
Ruff also does not have a public API: https://github.com/astral-sh/ruff/issues/659
So now the xsdata package is broken (because of a missing dependency) in case anyone uses its optional cli dependencies and the closure size is increased for no reason.

It is however called using subprocess.run() rather than imported.

So, I'm not sure if I'm missing something (I really need to sleep now), but isn't the subprocess call the reference that got patched in this PR?

It is however called using subprocess.run() rather than imported.

So, I'm not sure if I'm missing something (I really need to sleep now), but isn't the subprocess call the reference that got patched in this PR?

It's also listed in pyproject.toml.

It's also listed in pyproject.toml.

Ohh I see what you mean.
I guess removing ruff from there should be sufficient?


Initials commands

Initials commands
Add basic initial commands and start application.

[x]  Deploy App
[x]  Ping Command
[x]  Avatar Command

Done with the rework proyect.


run and detach

hi guys, what's the equivalent of this command?
docker run -itd ubuntu /bin/bash

basically i just want to create a container and leave it running, im not sure if its just on my end but every time i create a container it simply stop.

docker run =~ create, start, attach
docker run -d =~ create, start
(Typing on a tablet, hopefully that is clear enough)

cool thanks


Reference on docs.Microsoft.com doesn't allow for comments or contributions

The VSTS-CLI Reference on Docs.Microsoft.com doesn't allow either comments or contributions. The documentation needs to be just as Open Source as the code.

The reference section is all auto-generated from the code.  When you update the source it updates the docs.   The section above is manually written, and for those there is a comment section below the page.  I will see if I can find out why the doc tools don;t allow comments on the auto generated files.

There are links at the bottom of each resource page, which allows you to provide comments, questions, and feedback.
For example this resource page has links at the bottom of the page:
https://docs.microsoft.com/en-us/rest/api/vsts/git/pull requests?view=vsts-rest-5.0
For the documentation feedback you will get redirected to the specs repo, which includes the swagger.  As a side note this swagger is generated from the code, and the documentation is generated from this swagger.  Issues here are actively monitored.
https://github.com/MicrosoftDocs/vsts-rest-api-specs/issues

Please reopen the issue.  Here is an example of a reference page which does NOT contain the feedback links that you mention as the reason for closing this issue.
https://docs.microsoft.com/en-us/cli/vsts/build?view=vsts-cli-latest#vsts_build_queue
The same problem appears for every page in the reference for the VSTS CLI.

Sorry, this should have laready been done.  We are following up on it.


update contrib guide

Looks great. One minor comment. The intro says "It's also a system you could take as a whole or in parts and deploy locally, on-prem on in the cloud, especially when leveraging Kubernetes.". Maybe we should remove the Kubernetes mention?


Add mathjax support for markdown preview

Added Mathjax to html previews for markdown.  This can be tested by running markdown-preview on some markdown file.
Before:

After:

Thanks!


Gson 2.4 now supports @SerializedName on methods, description should be updated

Since recent release gson-2.4, it supports @SerializedName on methods (see CHANGELOG).
So I guess this part of README.md should be updated somehow:
Note: Since Gson's built in SerializedName annotation can't be used on methods, you'll have to change your SerializedName import to com.ryanharter.auto.value.gson.SerializedName.

I am not sure how exactly you want to handle this - either by dropping your version of @SerializedName and removing respective note from README or by leaving this custom annotation for those who use earlier Gson version and just mentioning that since gson-2.4 it is not needed.

I chose to simply remove the references, since the code change removing the custom attribute was already in place, and simply bumped the version so that people can still use the old version if they choose.


fix num_kv_heads sharding in uneven autoTP for Falcon-40b

Falcon-40b will fail on uneven autotp. Need to add 'num_kv_heads' in the kv_head_names list.

@tjruwase from the failure log it seems like a environment issue.  Has this already been resolved?
Thanks!
FAILED tests/deepspeed/test_deepspeed.py::TrainerIntegrationDeepSpeed::test_early_get_last_lr_zero2_fp16 - deepspeed.ops.op_builder.builder.CUDAMismatchException: >- DeepSpeed Op Builder: Installed CUDA version 11.6 does not match the version torch was compiled with 12.1, unable to compile cuda/cpp extensions without a matching cuda version.

@delock, apologies for the delay on this. The team is gradually returning from the holidays. This will be resolved asap.


Clarification PR: Tech Checks in Dev Testing

I'm willing to bet this is the case so am making a PR rather than an issue...if I'm wrong please reject to lmk :)

That assumption is not the case; Chrome clients do verify some of the invariants that are also enforced by the workflows in this repository. But in general, we'd prefer to avoid making promises here about what Chrome does or does not validate, since those details may change in the future. As such, we'll reject this PR.


Improve service status

The status was only checked for the LoadBalancer type and it was also wrongly expected that service.Spec.ClusterIP must be empty.
Fixes #209. Seems that me and @rstefan1 worked on the same issue at the same time.

Hi @kow3ns and @pwittrock. When might you have a look at this PR?

/remove-lifecycle stale


fixes to comply with leaflet 1.0+: clickable->interactive

Looks good, sorry about the slow response!


ResultSet implementation

This PR adds the ResultSet implementation.
Notes:

Classes SQLDroidDatabaseMetaData.java, SQLDroidPreparedStatement.java, SQLDroidStatement.java modified to make it compiles
Added AbstractCursor.java and MatrixCursor.java from android source code for the tests

Please @juanpedromoreno could you review? Thanks!

@juanpedromoreno could you review again? Thanks

LGTM! Excellent job!


Change how the Emergency Banner is deployed

Trello cards:

https://trello.com/c/2D0KFQZP
https://trello.com/c/EPTEOgHJ
https://trello.com/c/EPTEOgHJ
https://trello.com/c/3eq0AeHA

Related PRs:

https://github.com/alphagov/govuk-puppet/pull/5734
https://github.com/alphagov/govuk-puppet/pull/5760
https://github.com/alphagov/frontend/pull/1208

Context
The emergency banner implementation has been re-written so that instead of using a fabric script to add content to some partials in Frontend and Static, we will instead populate a hash in Redis with the values needed for the emergency banner.
This will mean that should we need to deploy an emergency banner, Static and Frontend deploys are no longer blocked.
We have chosen to store the values in Redis rather than another datastore because all applications can access the same Redis environment, so Frontend and Static don't need to keep separate stores for the Emergency Banner values, they can share the same ones.
The Implementation

Add the Redis gem to both Frontend and Static
Static retrieves a emergency_banner hash from Redis and uses it to determine whether to display the emergency banner
Create two emergency banner partial templates, one for the homepage and the other for all other pages. Populate them with the contents of the emergency_banner hash from Redis.
Create two tasks, one to set values in the emergency_banner hash in Redis and the other to delete the hash

Future work
Future work will remove the current implementation of the emergency banner code which relies on empty partials that are populated by a fabric task.

Can i ask what alternative approaches to this where thought of for this?

We looked at using ESI in Fastly but it doesn't support including from outside our infrastructure, which would have been the main benefit. There will be a writeup after the blitz of the other options we discussed.


setBountySplit separation

Current, setBountySplit is set by governance.
We want to te able to have that set by the creator of the vault when he calls createVault, and by the owner of the vault. However, we want hats governance to control the swapAndBurn and governanceHAT values
What we can do:

Remove the swapAndBurn setting (no tokens will be automatically burnt anymore)
a new mathod hatvaultregistry.setBountyFees(governanceHAT) sets the percentage values for governanceHat
setBountySplit and createVault can only set the distribution of the remaining values (hackerVested, hacker, committee)

Open questions:

what do we do with the hackerHatVested value? Is that controlled by governance or vault owner?
setBountySplit is calleable by vault.owner or committee?

i think committee should not control the bounty split, since it can be people working for the project. are we assuming that vault creator is the project leadership?

guess just change them accordingly? (i mean change all other parts to have the same percentages of what's left)

we can have governance decide on the part of the bounty that get swapped to HATs (and how much of it goes to gov and how much to the hacker) and have the committee/project leadership decide on the devision of the rest between hacker, hacker vested and committee (so they give relative percentage out of what is left that is not swapped).
e.g gov decides on 10% swapped - 5% to hacker and 5% to gov, and committee/lead decide on division of 50% to hacker, 30% to hacker vested and 20% to committee (out of the non-swapped share) - so it means that 45% go to hacker, 27% go to hacker vested and 18% go to committee

we can have governance decide on the part of the bounty that get swapped to HATs (and how much of it goes to gov and how much to the hacker) and have the committee/project leadership decide on the devision of the rest between hacker, hacker vested and committee (so they give relative percentage out of what is left that is not swapped). this way both sides can change their values independently.
e.g gov decides on 10% swapped - 5% to hacker and 5% to gov, and committee/lead decide on division of 50% to hacker, 30% to hacker vested and 20% to committee (out of the non-swapped share) - so it means that 45% go to hacker, 27% go to hacker vested and 18% go to committee.

Sounds fine to me. Should we have any limits on the value that can be controlled by the hats governance or just whatever is set?

i think should have a limit and also the committee portion should be limited

We can only limit one side because the other side would take whatever is left for it.

what do you mean? i mean to limit only the governance part of the HATs side and only the committee part of the native token side (the hacker parts not limited)

we have no limits  in v1, why do we need more limits now? We have time limits on the settability of this thing, if the users don't like the limits they can react.


Request-URI Too Long

I'm trying to download all the pollen data, but run into the following error
pollen_datasets <-  neotoma2::get_datasets(datasettype = "pollen",   all_data = TRUE)

neotoma2::get_downloads(pollen_datasets)
Error in parseURL(base_url, ...) :
  Request-URI Too Long (HTTP 414). Failed to Could not connect to the Neotoma API.
                    Check that the path is valid, and check the current
                     status of the Neotoma API services at
                      http://data.neotomadb.org.

Fairly sure this is because get.downloads.numeric pastes all the datasetid into a very long string that is too long for a GET request

Hello, can you do install.packages('neotoma2')
This issue should have been solved :)


Please add description for using Custom Policy

Please add description for using Custom Policy definition instead of portal.

Document Details
⚠ Do not edit this section. It is required for docs.microsoft.com ➟ GitHub issue linking.

ID: 15942a1a-df5c-bbeb-a693-510aadede4b2
Version Independent ID: dd96db95-d230-9690-ab08-dfc6ceaff7f2
Content: Set up sign-up and sign-in with OpenID Connect - Azure AD B2C
Content Source: articles/active-directory-b2c/identity-provider-generic-openid-connect.md
Service: active-directory
Sub-service: b2c
GitHub Login: @msmimart
Microsoft Alias: mimart

@MarekLani
Thanks for your feedback! I've assigned this issue to the author who will investigate and update as appropriate.

Thanks for your feedback, we are working on the custom policy part of the document. A new version will be published soon.

The new version is ready, updates will be published next week.


operator error

With added volumeMounts, the operator throws the following error:
 err: Operation cannot be fulfilled on clickhousekeeperinstallations.clickhouse-keeper.altinity.com "clickhouse-keeper": the object has been modified; please apply your changes to the latest version and try again

deploy
apiVersion: "clickhouse-keeper.altinity.com/v1"
kind: "ClickHouseKeeperInstallation"
metadata:
  name: clickhouse-keeper
spec:
  configuration:
    clusters:
      - name: {{ .Values.clickhouse.clusters.name}}
        layout:
          replicasCount: 3
    settings:
      logger/level: "trace"
      logger/console: "true"
      listen_host: "<IP_ADDRESS>"
      keeper_server/storage_path: /var/lib/clickhouse-keeper
      keeper_server/tcp_port: "2181"
      keeper_server/four_letter_word_white_list: "*"
      keeper_server/coordination_settings/raft_logs_level: "information"
      keeper_server/raft_configuration/server/port: "9444"
      prometheus/endpoint: "/metrics"
      prometheus/port: "7000"
      prometheus/metrics: "true"
      prometheus/events: "true"
      prometheus/asynchronous_metrics: "true"
      prometheus/status_info: "false"
  templates:
    podTemplates:
      - name: clickhouse-keeper
        spec:
          # affinity removed to allow use in single node test environment
          affinity:
            podAntiAffinity:
              requiredDuringSchedulingIgnoredDuringExecution:
                - labelSelector:
                    matchExpressions:
                      - key: "app"
                        operator: In
                        values:
                          - clickhouse-keeper
                  topologyKey: "kubernetes.io/hostname"
          containers:
            - name: clickhouse-keeper
              imagePullPolicy: IfNotPresent
              image: "altinity/clickhouse-keeper:<IP_ADDRESS>.altinitystable"
              resources:
                requests:
                  memory: "256M"
                  cpu: "1"
                limits:
                  memory: "4Gi"
                  cpu: "2"
              volumeMounts:
                - mountPath: /var/lib/clickhouse-keeper
                  name: working-dir
    volumeClaimTemplates:
      - name: working-dir
        spec:
          storageClassName: {{ .Values.global.acos.storageClass }}
          accessModes:
            - ReadWriteOnce
          resources:
            requests:
              storage: 10G

If volumeMounts are not added, there will be errors related to PVC. I just want to add a PVC mounted to /var/lib/clickhouse-keeper
 failed to get pvc by name acos/both-paths: persistentvolumeclaim "both-paths" not found

deploy
apiVersion: "clickhouse-keeper.altinity.com/v1"
kind: "ClickHouseKeeperInstallation"
metadata:
  name: clickhouse-keeper
spec:
  configuration:
    clusters:
      - name: {{ .Values.clickhouse.clusters.name}}
        layout:
          replicasCount: 3
    settings:
      logger/level: "trace"
      logger/console: "true"
      listen_host: "<IP_ADDRESS>"
      keeper_server/storage_path: /var/lib/clickhouse-keeper
      keeper_server/tcp_port: "2181"
      keeper_server/four_letter_word_white_list: "*"
      keeper_server/coordination_settings/raft_logs_level: "information"
      keeper_server/raft_configuration/server/port: "9444"
      prometheus/endpoint: "/metrics"
      prometheus/port: "7000"
      prometheus/metrics: "true"
      prometheus/events: "true"
      prometheus/asynchronous_metrics: "true"
      prometheus/status_info: "false"
  templates:
    podTemplates:
      - name: clickhouse-keeper
        spec:
          # affinity removed to allow use in single node test environment
          affinity:
            podAntiAffinity:
              requiredDuringSchedulingIgnoredDuringExecution:
                - labelSelector:
                    matchExpressions:
                      - key: "app"
                        operator: In
                        values:
                          - clickhouse-keeper
                  topologyKey: "kubernetes.io/hostname"
          securityContext:
            fsGroup: 101
            runAsUser: 101
          containers:
            - name: clickhouse-keeper
              imagePullPolicy: IfNotPresent
              image: "altinity/clickhouse-keeper:<IP_ADDRESS>.altinitystable"
              resources:
                requests:
                  memory: "256M"
                  cpu: "1"
                limits:
                  memory: "4Gi"
                  cpu: "2"

    volumeClaimTemplates:
      - name: working-dir
        spec:
          storageClassName: {{ .Values.global.acos.storageClass }}
          accessModes:
            - ReadWriteOnce
          resources:
            requests:
              storage: 10G

Duplicate https://github.com/Altinity/clickhouse-operator/issues/1362

I have found the same operator error after POD annotations are dropped (by the operator itself):

https://github.com/Altinity/clickhouse-operator/issues/1469


Add PEP484 stubs

Here's a first take at PEP484-compatible pyi stubs.  The discussion in #215 has been mostly focused on runtime type checking, so I wanted to make sure that the plan discussed there will work with static analysis as well.
Here's a quick test of the stubs that I put together to run against mypy:
from typing import cast
import attr

@attr.s
class C(object):
    x : int = attr.ib(convert=int)
    y: str = attr.ib()

c = C('1', 'foo')  # E: Too many arguments for "C"
c.x = 2
c.y = 'bar'
c > C()  # E: Unsupported left operand type for > ("C")
str(c)

# errors below are correctly detected:
c.x = 'foo'  # E: Incompatible types in assignment (expression has type "str", variable has type "int")
c.y = 1  # E: Incompatible types in assignment (expression has type "int", variable has type "str")

D = attr.make_class('D', {'x': cast(attr._CountingAttr, attr.ib())})
d = D(2)
# errors below are not correctly detected (mypy knows nothing about D other than that it's a type)
d.x ='foo'

mypy knows nothing about the dunder methods added by attrs, so cmp methods and __init__ fail.  This will have to be solved with a mypy plugin, which I'll look into next. Same goes for attr.make_class though that's likely to be more difficult.
One important thing to note: in order to ensure that y: str = attr.ib() does not trigger a mypy error, the return type of attr.ib is Any instead of _CountingAttr.   A side effect of this is that it complicates passing the result of attr.ib to functions that expect _CountingAttr instances.  There are a handful of strategies to solve this:

use typing.cast:  ugly and verbose
create, or choose an existing, alias for attr.ib that will return _CountingAttr, to use with functions like make_class.
add another argument (make=True?) whose presence invokes an @overload of attr.ib that returns _CountingAttr
slight variation on 2.  create a public alias for _CountingAttr and copy the keyword defaults from attr.ib to _CountingAttr.__init__.  In other words, if you use static type checking and are working with a function that expects _CountingAttr instances, use _CountingAttr()  directly instead of attr.ib()

I favor the 3rd solution.  After some consideration I favor 4.
If you're interested in accepting this, the next things to figure out are:

how to make tests for this, and run them on travis
how best to install the stubs (should they be moved to python-typeshed?)

Let me know what you think.
edit added option 4.

So, we need a mypy-Plugin in any case (please coordinate with @Tinche if you want to help, so we don't end up with duplicate work here!), [c|sh]ouldn't that plugin also handle the y: str = attr.ib() problem or am I missing something here?

I'm not really sure how to handle the stubs; does mypy scan the PYTHONPATH for them? I seem to remember it doesn't. Putting them into typeshed is not a good solution imho, what about versioning? Maybe someone should go ask them what to do exactly.
But stubs aren't really the big issue here. We basically need a mypy plugin that would run between the 2nd pass semantic analysis and the typecheck pass that would inject attrs generated stuff into attrs classes, and I think mypy doesn't have this type of plugin yet.

So, we need a mypy-Plugin in any case (please coordinate with @Tinche if you want to help, so we don't end up with duplicate work here!), [c|sh]ouldn't that plugin also handle the y: str = attr.ib() problem or am I missing something here?

I think that the plugin should focus on exposing the dunder methods to mypy, and not concern itself with the return value of attr.ib.  What I'm proposing here for attr.ib is not only sufficient as-is but may be preferable to trying to solve via a mypy plugin.  Here's why:
The core problem here from a static type-checking POV is that in our example we want C.x to be a _CountingAttr and C(1).x to be an int.  This is anathema to static type checking, which wants a variable to always have one type.   For example, this is an error in mypy:
x = 1
x = 'str'  # error

The typing.ClassVar construct adds greater restriction: it says that a class attribute cannot be modified from an instance:
class C:
    x : ClassVar[int] = 1

C.x = 2  # ok
C().x = 2 # error

So that's not what we want either.
Could we create a mypy plugin that allows this dual-type behavior between classes and instances?  Maybe, I don't know the API well enough to say for sure, but my instincts tell me that it will be far more difficult than adding the attr.s dunder support, precisely because it bucks against how static type checking works in general.   As @Tinche pointed out, the current mypy plugin system does not expose everything needed to solve our issues for attrs:  attempting to solve the attr.ib problem might require exposing a lot more to the plugin system, and if this requires some kind of specific support for dual-typing, the mypy folks might not approve it.
I believe that the desire to make attr.ib "just work" with existing code in all cases is a perspective that users of static type checking won't share.  I've been working towards having complete static type checking for a medium sized code base and it requires changing the way that you code in many cases.   Given my exposure to the static way of thinking, changing code to make clear when an object is a _CountingAttr is a perfectly natural and sufficient solution.
Here's an example showing those two use cases :
from typing import cast
import attr

@attr.s
class C(object):
    x : int = attr.ib(convert=int)
    y: str = attr.ib()

D = attr.make_class('D', {'x': attr.CountingAttr()})

A user who is experienced with static type checking will actually find it unintuitive if the attribute types are allowed to change.  Yes, we're lying to the static type checker, and certain operations are off limits if you want the analysis to succeed (e.g. C.x.type without also using cast) but I've seen quite a bit of both in the official stdlib stubs.
All these things considered, I think we should focus on writing a mypy plugin that exposes the dunder methods added by @attr.s.

I'm not really sure how to handle the stubs; does mypy scan the PYTHONPATH for them? I seem to remember it doesn't.

Mypy has its own search path defined by MYPYPATH, whereas  PyCharm searches the PYTHONPATH.  Both tools will prefer .pyi over .py.

Putting them into typeshed is not a good solution imho, what about versioning? Maybe someone should go ask them what to do exactly.

I agree about the disadvantages of typeshed.  There is an epic typing issue  discussing installation of third-party stubs, and it's still not resolved.
Maybe the simplest solution is just to move the annotations into the code itself?  This also has a major advantage in PyCharm: when working with modules that provide stubs, the "go to definition" behavior will take you to the definition within the .pyi file, which doesn't contain docs or any code.

But stubs aren't really the big issue here. We basically need a mypy plugin that would run between the 2nd pass semantic analysis and the typecheck pass that would inject attrs generated stuff into attrs classes, and I think mypy doesn't have this type of plugin yet.

I agree that for complete support we'll need such a plugin, but adding typing to attr's public API will provide immediate benefits in tools like PyCharm.  Let's just say it's a step in the right direction and sets us up to solve the harder issue of dunder methods.

I read all of the epic typing issue on third-party pyi stubs, as well as the newly drafted PEP on the subject, and here's the synopsis:

For package maintainers wishing to ship stub files containing all of their type information, it is prefered that the *.pyi stubs are alongside the corresponding *.py files.

setuptools will soon grow a new typed argument:
setup(
    ...
    setup_requires=["typing"],
    typed="stubs",
    ...
)

mypy and other type checkers will work out-of-the-box with compliant packages

That means that installing the pyi files alongside the py files is correct.
@Tinche @hynek, do you all have any concerns about merging this PR prior to making a mypy plugin?  Any other concerns that you'd like addressed?
I still have to fix a few remaining typing issues and deal with documentation and testing, I just want to make sure I have the green light first.
thanks.

Correct me if I'm wrong, but it seems to me that merging this is kind of pointless without a mypy plugin because it fixes only a part of the failures?  Unless I miss something, I’d put this PR on hold until we can actually use mypy (better sooner than later as far as I'm concerned…).

Correct me if I'm wrong, but it seems to me that merging this is kind of pointless without a mypy plugin because it fixes only a part of the failures?

This is probably true for mypy users, since it would typically be used as part of a CI process where erroneous failures are problematic, but this PR would immediately benefit users of IDEs with PEP 484 support, like PyCharm.
Below is an animation showing how the stubs improve PyCharm's completions.  What's great is that this works for users who aren't yet on python 3.6 and can't take advantage of variable annotations.  It also gives completions for utility functions like  attr.fields.  I don't know about you, but this is something that I'd like to have right away, and I'm sure others will agree.

I see, so the question becomes: [how] can we meaningfully test them?  Ideally both for consistency and completeness?

The mypy project contains some pytest utilities that shouldn't be to hard to port/utilize, but mpy will have to be added to the list of test requirements.
Our test runner will look something like this
Tests files look like this
The test runner code can only be run in python 3.5+ but the code within the .test files can be written using 2 or 3.  I see two approaches to running them:

Create tests/test_stubs.py and use conftest.collect_ignore to ensure that it only runs in python 3.5+
Create a separate entry point script and run it using tox

Update:  I've got the test running added, but the stubs don't check properly in mypy due to a bug:  https://github.com/python/mypy/issues/4027
Let me know if you have any comments on how the tests are run.

@hynek @Tinche  @wsanchez  I think this PR is ready for a more thorough review.
Other than general input on the stubs, there are two topics to discuss:
Testing the stubs
I added a new stubs env to tox to run the mypy tests.  IMHO it doesn't make sense to lump the stub tests in with the other tests because:

test success/failure is not tied to the python runtime
It is therefore wasteful to run them multiple times
moreover, trying to run the mypy tests along with the normal results in more headaches.  requires python 3.5+ but not pypy...

Two issues to resolve:

travis is not running my stubs env, but it works locally, and the env is clearly in the envlist.  Where is travis pulling tox.ini from?  Do I have to do something to rebuild tox on travis?
where do we put test_stubs.py?  Right now it lives in tests, but that means it must be excluded in conftest, which is a little ugly.

Testing the docs
In order to spot problems with static type checking related to new features, I thought it would be a good idea to type check the doctests examples in the docs.  I whipped up a prototype sphinx extension based on sphinx.exts.doctest (cleverly named doctest2) that can do what we need with just a little more work (still need a way to propagate failures, and specify expected errors).  If you think this is on the right track, I'll finish it up.

I agree about the separate Tox environment.

I'm still confused about how an external project correctly uses these stub files… :-(

I'm still confused about how an external project correctly uses these stub files… :-(

After PEP 561 is complete, we edit attrs' setup.py to add a typed argument and then mypy will handle the rest:
setup(
    ...
    typed="stubs",
    ...
)

Until then, you need a separate checkout of attrs :/

Hi folks.  So based on the conversation happening in https://github.com/python/mypy/issues/2088#issuecomment-351677109 these should go in the typeshed.  I'm glad to make a PR to do it there.  Let me know if there's a reason I shouldn't.

@euresti  exciting stuff!

So based on the conversation happening in python/mypy#2088 (comment) these should go in the typeshed.

Yeah, I saw that.  Guess I was being optimistic about the timeline on PEP 561

I'm glad to make a PR to do it there. Let me know if there's a reason I shouldn't.

How about this:  give me a day or two to get the tests passing with your fork of mypy, since I may need to make some adjustments to the stubs during that process, and it will generally be easier if everything is in one place.  You can play around with this branch at that point and see if everything is working as you'd expect. Then you can take the stubs to typeshed from there.  Sound good?

Sounds great! Thanks!

By the way, if you're using PyCharm (and if you're following this issue you should be), head over to this JetBrains issue to add your +1 and star it:  https://youtrack.jetbrains.com/issue/PY-26354

Quick update:  the stub tests broke in newer versions of mypy, upon which your changes are based.  Opened a ticket:  https://github.com/python/mypy/issues/4366
That's going to slow me down a little bit, while I figure out the most expedient solution.

If all you're wanting to do is run mypy tests on these files one simple/gross way to do it is to clone mypy, and get a dev environment set up (enough to run unit tests) Then symlink your files .pyi files in the typeshed subdirectory and the tests into the test subdirectory.  (It's a bit annoying that the files are in separate repos but that's life)
Another option is to work against the old version of mypy just to make sure they're clean. Then I bring the .pyi files into the typeshed, and I can bring the test files into mypy also when we bring in the attrs plugin.
Anyway it's Friday so have a good weekend!

Looks like I was wrong about the mypy tests. They don't use the typeshed for their tests.  This does mean that I don't need these to be done to work on the plugin.  However in order for others to actually use the feature we do need stubs in the typeshed.  But I'm not blocked on these.

Cool.  I got word from the mypy team that they are not interested in
supporting their pytest plugin (i.e. it's use at your own risk and their
changes have already broken my tests once), so I'll copy that over to attrs
for now, and probably eventually split it out and put it on PyPI.

@euresti  I pushed up a new commit that tests the stubs against the latest from your attrs_plugin branch of mypy.  I noticed one issue that popped up there which was not present on master.
In the "test_type_arg" in tests_stubs.test:
import attr

@attr.s
class C(object):
    a = attr.ib(type=int)

c = C(1)
reveal_type(c.a)  # int
reveal_type(C.a)  # int

Expected output is
a.py:8: error: Revealed type is 'builtins.int*'
a.py:9: error: Revealed type is 'builtins.int*'

However, on your branch we grow a new error:
 a.py:5: error: Need type annotation for variable

This should not happen because attr.ib is properly annotated in the stubs to return a type based on the type arg.  Not sure why this is breaking on your branch.  Any ideas?

Oh wow. You're running this against my attrs_plugin branch. Cool! Looks like you found a bug in  my plugin. I don't handle the type= correctly.  Oops.

Correct me if I’m wrong but the plugin should not need to deal with the
attrib function at all since it can be solved using normal stubs. I think
the plugin should only handle the @attrs case.
On Wed, Dec 20, 2017 at 9:22 PM David Euresti<EMAIL_ADDRESS>wrote:

Oh wow. You're running this against my attrs_plugin branch. Cool! Looks
like you found a bug in my plugin. I don't handle the type= correctly. Oops.
—
You are receiving this because you authored the thread.
Reply to this email directly, view it on GitHub
https://github.com/python-attrs/attrs/pull/238#issuecomment-353261025,
or mute the thread
https://github.com/notifications/unsubscribe-auth/AAD3E7dYw5HILrFL1KfETB3WTzSoEpnyks5tCesbgaJpZM4PDtI5
.

The plugin as it's written now needs to extract the default value from the attrib call (technically it needs to know if one is set) to put it in the __init__. It also needs to look for init=False and not include that one in the __init__ I'll probably just have to handle type separately.  Or investigate if we can actually extract the type out in a different manner.  (Mypy is pretty complex and does multiple passes through the code)

Does it seem possible to extract that info from attrib to use when
generating the init but still allow mypy to fall back to using the
stubs for type checking attrib?
On Wed, Dec 20, 2017 at 10:19 PM David Euresti<EMAIL_ADDRESS>wrote:

The plugin as it's written now needs to extract the default value from
the attrib call (technically it needs to know if one is set) to put it in
the init. It also needs to look for init=False and not include that
one in the init I'll probably just have to handle type separately. Or
investigate if we can actually extract the type out in a different manner.
(Mypy is pretty complex and does multiple passes through the code)
—
You are receiving this because you authored the thread.
Reply to this email directly, view it on GitHub
https://github.com/python-attrs/attrs/pull/238#issuecomment-353267962,
or mute the thread
https://github.com/notifications/unsubscribe-auth/AAD3EwlNKTRfTPOojCdjfCa3r-KSptbgks5tCfhvgaJpZM4PDtI5
.

You guys let us know if you need something, right?  Because it’s all gibberish to me by just trying to follow along. :)

Actually now that I've thought about it more.  The plugin should just add the type of 'Any' to any attr.ib() assignment that isn't annotated.  (You actually don't want to use the type of default because for example:
@attr.s
class Foo:
    x = attr.ib(18)

Foo('Yeah i want a string')

Setting it to Any is great in a large code base.  Specially --disallow-untyped-defs flags the generated __init__  Then you can still do gradual typing.  I'll do that.

I found a solution!
# `attr` also lies about its return type to make the following possible:
#     attr()    -> Any
#     attr(8)   -> int
#     attr(validator=<some callable>)  -> Whatever the callable expects.
# This makes this type of assignments possible:
#     x: int = attr(8)
# First form catches a default value set.  Can't use `= ...` on default or you get "overloaded overlap" error.
@overload
def attr(default: _T, validator: Optional[_ValidatorArgType[_T]] = ...,
         repr: bool = ..., cmp: bool = ..., hash: Optional[bool] = ..., init: bool = ...,
         convert: _ConverterType[_T] = ..., metadata: Mapping = ...,
         type: Type[_T] = ...) -> _T: ...
# 2nd form catches a default of None but one of the other _T set.
@overload
def attr(default: None = ..., validator: Optional[_ValidatorArgType[_T]] = ...,
         repr: bool = ..., cmp: bool = ..., hash: Optional[bool] = ..., init: bool = ...,
         convert: Optional[_ConverterType[_T]] = ..., metadata: Mapping = ...,
         type: Optional[Type[_T]] = ...) -> _T: ...
# 3rd form catches nothing set. So returns Any.
@overload
def attr(default: None = ..., validator: None = ...,
         repr: bool = ..., cmp: bool = ..., hash: Optional[bool] = ..., init: bool = ...,
         convert: None = ..., metadata: Mapping = ...,
         type: None = ...) -> Any: ...

Also can you change attributes to the following?
@overload
def attributes(maybe_cls: _C, these: Optional[Dict[str, Any]] = ..., repr_ns: Optional[str] = ..., repr: bool = ..., cmp: bool = ..., hash: Optional[bool] = ..., init: bool = ..., slots: bool = ..., frozen: bool = ..., str: bool = ...) -> _C: ...
@overload
def attributes(maybe_cls: None = ..., these: Optional[Dict[str, Any]] = ..., repr_ns: Optional[str] = ..., repr: bool = ..., cmp: bool = ..., hash: Optional[bool] = ..., init: bool = ..., slots: bool = ..., frozen: bool = ..., str: bool = ...) -> Callable[[_C], _C]: ...

This way it works with --strict-optional set.
PS. Pycharm is very unhappy about this.  I get lots of squiggly lines.
Also how do you want to merge the pyi files into the typeshed?  I can do it myself but want to make sure you get the credit somehow.

I tried out the changes and I'm getting some issues running my tests.  One of them is an unhandled exception coming from the plugin.
Can you check out this branch, apply your edits to __init__.pyi and then run tox -e stubs to see the issues that I'm referring to?

Also how do you want to merge the pyi files into the typeshed? I can do it myself but want to make sure you get the credit somehow.

I'll handle it once all the tests are passing.  I still want to add a bunch more to test the new dunder methods added by the plugin.

Actually now that I've thought about it more. The plugin should just add the type of 'Any' to any attr.ib() assignment that isn't annotated.

attrs is a tool for reducing boilerplate.  If we're ever in doubt about the correct behavior, we should write out the boilerplate version (esp of __init__) and use mypy to check the result, then use that to guide the attrs stubs and plugin.  Once you've had a look at the current round of issues I plan to create tests that do just that.

I think we might be better off doing this without the plugin first just so we can get the stubs into the typeshed.  Once those are in, I can work on the plugin.  After all, the plugin will only add the init and the cmp methods.

Ok the crashes were that I left pdb.set_trace() statements in there.  Oops.  I pushed a new commit to fix that.
Anyway I looked at the pyi files and made a few edits:  https://github.com/euresti/attrs/tree/pyi_stubs
Mostly added TypeVars and Any to things.  (I removed Collection because that's only in 3.6) The tests now pass.   Feel free to merge those into your branch.  I don't yet know how to do a PR to a forked repo otherwise I would do that.

@euresti  fantastic!  we're getting very close.
As I've mentioned before I wrote a modified version of sphinx.ext.doctest to perform static analysis on doctest blocks in the documentation.  This will help spot issues introduced by attrs developers who may not be as familiar with mypy, who can call us in for backup :)
The doctests are almost entirely passing, we're just hitting errors on fields():
   >>> @attr.s
   ... class C:
   ...     x = attr.ib(type=int)
   ...     y: int = attr.ib()
   >>> attr.fields(C).x.type
   <class 'int'>
   >>> attr.fields(C).y.type
   <class 'int'>

Produces
    30: error: "Tuple[Attribute[Any], ...]" has no attribute "x"
    31: error: "Tuple[Attribute[Any], ...]" has no attribute "y"

Can your attrs mypy plugin modify fields to return a NamedTuple.  e.g. for the example above, it would be:
NamedTuple('_attrs_fields_for_C', [('x', Attribute[int]), ('y', Attribute[int])])

Open for input on the name to generate, which really isn't all that important.

Oh wow.  I didn't realize attr.fields(C) returned a manufactured object.  I think the correct way is to have the stub be as correct as possible.  Something like this might work:
class _Fields(Tuple[Attribute]):
    def __getattr__(self, name: str) -> Attribute: ...

def fields(cls: type) -> _Fields: ...

Of course it won't catch something like this attr.fields(C).not_there.type but mypy can only go so far.

Oh and separately I believe a plugin could be written to infer a better return type.

Something like this might work:

Eventually it would be nice to have proper NamedTuple support, but it's a niche case.   Pushed a fix based on your suggestion.
On to the next issue, subclassing.
I ran into failures with this example:
   >>> @attr.s
   ... class A(object):
   ...     a = attr.ib()
   ...     def get_a(self):
   ...         return self.a
   >>> @attr.s
   ... class B(object):
   ...     b = attr.ib()
   >>> @attr.s
   ... class C(B, A):
   ...     c = attr.ib()
   >>> i = C(1, 2, 3)
   >>> i
   C(a=1, b=2, c=3)
   >>> i == C(1, 2, 3)
   True
   >>> i.get_a()
   1

Errors:
Line 1, in subclassing
Failed example:

Expected nothing
Got:
    10: error: Definition of "__ne__" in base class "B" is incompatible with definition in base class "A"
    10: error: Definition of "__eq__" in base class "B" is incompatible with definition in base class "A"
    10: error: Definition of "__lt__" in base class "B" is incompatible with definition in base class "A"
    10: error: Definition of "__le__" in base class "B" is incompatible with definition in base class "A"
    10: error: Definition of "__gt__" in base class "B" is incompatible with definition in base class "A"
    10: error: Definition of "__ge__" in base class "B" is incompatible with definition in base class "A"
    13: error: Too many arguments for "C"
    15: error: Too many arguments for "C"

I pushed up my doctest changes so that you can reproduce this.  A few notes:

test blocks are grouped using .. doctest:: <groupname> so that tests get a fresh start when necessary to avoid the tests stomping on each other (mypy does not like classes being redefined, and many of the examples use C).
I'm only testing examples.rst at the moment.
the error output is not super friendly yet.  line numbers refer to those in the mypy file, not the doc file.  to hone in on the right location first find the doctest group in the error output: Line 1, in <groupname>
it stops on the first failed section, which is annoying.  still looking into how to make it continue.
if applicable, just add a # test: ignore.  I'll add something to strip these from rendered output.
to run: tox -e docs.  you may need to run with -r once if you've run these before.

Yep, can't say I gave much thought to subclassing.  (We practically don't do that at our company)  It will eventually have to get done.
Is there any way to just run the tests on stock mypy without the plugin, just marking all the errors that will eventually be fixed by the plugin?  Then as the plugin develops we can remove all the error: lines and feel good about what's implemented.

I think it’s fairly reasonable for the plugin to support the basic set of
advertised features. Subclassing is not a niche case. If it’s not something
that you’re willing to do I can try to find the time.
On Fri, Dec 22, 2017 at 10:48 AM David Euresti<EMAIL_ADDRESS>wrote:

Yep, can't say I gave much thought to subclassing. (We practically don't
do that at our company) It will eventually have to get done.
Is there any way to just run the tests on stock mypy without the plugin,
just marking all the errors that will eventually be fixed by the plugin?
Then as the plugin develops we can remove all the error: lines and feel
good about what's implemented.
—
You are receiving this because you authored the thread.
Reply to this email directly, view it on GitHub
https://github.com/python-attrs/attrs/pull/238#issuecomment-353655177,
or mute the thread
https://github.com/notifications/unsubscribe-auth/AAD3EyX-viPlZy-Tc1eWWi9qvE2A2MXsks5tC_mKgaJpZM4PDtI5
.

I'm not saying I wouldn't do it. I'm just saying I don't want to block the stubs getting to the typeshed because the plugin is still an RFC/WIP.

Ok I investigate a little bit. There are 2 issues here. One stems from multiple inheritance and is technically an issue in mypy.  Take this code without attrs.
class A:
    def __lt__(self, other: 'A') -> bool: pass

class B:
    def __lt__(self, other: 'B') -> bool: pass

class C(A, B):  # <--- error foo2.py:13: error: Definition of "__lt__" in base class "A" is incompatible with definition in base class "B"
    def __lt__(self, other: 'C') -> bool: pass

The only way around it is a #type: ignore  Perhaps mypy shouldn't freak out if the method is being overriden anyway but that's for another day.
The other issue is the straight up inheritance on of attr classes and the generated __init__.  Just need to figure out how attrs does it and then figure out how to write it in mypy land.  :)

Ok plugin now supports inheritance.  It was much much easier than I expected.  :)

Ok, I worked through the remaining issues in the docs.
I also found a few issues related to the mypy plugin.

an error occurs in examples.rst in the default_decorator section:  "Non-default attributes not allowed after default attributes."

   >>> @attr.s
   ... class C(object):
   ...     x = attr.ib(default=1)
   ...     y = attr.ib()
   ...     @y.default
   ...     def name_does_not_matter(self):
   ...         return self.x + 1
   >>> C()
   C(x=1, y=2)

hit an exception within the plugin for the nested class example:

   >>> @attr.s
   ... class C(object):
   ...     @attr.s(repr_ns="C")
   ...     class D(object):
   ...         pass
   >>> C.D()
   C.D()

it would be awesome if you could suppress the  Definition of "__ne__" in base class "B" is incompatible with definition in base class "A" errors, by whatever means you deem appropriate.

With those complete we'll be error-free.
I think the stubs are pretty well tested now so they're just about ready to go to typeshed.  I'm going to give them one more look over and then I'll make the PR there and I'll tag you.

Oh yeah the @y.default  decorator.  I might be able too look for those too.
Interesting find in the subclasses look like there's an easy fix.
I'll see what can be done.

Ok. Nested classes are fixed. And I added support for frozen.

x.default is fixed too!

I switched to inline error comments, so the tests should be much more legible now.
There are two known issues remaining:

the eq methods are still generating the error Definition of "__ne__" in base class "A" is incompatible with definition in base class "B"

A type error occurs in the docs when using validators to determine the type of attr.ib:
The mypy error is marked in the comment below:
import attr
import enum
class State(enum.Enum):
    ON = "on"
    OFF = "off"
@attr.s
class C(object):
    state = attr.ib(validator=attr.validators.in_(State))  # E: Need type annotation for variable

Recall that validator.in_ looks like this:
def in_(options: Container[_T]) -> _ValidatorType[_T]: ...

It seems that mypy does not know how to expand State into Container[_T] to get _T.  An enum class is a container of instances of itself (isinstance(State.ON, State) is True), so in this case _T is State.
I think this is probably an issue with mypy which may be solved if/when enum is rewritten as a protocol.  The error can be resolved by adding a type argument:
@attr.s
class C(object):
    state = attr.ib(type=State, validator=attr.validators.in_(State))

While this is not necessarily an issue with our stubs, I just wanted to point out that the fact that we enforce proper typing of validators means that more work will need to be done in some cases to make them behave properly in mypy.  For the moment, I think this is a good thing, so I will ignore this in the tests.

One more question about the results from the plugin:
When the attribute type is implied from the validator or default arg using a TypeVar rather than stated explicitly, the type does not affect the __init__:
import attr
from attr.validators import instance_of

@attr.s
class C:
    x = attr.ib(validator=instance_of(int))

reveal_type(C.x)  # E: Revealed type is 'builtins.int*'

C(42)
C("42")  # <----- should be an error?

Yeah. That's how it currently works. The __init__ argument type is pulled from the annotation or the type=, otherwise it's Any.  Checking for validators is highly complex.  instance_of(int) and_(instance_of(int), in_(15, 5))  etc etc.  It's probably just easier/safer for the programmer to add:
x: int = attr.ib(validator=instance_of(int))
I don't just take the type of the right hand side because x = attr.ib(9) means def __init__(self, x=9) but it doesn't mean def __init__(self, x: int = 9)

I haven't looked at the mypy plugin code yet, though I plan to familiarize myself with it eventually, so bear with me.

I don't just take the type of the right hand side because x = attr.ib(9) means def init(self, x=9) but it doesn't mean def init(self, x: int = 9)

Consider in the original example that mypy knows the type of C.x is int:
@attr.s
class C:
    x = attr.ib(validator=instance_of(int))

reveal_type(C.x)  # E: Revealed type is 'builtins.int*'

This type is computed from the stubs for attr.ib.  Can the plugin use this type instead of attempting to recompute it from the arguments to attr.ib?  That would keep the two sides of the system -- plugin and stubs -- in sync, and prevent you from having to do anything too complex in the plugin.
By the way, I don't disagree that explicit annotations are always preferable to relying on the implicit typevar behavior, but I do think that working out some guidelines for interaction between plugin and stubs is a good idea (and besides, I'd like to understand this better myself).

If I read the mypy code correctly that part is done through type inference which is done after semantic analysis.  The plugin runs at semantic analysis time.  :(

If I read the mypy code correctly that part is done through type inference which is done after semantic analysis. The plugin runs at semantic analysis time. :(

Ok, no worries.  Proper annotations are the preferred solution.
Next up.
attrs provides the type argument as a convenience for developers still targeting 2.7.  From the perspective of attrs, these two attribute declarations are the same:
@attr.s
class D:
    x = attr.ib(default='bad', type=int)
    y: int = attr.ib(default='bad')

But from mypy's perspective, they're quite different.  The type assigned to x by mypy  is object (the common parent of the two type vars, str and int) and the latter issues an error: Incompatible types in assignment (expression has type "str", variable has type "int").
Can the plugin assign x a type such that the behaviors of these two are the same?  i.e. they both result in an "Incompatible types" error.

Good idea and done!
You may want to adjust the stub to avoid the coercion to object.  I believe changing the first definition of type to be type instead of Type[T] will make sure coercion doesn't happen.

@euresti
hmm... not quite there yet.
Given this:
x = attr.ib(default='bad', type=int)

The type of x is now str, but we expect it to result in an error, as it would with the type annotated equivalent (yes, this is after replacing Type[_T] with type in the first overload).
I noticed that there are no tests for this case in the mypy plugin.  I'll have time to dig into the plugin soon so that I can help with these issues instead of just pointing them out.
Another note: it's my hope that we don't have to replace Type[_T] with type because this will break the current PyCharm inspections, which are useful even without native support.
My last commit has some notes about the issues in the test file.  The previous commit set a baseline against the previous version of the plugin, so you can switch between the two commits to see the issues for yourself.

I see.  The plugin only run on the annotated class.  Not on the attr.ib.
Basically it turns:
@attr.s
class A:
     x = attr.ib(default=18, type=str)

into
@attr.s
class A:
   x: str = attr.ib(default=18, type=str)

And since without the Type[T] attr.ib(default=18, type=str) is an int you get the error.

Ah, ok.  So I can adjust my tests to correct this.  Testing without classes was just a matter of convenience, but the use of attr.ib outside of a class is niche -- usually with make_class -- and that will need special treatment in the plugin to be useful in a static context anyway.

Another thing we can try is:
Callable[..., T] instead of Type[T]

And I found a bug in my original and so we only need 2 definitions:
# 1st form catches a default value set.
@overload
def attrib(default: Optional[_T] = ..., validator: Optional[_ValidatorArgType[_T]] = ...,
           repr: bool = ..., cmp: bool = ..., hash: Optional[bool] = ..., init: bool = ...,
           convert: Optional[_ConverterType[_T]] = ..., metadata: Mapping = ...,
           type: Optional[Callable[..., _T]] = ...) -> _T: ...
# 2nd form catches no type-setters. So returns Any.
@overload
def attrib(default: None = ..., validator: None = ...,
           repr: bool = ..., cmp: bool = ..., hash: Optional[bool] = ..., init: bool = ...,
           convert: None = ..., metadata: Mapping = ...,
           type: None = ...) -> Any: ...

Though PyCharm is still unhappy.  It says "Expected type None got int instead" on calls like attr.ib(15)  Don't know why.

Wow. I figured out why PyCharm is angry. The overloads don't propagate assignments.  I'm gonna file a bug if I can't find one.

Fixed the tests!
Only one known issue remaining, which is more along the lines of a feature request:
import attr

def str_to_int(s: str) -> int:
    return int(s)

@attr.s
class C:
    x: int = attr.ib(convert=str_to_int)

C(1)
C('1')

The type of __init__ args should be the union of type and the convert callable's args.

Filed: https://youtrack.jetbrains.com/issue/PY-27788
PS we can work around the issue by repeating the definitions for all the aliases.  But how tedious.  :)
I'll take a look at convert. It looks pretty complex though.

The type of init args should be the union of type and the convert callable's args.

Actually the type of the __init__ arg should be just the callable's arg, since convert is always called.  I'll see if that's doable.

PS we can work around the issue by repeating the definitions for all the aliases. But how tedious. :)

dealt with this the tedious way for now, and left a note with the PyCharm issue

Actually the type of the init arg should be just the callable's arg, since convert is always called. I'll see if that's doable.

Note that convert is now deprecated in favor of converter.  Need to get latest master merged in.

Nit: You only need 2 overloads not 3.  One that returns _T and the other that returns Any.  Or did it not work for you?

Also, just added support for convert.  Will have to add support for converter too.

Nit: You only need 2 overloads not 3. One that returns _T and the other that returns Any. Or did it not work for you?

I needed all 3.  I tried alternately removing the 1st and the 2nd, but various tests failed in each case.  Feel free to have a look.
All stub tests are passing now.

We just need that Definition of "__ne__" in base class "A" is incompatible with definition in base class "B" issue resolved and all the docs tests will pass too.

I was using these two:
# 1st form catches a default value set.
@overload
def attrib(default: Optional[_T] = ..., validator: Optional[_ValidatorArgType[_T]] = ...,
           repr: bool = ..., cmp: bool = ..., hash: Optional[bool] = ..., init: bool = ...,
           convert: Optional[_ConverterType[_T]] = ..., metadata: Mapping = ...,
           type: Optional[Callable[..., _T]] = ...) -> _T: ...
# 2nd form catches no type-setters. So returns Any.
@overload
def attrib(default: None = ..., validator: None = ...,
           repr: bool = ..., cmp: bool = ..., hash: Optional[bool] = ..., init: bool = ...,
           convert: None = ..., metadata: Mapping = ...,
           type: None = ...) -> Any: ...

Note how the first one uses Optional whenever there's a _T in the type.  It also uses Callable[..., _T] instead of Type[_T]
PS. Happy New Year!

Oh tests failing. Hmm. I guess I'll pull and see what's up.  Tomorrow.

Happy New Year!
Ok I pulled your branch, made change and tested.  It's now working with 2 overloads instead of 3.
Now about that type= type annotation:
Note: main:11 is     c = attr.ib(default='bad', type=int)
Type[_T] passes tests without changes but leads the object weirdness.

  main:11: error: Incompatible types in assignment (expression has type "object", variable has type "int") (diff)

Using Callable[..., _T] remove the object issue but looks kind of ugly:

  main:11: error: Argument 2 to "ib" has incompatible type "Type[int]"; expected "Callable[..., str]" (diff)
However this code b = attr.ib(type=int, validator=validate_str)   led to
main:12: error: Cannot infer type argument 1 of "ib" (diff)  which I can't really explain. Maybe it's because type is first.  Anyway, that's kind of a confusing error.

Using just type leads to:

No object showing up.
  main:11: error: Incompatible types in assignment (expression has type "str", variable has type "int") (diff)
The plugin does all the setting of annotations.  So no weird ib has incompatible type.
However I did notice the plugin doesn't show any error for this:

    d: int = attr.ib(default=0, type=str)

Because the plugin prefers the annotation over the type=.  This could be fixed in the plugin.
So your choice on which you want to use.  I like type because it works exactly like adding a type annotation as long as you're using the plugin.
Using type looks like this.  Notice the 2nd one changes from type: None -> type: Optional[type]
# 1st form catches _T set.
@overload
def attrib(default: Optional[_T] = ..., validator: Optional[_ValidatorArgType[_T]] = ...,
           repr: bool = ..., cmp: bool = ..., hash: Optional[bool] = ..., init: bool = ...,
           convert: Optional[_ConverterType[_T]] = ..., metadata: Mapping = ...,
           type: Optional[type] = ...) -> _T: ...
# 2nd form no _T , so returns Any.
@overload
def attrib(default: None = ..., validator: None = ...,
           repr: bool = ..., cmp: bool = ..., hash: Optional[bool] = ..., init: bool = ...,
           convert: None = ..., metadata: Mapping = ...,
           type: Optional[type] = ...) -> Any: ...

I believe this can be closed now?

@hynek  Personally, even though the stubs have been released in the python typeshed, I think that they should be included in this repo. Here's why:

It will be easier to develop in this repo, rather than in the typeshed.  Here we can easily create issues and PRs and track their history all in one place without the noise of other projects and restrictions of other maintainers.
Eventually, when PEP 561 is complete, the stubs will be released along with the source.
Even now, releasing stubs alongside the source is good practice:  PyCharm still doesn't use the typeshed, but it will find pyi stubs living next to installed modules
The typeshed does not include tests for third-party stubs
Including the stub tests in this repo will ensure that contributors keep the stubs up to date.  i.e. if a change is made here that impacts static typing, we want the stub tests to fail until the stubs are also addressed.

So, what's left before merging this?  Just finalizing the tests.
In this PR, I've added two approaches to testing the stubs: unittests and doctests. Each of these introduces some additional utitlity code which we need to decide what to do with.

unittests: added a pytest plugin derived from the plugin used by mypy for asserting expected behavior from mypy, i.e. inspected types and generated errors (The mypy developers are emphatically against providing a stable plugin API for doing this, so we have to roll our own).
doctests: added a wrapper to the sphinx doctest extension for running static analysis of doctest code. Note that I had to add labels to the logical doctest groups, because mypy does not like types to be redeclared. If you're not a fan of this, there may be other approaches, though likely uglier in other ways.

We can either leave these utilities within attrs, or I can split them out into their own project(s), release on PyPI, and add as a requirement here.

@hynek, any more thoughts on my post above regarding adding the stubs to this project?

OK I finally conquered my procrastination and decision fatigue.
So I can see your point. PyCharm support is good. It’s also nice that its state becomes our prerogative.
I’m afraid of two things:

I do not 100% understand the code around mypy and types and I don’t know when I will (I was kind of waiting for attrs support to start using it ;)). Having code I don’t understand makes me uneasy, but I guess that’s the fate of growing projects? What that’s mean for you, is that I’d pull you into all related issues and PRs like I’m doing with Tin when I have trouble with Hypothesis.
How do we avoid two sources of truth? What's the workflow here? Who will how make sure that changes flow to type shed? My personal hope is that type shed will go aways eventually for non-stdlib but who knows how long that’ll take…

Plus there’s quite a bit of work for you to fix up the code. ;) We don’t do .txt dependency files anymore for instance.

What that’s mean for you, is that I’d pull you into all related issues and PRs like I’m doing with Tin when I have trouble with Hypothesis.

Between myself and @euresti I think we'll be able to handle it.

Who will how make sure that changes flow to type shed? My personal hope is that type shed will go aways eventually for non-stdlib but who knows how long that’ll take…

The good news is that there is already a mypy PR for PEP 561 support, and it sounds like it should make it into the next release.  Once that happens I think we should remove the stubs from the typeshed to avoid conflicts and require users to upgrade to at least that version of mypy (0.580 will be the next release).  The new draft of PEP 561 does not require any modifications to distutils/setuptools, so we should be able to become compliant immediately.  Until then, I'm sure that myself and @euresti can manage it.  We're already doing this, but the changes are flowing the opposite direction right now.

Plus there’s quite a bit of work for you to fix up the code. ;) We don’t do .txt dependency files anymore for instance.

Updates are under way.  I'll check back when it's all done.

speaking of the advantages of having all the tests in one place:
@euresti I'm getting new errors when running mypy against the doctests:
Line 1, in converters1
Failed example:
    import attr
    @attr.s
    class C(object):
        x = attr.ib(converter=int)
    o = C("1")
    o.x
Expected nothing
Got:
    main:4: error: Unsupported converter function, only named functions are currently supported

I assume this is trying to ward off lambdas, but getting tripped up by builtins?

That's a good point. Can you file a bug on mypy?  :)

Just occurred to me: this should probably include updates to

CONTRIBUTING.rst
PULL_REQUEST_TEMPLATE.md

The good news is that there is already a mypy PR for PEP 561 support, and it sounds like it should make it into the next release. Once that happens I think we should remove the stubs from the typeshed to avoid conflicts and require users to upgrade to at least that version of mypy

FYI, PEP 561 support has been merged, and will be released in 0.590 on Friday.

FYI, PEP 561 support has been merged, and will be released in 0.590 on Friday.

What does that mean for us exactly? Do we have to add some metadata to attrs to make it discoverable?

@hynek if you want to distribute stubs along with attrs, you would need to include it as package_data. So assuming a directory (moved from typeshed) attr-stubs, you could modify your setup.py like:
....
setup(....
      packages=[..., 'attr-stubs'],
      package_data={'attr-stubs': [.... a list of stub files relative to the attr-stubs directory]},
      ....
)

I have a branch of numpy-stubs that makes it PEP 561 compatible if you want a concrete example.

No objections here.
On Sat, Apr 14, 2018 at 2:23 AM Hynek Schlawack<EMAIL_ADDRESS>wrote:

So since 18.1 is already wayyy too late, would anybody be upset if we push
this to the next release, also waiting a bit until the dust around mypy/PEP
561 settles? I really want attrs to be a trailblazer on this topic but I
don’t want to block the release by something big like this.
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
https://github.com/python-attrs/attrs/pull/238#issuecomment-381316136,
or mute the thread
https://github.com/notifications/unsubscribe-auth/AAD3E7gdaDrEbB6mfck3zejOuJhtiaj7ks5tocAjgaJpZM4PDtI5
.

Awesome, I presume you’re interested to bring this to a glorious finale? :)

No, it’s for users, too, because the plugin is bundled with mypy. The
output formatting is a separate issue with other workarounds. Just focusing
on the plugin, there may be multiple versions of mypy that will work with a
given attrs release, and we could conceivably try to test against a list of
them, and each release document the approved list, but for our own sanity I
thought it might be wise to just choose one version. On the other hand,
once it’s stable I suspect that the plugin will change less often than the
stubs, which means that the number of mypy versions compatible with each
new attrs release could grow.
But what about users of older attrs releases? How will they know what new
mypy releases are compatible? Will we have to test each mypy against each
attrs and post the results? Users who use a newer version of mypy (seeking
out some bug fix) with an older attrs may get updates to the plugin which
are intended for a newer version of attrs and not compatible with their
older attrs. As long as the plugin is bundled with mypy this problem will
exist, and making a separate repo for the stubs doesn’t really solve the
problem, it just shoves it elsewhere.
I’ve got a post I’m working on to make one last plea to the mypy devs.
Let’s see what happens.
On Sat, Apr 21, 2018 at 1:31 AM Hynek Schlawack<EMAIL_ADDRESS>wrote:

@hynek commented on this pull request.
In setup.py
https://github.com/python-attrs/attrs/pull/238#discussion_r183204221:

@@ -29,11 +32,16 @@
"Programming Language :: Python :: Implementation :: PyPy",
"Topic :: Software Development :: Libraries :: Python Modules",
]
+# mypy plugins are not yet externally distributable, so we must lock tests

So just to be clear: this pin is only for running our own tests and
has nothing to do with our users?
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
https://github.com/python-attrs/attrs/pull/238#discussion_r183204221,
or mute the thread
https://github.com/notifications/unsubscribe-auth/AAD3E8p5Sl1wWv6nVMlKmJJVhAqkNJg7ks5tqu5vgaJpZM4PDtI5
.

Any chance that everyone involved will be at PyCon US next week? 😇

No, but I am glad to setup a time to do a video conference to figure all
this out.
On Thu, May 3, 2018 at 6:23 AM David Euresti<EMAIL_ADDRESS>wrote:

Sadly, not me. :(
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
https://github.com/python-attrs/attrs/pull/238#issuecomment-386294004,
or mute the thread
https://github.com/notifications/unsubscribe-auth/AAD3E3rXd-Tuj-LVePOUMd3aSqhKXls2ks5tuwTsgaJpZM4PDtI5
.

I will be arriving at PyCon late on 4/13 and will be there until 4/17, so if you'd like to set up a meeting, I'd be happy to.

I think we’ll do a BoF. Łukasz is coming and maybe we/you can trick more mypy folks to attend too.

OK so I caught @ambv at the PyCon sprints and this are our thoughts:

The docstring stuff should go out for now completely.  Specifically: you should publish doctest2.py under a better name on PyPI so a) we don't have to maintain it as part of attrs and b) he can use it in black too. Once it's there, we can re-add the doctest changes from this PR.  That should shrink this PR considerably.
Let's not pin mypy so we we learn about breaking changes in it right away. The pin is only for tests anyway.
We're not sure what mypy.tests.py is. Is that some mypy stuff? Where does the syntax come from? We should def mention it in the file.
Fun bonus: we'll have to remove the stubs from typeshed and mypy will have to depend on attrs to get the stubs. 🎉

So now we also talked to @ethanhs and more points:
Please rip out the test plugin etc and let’s do very minimal testing for now: “just” add a typed script to tests and run mypy over it with our stubs. This is not exhaustive as I’d like it to be but at least we don’t have to add like half of mypy to our code base.
I’m sure the situation will improve over time and we’ll be able to add more interesting tests. But until then: if we ship buggy stubs: oh well, nobody’s software will break and we’ll just fix it.
Any thoughts anyone?

Oh and MANIFEST.in needs to be fixed too probably?

Please rip out the test plugin etc and let’s do very minimal testing for now: “just” add a typed script to tests and run mypy over it with our stubs. This is not exhaustive as I’d like it to be but at least we don’t have to add like half of mypy to our code base.

To be clear, if we do this, we can only test that the typed script passes.  We can't assert that specific cases fail.  If we want to test the latter, we need to add a handful of features:

multiple test scripts
assert failure or success for each test script
optionally test failure of certain lines within the script

... and then we're back to needing a pytest plugin.
Does this request override the original request "you should publish doctest2.py under a better name on PyPI".  i.e. Would you also like to keep or remove the testing of the doctest code?

We're not sure what mypy.tests.py is. Is that some mypy stuff? Where does the syntax come from? We should def mention it in the file.

This is a slight alteration of the *.test fixture files that the mypy pytest plugin uses (changed the extension and a few of the special characters within).  Since the mypy devs have made clear that using their pytest plugin is off limits, I took the liberty of making some improvements in my version.  If we remove the test plugin, then this goes with it (and some of the contents gets reused to create the basic test script).

Fun bonus: we'll have to remove the stubs from typeshed and mypy will have to depend on attrs to get the stubs.

Have you gotten the mypy devs to agree to this?
By the way, it looks like the next version of PyCharm will have attrs support.

Have you gotten the mypy devs to agree to this?

I think I am open to this idea, but we are meeting in the next week, so I will have a definite answer soon.
Also @hynek fwiw if you use setuptools and pass include_package_data=True, it will install package_data that you indicate. I hope once the PEP is finalized I can add some utilities for this.

Fun bonus: we'll have to remove the stubs from typeshed and mypy will have to depend on attrs to get the stubs.

I'm not sure I understand the 2nd part of this statement.  mypy wouldn't 'depend' on attrs to be able to work.  But if if you're type checking something that uses attrs then (via PEP 561) mypy would use the stubs that are included with the attrs package.  Or am I missing something?

OK so I’m slightly de-jetlagged but caught up in some last-minute GDPR bullshit, but lemme unblock you real quick:

Until this is resolved, could you please update the stubs in typeshed? 🐶 I tried to use mypy for the first time and I couldn’t use our sweet new factory argument. 💔 😇
I am aware that our typing tests are gonna be sub-par for the moment, but the alternative just doesn’t seem worth it right now.  I think it’s not the end of the world if we have a bug in our stubs as opposed to code that actually breaks. Just trying to be pragmatic here. :|
As for doctest2.py: I think this would be a useful thing to exist on PyPI and may help to improve the point before. I would love to have at least some doctests around typing but I really don’t want it to be part of attrs. Please don’t call it doctest2 though. :) To be more direct: I do not expect you to do it, but I think it would be useful for the larger Python typing community!
Same goes for the pytest plugin basically. If something lands on PyPI, we may start using it in the future but I very much don’t want to maintain it.
Yay for mypy not needing the stubs.

TL;DR: let’s strip the PR as bare as possible with MVT (minimally viable tests :)) and get it merged ASAP. I’m personally not gonna start any major work until this is in!

Oh and one thing I’ve just run into: it seems like Factory chokes on partials: error: No overload variant of "ib" matches argument types [functools.partial[Any]] any chance to fix it or am I doing typing wrong?

JFTR, I started using mypy in an internal project and one thing that we seem to also need is an empty file called py.typed: http://mypy.readthedocs.io/en/latest/installed_packages.html#making-pep-561-compatible-packages

@chadrik do you have the free cycles to finish this up or should someone take over?
P.S. I think we should totally switch to inline type hints and use mypy on attrs as well – am I overlooking any problem?

 Since you still support Python 2, you will probably need to use type comment annotations for both variables and functions. If you do e.g.:
MYPY=False
if MYPY:
    from typing import List, Tuple

it should never get imported and nothing gets executed. Its not the most beautiful solution, but it is a work around which you might consider, if adding typing as a dependency is undesirable.

Hm, is that the canonical way to do it? I really do not like stub files. I’m playing with them in my pem project right now.

(FWIW we want to avoid importing typing on any version because it’s so slow)

Hi all,
Sorry about the radio silence.  Here are some updates.
First, I want to address some of the questions brought up by @hynek, regarding inline type comments.
I share your distaste for stubs and in my own projects I use inline comments almost exclusively, but there are a few issues you have to watch out for.
Type hints are very fluid, and our developers found it annoying to micromanage the imports from typing, but using from typing * cluttered our globals and interfered with interactive debugging (e.g. auto-completion in ipython).  After a bit of debate we decided to kill two birds with one stone and use this as our convention:
TYPE_CHECKING = False
if TYPE_CHECKING:
    from typing import *

Any type objects which are only referenced by comments live in that block, such as TypeVars.  Which brings me to my next point.

There are a few objects in typing that you need at runtime:  Generic, NamedTuple, cast, overload.  For attrs, probably the last is the most important.  If you really want to avoid importing typing, but you need overloads, you can do this:
TYPE_CHECKING = False
if TYPE_CHECKING:
    from typing import *
else:
    def overload(f):
        return f

@overload
def add(x, y):
    # type: (int, int) -> int
    pass

@overload
def add(x, y):
    # type: (float, float) -> float
    pass

def add(x, y):
    return x + y

add(1, 3)

Note that TYPE_CHECKING has special meaning to mypy:  You must use this as the variable name for this to work.  You can use similar strategies for the other runtime objects.

Next up: linting.  Unless you use the (IMO much uglier) multiline-type-comment style, your type comments will often run over the max length allowed by a linter.  I looked briefly at writing a plugin for flake8 to allow this for type comments, but I didn't get far.

Keeping docstrings and type comments in sync can also be a challenge.  I decided that I wanted one source of truth and that it should be the docstrings, so I wrote this utility to create type comments from parsed docstrings:  https://github.com/chadrik/doc484

Last but certainly not least: lying stubs.  It's sometimes convenient to lie about the type or signature of an object in the stubs.  For example, in attrs the stubs define Factory as a function so that we can make this abbreviated syntax possible:  x: List[int] = Factory(list).  To create this affect without stubs, you can use a TYPE_CHECKING switch  to define alternative code for runtime vs type-analysis.

Back to the original question of my status.  The most time consuming part remaining is writing the tests.  As I started down that road, I asked myself what we should test, and I came right back to the code in the doctests.  I was about to copy-and-paste that code into a separate .py file, but I was overcome by the urge to automate this.  I already have the sphinx extension to do this, so I started working on getting a PyPI deployment of my amazingly-named doctest2 sphinx extension (I'm thinking I'll name it sphinx-doctest484, but I'm open to suggestions), and ultimately ran out of cycles.
Long story short, if someone wants to write a simple script to test against mypy, I can do the rest.
"The rest" depends on whether we want to do stubs as an initial release or go straight to type comments.  @hynek  what's the call here?
Here's what's left:
If inline:

convert stubs to inline
solve flake8 issue
add a simple mypy test to tox and travis
handle any packaging changes

If stubs:

add a simple mypy test to tox and travis
handle any packaging changes

If you don't want to depend on typing at runtime, then I think you may have to use stubs.
The other option you have is to process out type annotations for releases into stubs, so you don't have to actually import typing in releases, but that seems rather hacky, and would not allow people to get fully performant attrs with installing from git...

If you don't want to depend on typing at runtime, then I think you may have to use stubs.

@ethanhs  I don't think this is true.  I've found workarounds to every issue that I've encountered so far.
 We’re basically at the forefront and have a non-trivial project. :|
Given the complexity of attrs from typing PoV, I think we have to go the stubs route, because everything else is just too frickin’ hack.

FTR I don’t mind the multi-line style of stubs.

I’m still confused about the TYPE_CHECKING thing; if I don’t import it from typing, does it still bear meaning? I’ve been told mypy uses MYPY?

I find the concept of doc484 interesting, but doesn’t Sphinx and typing use slightly different syntaxes? I’m mostly concerned about  auto-linking here.

As for tests: I really want to have some, but we don’t have any right now either so it’s not a regression in any way. I’m eager to merge something that we have along with a simple smoke test: defines a moderately complex class and it must pass.
I believe that shouldn’t be too complex? I have some more thoughts but I’m holding them back, until we’ve basically moved what we have in typeshed to attrs to we have control over the stubs. Then we can iterate.
Is there anything unclear/blocking you?

Given the complexity of attrs from typing PoV, I think we have to go the stubs route, because everything else is just too frickin’ hack.

Understood.

I’m still confused about the TYPE_CHECKING thing; if I don’t import it from typing, does it still bear meaning?

Yes.

I’ve been told mypy uses MYPY?

A quick test shows that MYPY works the same as TYPE_CHECKING.  I believe mypy adopted MYPY before TYPE_CHECKING became part of the official PEP 484 standard.
The important thing to remember is that any falsey value will work at runtime, but only these specially designated constants will prevent the else block from being analyzed.
Consider this example again:
TYPE_CHECKING = False
if TYPE_CHECKING:
    from typing import *

else:
    def overload(f):
        return f

@overload
def add(x, y):
    # type: (int, int) -> int
    pass

@overload
def add(x, y):
    # type: (float, float) -> float
    pass

def add(x, y):
    return x + y

It works as is, but if we replace TYPE_CHECKING with FOO, we get these errors:
overload_fake.py:3: error: Incompatible import of "overload" (imported name has type "object", local name has type "Callable[[Any], Any]")
overload_fake.py:14: error: Name 'add' already defined on line 9
overload_fake.py:19: error: Name 'add' already defined on line 9

These errors occur because the else block is now evaluated.  The first error happens because overload in the else block overrides typing.overload from the if block.  This in turn generates the next two errors: the overridden overload does not originate from typing so the standard rules apply, wherein redeclaration of a function is disallowed.

I find the concept of doc484 interesting, but doesn’t Sphinx and typing use slightly different syntaxes? I’m mostly concerned about auto-linking here.

Good question.  I tested with the latest sphinx and it nicely generates links between types found in the currentmodule scope, though it doesn't seem to work properly for Dict, List, etc.
FTR, I've spent the past week adding tests and prepping doc484 for release.  It should be on PyPI later this week.

Is there anything unclear/blocking you?

All clear now.  I've made some progress getting things ready.  Shouldn't be too much longer unless we hit a snag with newer versions of mypy.

@hynek  ready for your review!

(As for the typeshed competition problem: does anyone have an idea how to ensure we’re using our own stubs? Maybe define some private sentinel object that typeshed doesn’t have and check against it in typing_example.py?)

It is, this PR’s packaging has a bug and we can’t tell because it falls back to typeshed.

Hi all, I addressed your notes.

does anyone have an idea how to ensure we’re using our own stubs?

Why don't we remove them from typeshed?  I don't see any good reason to keep them in both, and there are a lot of reasons not to.

Wouldn’t that be a regression for users of older versions of attrs? 🤔

Wouldn’t that be a regression for users of older versions of attrs?

We're talking about the bloodiest of bleeding edge here.  I just don't think it's worth taking on the work -- and additional issues -- of maintaining both for the tiny niche of users who are using the typeshed stubs but not able to update to the latest version of attrs, or who are using pyre or pytype and are not able to wait for PEP 561 support.  Keep in mind that the typeshed stubs are limited to the bleeding-edge anyway, as they can only support a single version of attrs at a time.

Almost eleven months, 164 comments, a lot hence and forth, but we’ve made it! Thanks @chadrik and everyone else! Now we can work on details. :)

Congrats!
@chadrik I likely will work on the plugin this weekend. I've opened https://github.com/ethanhs/pytest-stub-check/issues/1 and would welcome your input.


Remove TaskList::Item#source

This isn't used at all in the github.com Rails app.
/cc @mtodd

@mtodd How's this look to you?

@aroben looks good to me! Need to get this merged in soon?
On Thursday, June 18, 2015, Adam Roben<EMAIL_ADDRESS>wrote:

@mtodd https://github.com/mtodd How's this look to you?
—
Reply to this email directly or view it on GitHub
https://github.com/github/task_list/pull/59#issuecomment-113161766.

--
Matt Todd
GitHub, Inc
www.github.com
cell:<PHONE_NUMBER>
blog: maraby.org

No rush, just wanted to ping since I hadn't heard back from you yet.

@aroben :+1: OOO this week so it'll likely be next week before I get back to this. Thanks for the bump, though!


Fix scrollbar visibility issue on Windows browsers(replaced overflow-y: scroll with overflow-y: auto).

Fixes

Description

Testing Instructions

Checklist

[x] My pull request has a descriptive title (not a vague title likeUpdate index.md).
[x] My pull request targets the default branch of the repository (main) or a parent feature branch.
[x] My commit messages follow best practices.
[x] My code follows the established code style of the repository.
[ ] I added or updated tests for the changes I made (if applicable).
[ ] I added or updated documentation (if applicable).
[x] I tried running the project locally and verified that there are no visible errors.
[ ] I ran the DAG documentation generator (ov just catalog/generate-docs for catalog
PRs) or the media properties generator (ov just catalog/generate-docs media-props
for the catalog or ov just api/generate-docs for the API) where applicable.

Developer Certificate of Origin

Developer Certificate of Origin
Developer Certificate of Origin
Version 1.1

Copyright (C) 2004, 2006 The Linux Foundation and its contributors.
1 Letterman Drive
Suite D4700
San Francisco, CA, 94129

Everyone is permitted to copy and distribute verbatim copies of this
license document, but changing it is not allowed.

Developer's Certificate of Origin 1.1

By making a contribution to this project, I certify that:

(a) The contribution was created in whole or in part by me and I
    have the right to submit it under the open source license
    indicated in the file; or

(b) The contribution is based upon previous work that, to the best
    of my knowledge, is covered under an appropriate open source
    license and I have the right under that license to submit that
    work with modifications, whether created in whole or in part
    by me, under the same open source license (unless I am
    permitted to submit under a different license), as indicated
    in the file; or

(c) The contribution was provided directly to me by some other
    person who certified (a), (b) or (c) and I have not modified
    it.

(d) I understand and agree that this project and the contribution
    are public and that a record of the contribution (including all
    personal information I submit with it, including my sign-off) is
    maintained indefinitely and may be redistributed consistent with
    this project or the open source license(s) involved.

Hi, @Anuj012004, thank you for your PR! Could you update the PR description? Something like https://github.com/WordPress/openverse/pull/5286 would be great.

Hi @obulat, I have updated the description. Is it okay now?

Hi [@obulat, @dhruvkb],
I accidentally cleared the original description in my PR (#5285) and replaced it with my own. Could you please confirm if it's okay or if I need to change it? Also, is there any way to recover the original description?

Hey @Anuj012004, the PR template should be populated by filling out the <placeholder> parts and checking off the task list [ ] → [x]. I'll restore the original template that you can then fill out.


[Docs] Add section for tag list in UG

Closes #148

Codecov Report
Base: 76.91% // Head: 76.91% // No change to project coverage :thumbsup:

Coverage data is based on head (b44d7b1) compared to base (18408a1).
Patch has no changes to coverable lines.

Additional details and impacted files
@@            Coverage Diff            @@
##             master     #172   +/-   ##
=========================================
  Coverage     76.91%   76.91%
  Complexity      788      788
=========================================
  Files           108      108
  Lines          2214     2214
  Branches        254      254
=========================================
  Hits           1703     1703
  Misses          418      418
  Partials         93       93

Help us with your feedback. Take ten seconds to tell us how you rate us. Have a feature suggestion? Share it here.

:umbrella: View full report at Codecov.
:loudspeaker: Do you have feedback about the report comment? Let us know in this issue.


acc and rit as values for @rend on beam not sufficient

From<EMAIL_ADDRESS>on July 26, 2012 16:07:46
@-rend on <beam> doesn't allow for a single beam to have both characteristics.
Original issue: http://code.google.com/p/music-encoding/issues/detail?id=95

From<EMAIL_ADDRESS>on July 28, 2012 09:16:20
For those beams that have both an accelerando and a ritardando component, Johannes and I propose (and describe in the Guidelines) a value of 'mixed' for beam/@rend.
Status: Started

From<EMAIL_ADDRESS>on July 29, 2012 14:09:49
This issue was closed by revision r621 .
Status: Fixed